Atualizei o guia de Campos Personalizados de Tópicos para o Discourse 3.4.0. Atualizarei o guia de categorias na próxima semana.
Olá @angus, obrigado pelo plugin category-custom-fields!
No entanto, os valores não são salvos ao clicar em Salvar Categoria:
- A caixa de seleção do seu exemplo não modificado volta imediatamente para
desmarcada. - O campo personalizado não é salvo no banco de dados (eu monitorizei isso).
Não recebo nenhum erro.
Você poderia me ajudar a descobrir isso? Não consigo encontrar nenhuma causa.
Existe uma maneira de garantir no lado do servidor que campos personalizados sejam obrigatórios?
Em um plugin, você geralmente usa o modelo ModelCustomField para adicionar seus próprios dados.
Você pode dizer mais sobre o que você está tentando fazer?
Eu adicionei os campos personalizados e consigo salvá-los no banco de dados em uma tabela personalizada. No entanto, quero tornar esses campos personalizados obrigatórios tanto no lado do cliente quanto no lado do servidor. No lado do cliente, ainda é relativamente fácil. No lado do servidor, existe uma maneira padrão de validar se todos os campos personalizados estão preenchidos e, então, permitir que a criação do tópico seja concluída? Atualmente, mesmo que os campos personalizados estejam vazios, o tópico é criado sem eles.
Ah. Isso é fácil, mas não sou bom o suficiente em Rails para te dizer como. Mas você terá seu código por trás de um callback (Active Record Callbacks — Ruby on Rails Guides) que é chamado antes da criação e falhará se seus campos não estiverem lá.
Olá a todos,
Configurei um plugin baseado em Topic Custom Fields e tudo estava funcionando perfeitamente até que atualizei o Discourse para a versão 3.6.0.beta1-dev.
- Lista de tópicos => OK, as colunas aparecem corretamente na listagem
- Título do tópico => OK, as colunas aparecem corretamente abaixo do título do tópico
- Compositor de tópicos => ERRO, os campos não aparecem e não consigo compor nem validar a mensagem.
Aqui está a mensagem de erro encontrada:
index.js:104 DEBUG: -------------------------------
index.js:104 DEBUG: Ember : 6.6.0
index.js:104 DEBUG: -------------------------------
app.js:271 ℹ️ Discourse v3.6.0.beta1-dev — https://github.com/discourse/discourse/commits/1d5b82ed51 — Ember v6.6.0
dev-tools.js:47 Carregando ferramentas de desenvolvimento do Discourse...
contentCommunicatorMain.js:1 -- pf - iniciando detecção de script
dev-tools.js:55 Ferramentas de desenvolvimento do Discourse carregadas. Execute `disableDevTools()` no console para desativar.
index.js:104 DEBUG: Para depuração mais avançada, instale o Ember Inspector em https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi
index.js:4148
Ocorreu um erro:
- Ao renderizar:
{{outlet}} para -top-level
-top-level
{{outlet}} para application
application
(componente apenas de template desconhecido)
DiscourseRoot
ComposerContainer
ComposerBody
ComposerEditor
DEditor
PluginOutletComponent
TopicVersionComposer
topic-custom-field-input
Input
execute @ index.js:4148
index.js:3391
Ocorreu um erro:
execute @ index.js:3391
index.js:85 Erro não capturado (na promessa): Tentativa de resolver um helper em um template de modo estrito, mas esse valor não estava no escopo: action
em lookupBuiltInHelper (index.js:85:30)
em index.js:253:60
em encodeOp (index.js:266:8)
em pushOp (index.js:1210:5)
em index.js:636:33
em Compilers.compile (index.js:448:14)
em expr (index.js:461:43)
em CompilePositional (index.js:614:47)
em SimpleArgs (index.js:595:15)
em index.js:1064:12
em index.js:214:11
em encodeOp (index.js:240:7)
em pushOp (index.js:1210:5)
em index.js:1063:35
em Compilers.compile (index.js:448:14)
em compileStatements (index.js:1212:49)
em index.js:1191:18
em CompilableTemplateImpl.compile (index.js:1193:6)
em VM.compile (index.js:3771:31)
em Object.evaluate (index.js:506:25)
em Object.evaluate (index.js:103:106)
em LowLevelVM.evaluateSyscall (index.js:2873:20)
em LowLevelVM.evaluateInner (index.js:2852:64)
em LowLevelVM.evaluateOuter (index.js:2849:10)
em VM.next (index.js:4167:45)
em VM._execute (index.js:4157:21)
em VM.execute (index.js:4137:26)
em TryOpcode.handleException (index.js:3450:19)
em UpdatingVMFrame.handleException (index.js:3592:52)
em UpdatingVM.throw (index.js:3414:16)
em Assert.evaluate (index.js:565:42)
em UpdatingVM._execute (index.js:3401:34)
em index.js:3384:51
em push.../../../../../../../node_modules/.pnpm/ember-source@6.6.0_patch_hash=tyhbf7f4uxnr3gt4x2tdcudbva_@glimmer+component@2.0.0_rsvp@4.8.5/node_modules/ember-source/dist/packages/@glimmer/validator/index.js.debug.runInTrackingTransaction (index.js:44:19)
em UpdatingVM.execute (index.js:3384:15)
em RenderResultImpl.rerender (index.js:3610:8)
em index-BCp6wOJU.js:4639:55
em RootState.render (index-BCp6wOJU.js:4600:9)
em index-BCp6wOJU.js:4934:16
em inTransaction (index.js:2414:7)
em Renderer._renderRoots (index-BCp6wOJU.js:4914:20)
em Renderer._renderRootsTransaction (index-BCp6wOJU.js:4962:12)
em Renderer._revalidate (index-BCp6wOJU.js:4995:10)
em invoke (index.js:262:14)
em Queue.flush (index.js:180:11)
em DeferredActionQueues.flush (index.js:334:19)
em Backburner._end (index.js:762:32)
em Backburner._boundAutorunEnd (index.js:499:12)
index-BCp6wOJU.js:4608 Tentativa de re-renderização, mas o aplicativo Ember apresentou um erro irrecuperável durante a renderização. Você deve recarregar o aplicativo após corrigir a causa do erro.
fn @ index-BCp6wOJU.js:4608
index-BCp6wOJU.js:4608 Tentativa de re-renderização, mas o aplicativo Ember apresentou um erro irrecuperável durante a renderização. Você deve recarregar o aplicativo após corrigir a causa do erro.
fn @ index-BCp6wOJU.js:4608
index-BCp6wOJU.js:4608 Tentativa de re-renderização, mas o aplicativo Ember apresentou um erro irrecuperável durante a renderização. Você deve recarregar o aplicativo após corrigir a causa do erro.
fn @ index-BCp6wOJU.js:4608
index-BCp6wOJU.js:4608 Tentativa de re-renderização, mas o aplicativo Ember apresentou um erro irrecuperável durante a renderização. Você deve recarregar o aplicativo após corrigir a causa do erro.
fn @ index-BCp6wOJU.js:4608
index-BCp6wOJU.js:4608 Tentativa de re-renderização, mas o aplicativo Ember apresentou um erro irrecuperável durante a renderização. Você deve recarregar o aplicativo após corrigir a causa do erro.
fn @ index-BCp6wOJU.js:4608
index-BCp6wOJU.js:4608 Tentativa de re-renderização, mas o aplicativo Ember apresentou um erro irrecuperável durante a renderização. Você deve recarregar o aplicativo após corrigir a causa do erro.
fn @ index-BCp6wOJU.js:4608
- Visualização de edição de tópico => ERRO, os campos não aparecem e não consigo validar a modificação do título.
Aqui está a mensagem encontrada — muito semelhante à anterior — :
index.js:4148
Ocorreu um erro:
- Ao renderizar:
{{outlet}} para -top-level
-top-level
{{outlet}} para application
application
(componente apenas de template desconhecido)
DiscourseRoot
{{outlet}} para topic
topic
(componente apenas de template desconhecido)
DiscourseTopic
TopicTitle
PluginOutletComponent
TopicVersionEditTopic
topic-custom-field-input
Input
execute @ index.js:4148
handleException @ index.js:3450
handleException @ index.js:3592
throw @ index.js:3414
evaluate @ index.js:565
_execute @ index.js:3401
(anônimo) @ index.js:3384
push.../../../../../../../node_modules/.pnpm/ember-source@6.6.0_patch_hash=tyhbf7f4uxnr3gt4x2tdcudbva_@glimmer+component@2.0.0_rsvp@4.8.5/node_modules/ember-source/dist/packages/@glimmer/validator/index.js.debug.runInTrackingTransaction @ index.js:44
execute @ index.js:3384
rerender @ index.js:3610
(anônimo) @ index-BCp6wOJU.js:4639
(anônimo) @ index-BCp6wOJU.js:4600
(anônimo) @ index-BCp6wOJU.js:4934
inTransaction @ index.js:2414
_renderRoots @ index-BCp6wOJU.js:4914
_renderRootsTransaction @ index-BCp6wOJU.js:4962
_revalidate @ index-BCp6wOJU.js:4995
invoke @ index.js:262
flush @ index.js:180
flush @ index.js:334
_end @ index.js:762
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_ensureInstance @ index.js:919
ensureInstance @ index.js:731
scheduleRevalidate @ index-BCp6wOJU.js:3609
dirtyTag @ index.js:229
dirtyTagFor @ index.js:287
markObjectAsDirty @ cache-fCezwMOy.js:49
notifyPropertyChange @ cache-fCezwMOy.js:745
_setProp @ property_set-2JtwI-ab.js:66
set @ property_set-2JtwI-ab.js:42
set @ observable.js:27
editTopic @ topic.js:376
index.js:3391
Ocorreu um erro:
execute @ index.js:3391
rerender @ index.js:3610
(anônimo) @ index-BCp6wOJU.js:4639
(anônimo) @ index-BCp6wOJU.js:4600
(anônimo) @ index-BCp6wOJU.js:4934
inTransaction @ index.js:2414
_renderRoots @ index-BCp6wOJU.js:4914
_renderRootsTransaction @ index-BCp6wOJU.js:4962
_revalidate @ index-BCp6wOJU.js:4995
invoke @ index.js:262
flush @ index.js:180
flush @ index.js:334
_end @ index.js:762
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_ensureInstance @ index.js:919
ensureInstance @ index.js:731
scheduleRevalidate @ index-BCp6wOJU.js:3609
dirtyTag @ index.js:229
dirtyTagFor @ index.js:287
markObjectAsDirty @ cache-fCezwMOy.js:49
notifyPropertyChange @ cache-fCezwMOy.js:745
_setProp @ property_set-2JtwI-ab.js:66
set @ property_set-2JtwI-ab.js:42
set @ observable.js:27
editTopic @ topic.js:376
5:1 O processamento de foco automático foi bloqueado porque o documento já possui um elemento com foco.
index.js:85 Erro não capturado (na promessa): Tentativa de resolver um helper em um template de modo estrito, mas esse valor não estava no escopo: action
em lookupBuiltInHelper (index.js:85:30)
em index.js:253:60
em encodeOp (index.js:266:8)
em pushOp (index.js:1210:5)
em index.js:636:33
em Compilers.compile (index.js:448:14)
em expr (index.js:461:43)
em CompilePositional (index.js:614:47)
em SimpleArgs (index.js:595:15)
em index.js:1064:12
em index.js:214:11
em encodeOp (index.js:240:7)
em pushOp (index.js:1210:5)
em index.js:1063:35
em Compilers.compile (index.js:448:14)
em compileStatements (index.js:1212:49)
em index.js:1191:18
em CompilableTemplateImpl.compile (index.js:1193:6)
em VM.compile (index.js:3771:31)
em Object.evaluate (index.js:506:25)
em Object.evaluate (index.js:103:106)
em LowLevelVM.evaluateSyscall (index.js:2873:20)
em LowLevelVM.evaluateInner (index.js:2852:64)
em LowLevelVM.evaluateOuter (index.js:2849:10)
em VM.next (index.js:4167:45)
em VM._execute (index.js:4157:21)
em VM.execute (index.js:4137:26)
em TryOpcode.handleException (index.js:3450:19)
em UpdatingVMFrame.handleException (index.js:3592:52)
em UpdatingVM.throw (index.js:3414:16)
em Assert.evaluate (index.js:565:42)
em UpdatingVM._execute (index.js:3401:34)
em index.js:3384:51
em push.../../../../../../../node_modules/.pnpm/ember-source@6.6.0_patch_hash=tyhbf7f4uxnr3gt4x2tdcudbva_@glimmer+component@2.0.0_rsvp@4.8.5/node_modules/ember-source/dist/packages/@glimmer/validator/index.js.debug.runInTrackingTransaction (index.js:44:19)
em UpdatingVM.execute (index.js:3384:15)
em RenderResultImpl.rerender (index.js:3610:8)
em index-BCp6wOJU.js:4639:55
em RootState.render (index-BCp6wOJU.js:4600:9)
em index-BCp6wOJU.js:4934:16
em inTransaction (index.js:2414:7)
em Renderer._renderRoots (index-BCp6wOJU.js:4914:20)
em Renderer._renderRootsTransaction (index-BCp6wOJU.js:4962:12)
em Renderer._revalidate (index-BCp6wOJU.js:4995:10)
em invoke (index.js:262:14)
em Queue.flush (index.js:180:11)
em DeferredActionQueues.flush (index.js:334:19)
em Backburner._end (index.js:762:32)
em Backburner._boundAutorunEnd (index.js:499:12)
lookupBuiltInHelper @ index.js:85
(anônimo) @ index.js:253
encodeOp @ index.js:266
pushOp @ index.js:1210
(anônimo) @ index.js:636
compile @ index.js:448
expr @ index.js:461
CompilePositional @ index.js:614
SimpleArgs @ index.js:595
(anônimo) @ index.js:1064
(anônimo) @ index.js:214
encodeOp @ index.js:240
pushOp @ index.js:1210
(anônimo) @ index.js:1063
compile @ index.js:448
compileStatements @ index.js:1212
(anônimo) @ index.js:1191
compile @ index.js:1193
compile @ index.js:3771
(anônimo) @ index.js:506
evaluate @ index.js:103
evaluateSyscall @ index.js:2873
evaluateInner @ index.js:2852
evaluateOuter @ index.js:2849
next @ index.js:4167
_execute @ index.js:4157
execute @ index.js:4137
handleException @ index.js:3450
handleException @ index.js:3592
throw @ index.js:3414
evaluate @ index.js:565
_execute @ index.js:3401
(anônimo) @ index.js:3384
push.../../../../../../../node_modules/.pnpm/ember-source@6.6.0_patch_hash=tyhbf7f4uxnr3gt4x2tdcudbva_@glimmer+component@2.0.0_rsvp@4.8.5/node_modules/ember-source/dist/packages/@glimmer/validator/index.js.debug.runInTrackingTransaction @ index.js:44
execute @ index.js:3384
rerender @ index.js:3610
(anônimo) @ index-BCp6wOJU.js:4639
(anônimo) @ index-BCp6wOJU.js:4600
(anônimo) @ index-BCp6wOJU.js:4934
inTransaction @ index.js:2414
_renderRoots @ index-BCp6wOJU.js:4914
_renderRootsTransaction @ index-BCp6wOJU.js:4962
_revalidate @ index-BCp6wOJU.js:4995
invoke @ index.js:262
flush @ index.js:180
flush @ index.js:334
_end @ index.js:762
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
Backburner._boundAutorunEnd @ index.js:499
Promise.then
iterations @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_ensureInstance @ index.js:919
ensureInstance @ index.js:731
scheduleRevalidate @ index-BCp6wOJU.js:3609
dirtyTag @ index.js:229
dirtyTagFor @ index.js:287
markObjectAsDirty @ cache-fCezwMOy.js:49
notifyPropertyChange @ cache-fCezwMOy.js:745
_setProp @ property_set-2JtwI-ab.js:66
set @ property_set-2JtwI-ab.js:42
set @ observable.js:27
editTopic @ topic.js:376
Alguém aqui está enfrentando o mesmo problema?
Olá @cdervout,
Problema
O componente de entrada de campo personalizado de tópico usava a sintaxe legada:
{{on "change" (action @onChangeField value="target.value")}}
- Essa sintaxe
(action …)não é suportada em componentes Glimmer modernos. - Consequentemente, o campo não foi renderizado no compositor.
Correção
Substituí a sintaxe antiga por uma ação Glimmer moderna:
{{on "input" this.handleInputChange}}
E adicionei o método JS correspondente:
@action
handleInputChange(event) {
this.args.onChangeField(event.target.value);
}
- Isso garante que o campo seja renderizado corretamente no compositor.
Código do componente refatorado
import Component from "@glimmer/component";
import { Input, Textarea } from "@ember/component";
import { on } from "@ember/modifier";
import { readOnly } from "@ember/object/computed";
import { service } from "@ember/service";
import { eq } from "truth-helpers";
import i18n from "discourse-common/helpers/i18n";
import { action } from "@ember/object";
export default class TopicCustomFieldInput extends Component {
@service siteSettings;
@readOnly("siteSettings.topic_custom_field_name") fieldName;
@readOnly("siteSettings.topic_custom_field_type") fieldType;
@action
handleInputChange(event) {
this.args.onChangeField(event.target.value);
}
<template>
{{#if (eq this.fieldType "boolean")}}
<Input
@type="checkbox"
@checked={{@fieldValue}}
{{on "input" this.handleInputChange}}
/>
<span>{{this.fieldName}}</span>
{{/if}}
{{#if (eq this.fieldType "integer")}}
<Input
@type="number"
@value={{@fieldValue}}
placeholder={{i18n
"topic_custom_field.placeholder"
field=this.fieldName
}}
class="topic-custom-field-input small"
{{on "input" this.handleInputChange}}
/>
{{/if}}
{{#if (eq this.fieldType "string")}}
<Input
@type="text"
@value={{@fieldValue}}
placeholder={{i18n
"topic_custom_field.placeholder"
field=this.fieldName
}}
class="topic-custom-field-input large"
{{on "input" this.handleInputChange}}
/>
{{/if}}
{{#if (eq this.fieldType "json")}}
<Textarea
@value={{@fieldValue}}
{{on "input" this.handleInputChange}}
placeholder={{i18n
"topic_custom_field.placeholder"
field=this.fieldName
}}
class="topic-custom-field-textarea"
/>
{{/if}}
</template>
}
EDIT: Levantei um PR para o mesmo
Obrigado, tudo funciona bem!
Adaptei o código para o caso em que o campo é uma caixa de seleção. Para obter o valor, tive que usar event.target.checked em vez de event.target.value.

