I recently dug deeper into the archetype system to figure out how it can, does and should work. In order to not get lost in the task, I decided to try to implement one very specific, narrow use case: Questions. I settled to try to get the following criteria done:
- add an archetype discourse core don’t have any specific knowledge of
- the archetype should show up in searches and listings as a normal
topic and otherwise behave like the normal topic (unlike than for e.g. the private
- the posts for this archetype are not ordered chronologically but by “most likes”
- the view shall be adapted to have a more explicit visibility of these likes for answers
In order to be able to get 2) done, I needed to refactor the archetype-system. Until this point the archetypes are referenced directly within the core on various occasion. To make it work I changed that into a capability-driven approach: when a Archetype is registered it provides a list of features it is capable of, for example to be shown publicly or be searchable. Then I replaced all occurrences of direct references with the appropriate capability.
That way I was able to add another Archtype - Question - which is also rendered in the lists because it has the capability of been publicly shown, while delivering it as a plugin and without discourse core having any previous knowledge about it - yay.
After that change the second two features weren’t that big of a deal, though a little hackish. As discourse code around the topic and posts-view is rather complex (to do autoloading and stuff), just providing my own ordering didn’t really work. So I patched the Like-Action to reset the score_order every time someone likes or unlikes a post of the topic-archetype question.
Secondly in order to be able to change the UI I did the usual reopening of Ember Views. Unfortunately, as the block relies on
spanX-grids I also had to patch that so that it fits in the view after adding my heart-shaped answer-score. But I got it working:
I am writing this post as a case study and in order to open the discussion on how archetype delivery through plugins should work (as I think it makes a whole lot of sense to have custom archetypes coming from plugins – you don’t want to ship everything with the core). What I did here is in no way meant as a plugin for production but it shows the main weaknesses in discourse when shipping your own archetypes:
- certain Archtypes are currently hard-coded and their usage in core is limited to them even if you’d ship your own archetype (this can be fixed with my capability-focussed patchset)
- the core posts-rendering heavily expects the discussion use case to be the way things are supposed to be done and patching that part is nearly impossible
- the views (and especially the templates) are currently hard-coded towards the existing archteypes. Unless the plugin overwrites them entirely, the extensibility of rendering for shipped archtypes is very limited.
- The same is true for the composer. That part is even more complex and though it looks like it was meant at some point that you should be able to “switch archetypes”, there is really no possible way for an archetype to be provider their own extensions or even full blown other editors.
Regard 1 I have the patch-set ready including tests and everything working and I am happy to make it into a pull-request if that is an approach we want to take. As for 2, 3 and 4 I don’t have a concrete solution at the moment but from what I feel there is little other possibility than adding explicit hooks in them to allow plugins to ship their own to be called and rendered or – if none found – just render the default one.