Here’s a currently working basic example of creating a topic custom field, and then setting it. This sets the field when the user clicks a particular button on the topic view page.
I note that in the plugins that have topic custom fields, there’s a common use in plugin.rb of PostRevisor (like PostRevisor.track_topic_field
) and DiscourseEvent.on(:topic_created) do |topic|...
These might allow setting the custom field without having to hit a button–such as setting the custom field when the topic is created. But I haven’t figured that out yet.
[EDIT: If anyone wants to suggest code for plugin.rb to add the custom field value to a topic at the time of creating the topic (instead of having a separate button that needs to be clicked), please do! ]
So here’s a basic example that works without that fancy stuff:
plugin.rb
Topic.register_custom_field_type('sample_field', :string)
add_to_class(:topic, :sample_field) { self.custom_fields['sample_field'] } ##maybe not necessary. based on line 83 of discourse-locations plugin plugin.rb
add_to_serializer(:topic_view, :sample_field, false) { object.topic.sample_field } ##probably only necessary if you want to show the custom field result to the user
connector/[add-button].hbs
//example here: connector is topic-above-post-stream, which passes a model (topic) in the plugin outlet
<button {{action "setThatTopic" model}}>Click Here</button>
connector/[add-button].js.es6
import Topic from 'discourse/models/topic'; //may not be necessary
export default {
actions: {
setThatTopic(model){
model.set('custom_fields.sample_field', 'newValue123')
console.log('testing that custom field is there = ' + JSON.stringify(model.custom_fields))
}
}
}
assets/javascripts/initializers/topic-custom-field.js.es6
//this might not be necessary. But the idea is to initialize the custom fields object, and make it so it can be sent to the server:
import { withPluginApi } from 'discourse/lib/plugin-api';
export default {
name: 'topic-custom-field',
initialize() {
withPluginApi('0.8.31', api => {
api.modifyClass('model:topic', {
custom_fields: {},
asJSON() {
return Object.assign(this._super(), {
custom_fields: this.custom_fields
});
}
})
})
}
}