Case-Study for Archetypes: Questions-Archetype

(Benjamin Kampmann) #1

Hello everyone,

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:

  1. 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:

  1. 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)
  2. 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
  3. 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.
  4. 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.


Discourse Version 1.2
Slow sql queries
(Zane Beckman) #2

I haven’t seen anything from the core team with regard to these patches or features, but they seem like a very instrumental tool for plugin authors.

For example, plugins implementing…

  • A bug report archetype with issue tracking functionality
  • A product page archetype for sites with products to peddle
  • This Q&A example archetype

My only addition / suggestion to @lightyear’s existing patches is that archetypes should also be category-based. That is, archetypes should be bound to specific categories whenever possible, limiting (or eliminating) the frequency that users would ever select the archetype of their post, and simplifying (slightly), some of @lightyear’s issues described above.

Perhaps archetypes could be manually adjusted by staff – for example – to create an introductory post in the bugs category, despite “bug / issue” being the specified archetype for that category.

Category bound archetypes could also open the door to custom templates / layouts of the topic listing itself. This would be particularly applicable to a “product page” archetype – the topic listing would become a listing of products with thumbnails, etc. For an issue tracking archetype, it could simply allow filtering by status. For a Q&A plugin, it may be a much more subtle tweak to how topics are sorted and displayed.

Edit: I’ve rerolled the 6 patches to apply cleanly on the latest discourse master. They’re in one patch file (for my ease in the rerolling process). It builds and runs with the patches applied, but I have not run tests on it, nor am I entirely sure that I didn’t miss something (It was suspiciously easy…). The updated patch is available here. (update: here.)

(Zane Beckman) #3

It turns out it did need a few updates and fixes. I’ll be maintaining a fork with these patches implemented here. It’s mostly working.

The only issue I’ve seen is that it sometimes takes two clicks on a navitem to get the contents to load. I’ve been unable to pinpoint exactly what the issue is there. (What is unique about the first time a navitem (i.e. categories) is loaded that doesn’t happen subsequent times?)


Give me that and I would switch platform right away.

That said, different content types will really make the Discourse platform flexible and much more useful.

(Sam Saffron) #5

I have been thinking about this stuff for quite a while. I wonder, why can’t all of this simply at the category level, promoting an archetype here means I need to make yet another decision when creating a topic

What category is it?
What tag is it?
What type of thing is this?

Instead I feel it is much simpler and a far smaller patch set to glue extra semantics at the category level

(Erlend Sogge Heggen) #6

Could I:

  • enforce a special archetype on a sub-category;
  • have topics from that sub-category show up as normal together with other topics in the parent category;
  • but when drilling into that special sub-category, show a custom topic index, e.g. something SO-esque?

(Sam Saffron) #7

Well that would be my pref for any initial work here, allow you to register a special view and serializer for a category, which would work like you described

(Erlend Sogge Heggen) #8

Right. What about moving archetype-topics around? Would there be any restrictions on changing the category of a topic to/from an archetype?

(Benjamin Kampmann) #9

This was a case study I had build for a client about one and a half years ago. Though the result of that very much is in production today, it has evolved a lot since. Among others, we added

  • capabilities to show videos and tips rather than discussion (both understood as different archetype)
  • filter lists by archetypes (see only videos)
  • restrict archetypes per category
  • have different composing of topics of different archetypes (backend mostly)

All archetypes can also ship their own rendering part and some even mess with structure in the backend (we even had a multi-level commenting system based on posts, which was returned by the backend as tree rather than a historical feed). I don’t think discussion this overall case study makes much sense at this point, as it has evolved a lot – but rather take a look at the various parts that it had too touch.

We’ve already worked on the plugin-system for extending templates/views a lot since then. The plugin outlets for example, would make this study come up with quite a different outcome, I’d suggest.

What I am happy to discuss, however, is to decouple DC’s core more from the specific archetypes in use, and make that system more flexible. The rewrite that underlies here, instead of insisting on specific archetype names, uses an idea of “archetype capabilities”: an archetype can list multiple capabilities it offers, like “can be searched”, “can be shown in lists”. And instead of doing a sql archetype <> private_message uses those capabilities to make that query ('topics.archetype in (?)', Archetype.capable(:shown_publicly)). Concerns about performance here, didn’t show to have any root in practice – both are equally as fast, even on a 1mio topics heavy DB.

In that way, I’d personally also make the wiki such an archetype, as the “any post could be an wiki everyone wants to edit” didn’t really turn out to be a use case: in practice the first post is the one that is edited. And make it actually render slightly different, where the discussion either happens a below or wikipedia-style on a different tab.

What is great about that system imho, is that it would actually allow for putting features like private messages and wiki into its own plugins, allowing for easy ways to turn them on and off. And if that was actually tried (at least for wikis) it could prove how also a ticket-system could easily be done with DC.

(Erlend Sogge Heggen) #10

Shouldn’t wiki just be another “archetype capability”, so that in an archetype you could say “enforces wiki topics”?

Just had to pop that in there. I’ll leave it to you devs to hash things out now.

(Benjamin Kampmann) #11

I personally don’t like the description of “wiki” in the first place, as it describes a process not even the means of production, nor the result. The “PEDIA” is what makes “wikipedia” an important thing – wiki is just their process. So, to an extend I agree. We had a similar behaviour on a specific “faq”-archetype, which the community (as in moderators) manages FAQ-Articles within a specific sub-category. But there edit-capabilties were also much more fine-grained than wiki is right now. In any case, for this archetype you don’t want the jump-to-last-read-post-behaviour but always see the article itself and have an extensive history view. And that kinda stuff…

(Tom Newsom) #12

Feels like “Document” is the archetype here. Whether it has one or many authors is by-the-by.

PS: I’d love to have this feature for my own wiki topics.

(Erick Guan) #13

Continuing the discussion from Links Category for Discourse:

The plugin is at category level as discourse-solved does. The composer collapse when the user choose the right category and pops up a url text field. I copied code from the core to reuse NewPostManager.
The controller enforces the validation and push the link with skip_validations to skip all validation, e.g. min character check, similarity. PostRevisor got a monkey patch to disable changing category of such topics.

The implementation looks hacky even at category level. It seems to me that Archetype is not conflict with the idea.
It’s particularly hard to let composer know:

  1. there is a new kind of topic which accepts different things other than a markdown text
  2. the validation also changes since the topic is a different kind
  3. category should be a jail to trap this kind of topic. Otherwise, what happened when it’s recategorized

This made Archetype really promising as it can define:

  1. how to display this kind of topic.
  2. how to edit/create this kind of topic.
  3. how to validate this kind of topic.

Knowing category can definitely enforce all of them above. But IMO the category is better to be a trigger point (in composer) and a place to check permission of users.

Merge discourse-links-category into Discourse