I am developing a paid plugin (don’t know whether it’s ok to public) where I need to set a category specific setting. Therefore, I compare several possible ways and proposal my suggestion.
With existing convenient custom_fields, it’s intuitive to put category-specific settings in the CategoryCustomField
. discourse-solved takes this approach. Solved plugin uses the setting to permit action in server, while I am also interested in knowing the category settings in the client when user opens the category chooser or composer.
Settings in Category’s custom_fields
Simply adding a template and binding it to associate custom fields:
https://github.com/discourse/discourse-solved/blob/master/assets/javascripts/discourse/pre-initializers/extend-category-for-solved.js.es6
Server will store them in CategoryCustomField. It’s easy to pluck all of them (See Guardian)
Category has 3 serializers. 2 of them:
BasicCategorySerializer
Discourse preloads categories by BasicCategorySerializer
with initial HTML. But custom_fields is not included. custom_fields
may be huge.
CategorySerializer
Right now, discourse serializes custom_fields
for category by CategorySerializer
. In client site, we may ask Category.reloadById
to get more data about category including custom_fields
. For the record, it’s invoked by editCategory(category)
in routes/application.js when you click Edit category button.
While you have to try to post a lot of GET requests to get custom fields and it’s asynchronous. The delay and many requests approach failed when you want to change the UI according to user’s interaction. However, if you store anything fairly long, it may not be a bad place.
Site serializer
When the settings is small (hopefully, most cases), push them to site serializer by: (e.g.)
add_to_serializer(:site, :can_create_tag) { scope.can_create_tag? }
In client side:
Discourse.Site.currentProp('can_tag_topics')