Knowledge Base Plugin

I will as soon as I finish a forced but needed migration and see if the issue still exists. Thanks, didn’t realize this was there, and will be helpful for reporting any bugs in the future!

Just an idea: There is a functionality that this plugin could “steal” from another similar one ( Knowledge Explorer Plugin ). It’s the ability to select what’s displayed in the knowledge base with tags instead of just categories. That enables to just cherry pick some topics from anywhere.

On desktop, the KB looks great, but on mobile it’s just a tiny rectangle on the top left. Would it be possible to show it expanded by default?

I tried finding the piece of code that is in charge of this, but I wasn’t able to figure it out. Removing this unless didn’t do the trick. :thinking:


@Nacho_Caballero You could have it always expanded if you force expanded to be true in the knowledge-base-nav component, and remove the bound events in that component. I don’t have the time right now to work that up for you, but happy to accept a PR / give further pointers.

More broadly I’ve been hestitant to work on this plugin because there’s a fair degree of overlap with @justindirose’s excellent Knowledge Base Theme Component.

If users of this plugin see same tangible differences that are not feasible to include in Justin’s work, then we can invest more resources in improving and maintaing this (cc @FoohonPie)


Thanks for the reply, Angus. I’ll give it a try :+1:

These are the reasons I prefer your plugin over Justin’s:

  • You let me put a help icon next to the search icon (instead of adding a KB nav pill inside each category)
  • You only show the first post of the topic (which lets me keep the discussion separate from the actual help guide)

I see benefits to both approaches, but your style fits better with the way I want to help my audience.

Justin has gone even further now and created the Knowledge Explorer Plugin. I’m not sure how it relates to the theme component he created and its status… but I think it goes further. I agree with you Angus that it might be better to focus energies on helping Justin. Using official plugins is always a Good Thing™.

That said, there are quite a few features I really like from this knowledge base plugin that I miss! We put some excellent thought and work in, Angus, so let’s think some more about it before we throw it all away. If Justin is not interested in them and if we have a maintainer, maybe we should keep going here. Also, our plugin is actually working pretty well now and Justin’s work is still in progress and there is not much info available on his plans.

I think Justin is pursuing a different model where sites have maybe one or two KB categories with lots of topics that can be drilled down into using tags. Topics inside them appear as discussion topics with all the replies and discussion features intact. Ours is based on having one category with lots of sub-categories that can be drilled down into using a navigation menu. Topics inside are clean and have no discussion features, with link across to the discussion topic.

In bullet points, features I like are:

  • automatic support for sub-categories so you can have a kb category, and each sub-category is automagically included as a section. lovely!
  • respects category permissions to display categories and topics within them only to people with access
  • super handy table of contents that can have sections opened/closed to drill down
  • ability to manually set the sort order of topics in the table of contents
  • landing page text for the kb
  • landing pages for each section drawn from the about page
  • clean display of the kb topic, with no discussion features (but with link across to the discussion)

Some work that seems needed to bring this plugin up to speed:

  • ability to reorder sections (feature request)
  • display DiscoTOC (feature request)
  • ability to export/print entire section at once
  • toggle to switch back and forth between kb view of topic and discussion view, that works both ways (feature request)
  • ability to restrict keyword search kb topics when within the kb
  • ability to link directly to a section to display it without the distraction of other sections (eg /k/helpdesk to display just the helpdesk knowledgebase). Maybe also ability to confiure multiple knowledge base root categories.
  • ability to edit kb topics directly from the kb, maybe by adding EDIT link next to PRINT

Some bugs I noticed trying it today on my work community:

  • name space collision with knowledge base theme component (I think - this may be resolved)
  • printing works, but takes user away from page and displays topic with pencil shaded theme. (on my site, also does not exclude some theme customizations that interfere)
  • KNOWLEDGE BASE is displayed on top menu, but links to /c/kb/l/kb path which is incorrect. Should link to /k which does work.
  • for some reason, first item on the knowledge base menu is knowledge base - and seems to contain all topics in the sub-categories. links broken.

Some features from Justin’s work that I now miss:

  • tag filtering!
  • default to kb view within regular usage of forum
  • big search form right at the top

Screen shots


I’m getting the same error. I love the plugin, but it completely breaks the search function. I’ve submitted a bug report as well. Thanks!


It seems this plugin causes my discourse instance to fail (bootstraps, but site doesn’t load) if I use it along with the Solved plugin. In other words, I seem to have to choose between the two plugins. Wondering if anyone else has run into this?

edit: Specifically it seems to fail in this manner if I try to nav from the admin panel to the homepage/forum index:

Server Error

while trying to load [/categories.json](DOMAIN/categories.json)

with domain being my app’s root domain

edit: This looks to manifest the same way as the bug @Ryan_Hyer is mentioning. Again (same logged error), it stops if I remove the solved plugin (which is listed in his list of used plugins) so I assume it is some sort of conflict between the two

1 Like

Yeah the idea on Knowledge Explorer is to filter and search any knowledge-base type topic across a set of selected categories and tags. It’s more about discovery and less about creating a structured KB like this plugin does. There are definitely two different use cases here.

The iteration released 2019-10-31T05:00:00Z pulls just the OP into the explorer view, versus the discussion. There is a link to the discussion if that is needed however.


Given the issues with this plugin, I would not recommend installing it until a path forward has been determined for it by @angus and his pavilion colleagues. The Knowledge Explorer Plugin is an impressive alternative, showing much promise. It will likely be an official plugin so it’s highly recommended.

Cool! I can repro this. Let’s keep the convo about this bug over here:

Hello - can anyone point me to a forum that is currently using this KB plugin? Would like to see the user experience. Thanks!

Hi Nina! Great to see you here and that you’re also interested in this plugin. Take a look at What is Pavilion? where you can see it in action.

Do note that as I wrote above, the plugin has some issues so I would not recommend you use it in production until they get resolved.

I do hope we get back to work on improving it, because it has some significant benefits over the knowledge explorer plugin. I love the PRINT button and the ability to arbitrarily reorder the topics in the table of contents, as well as the clean interface.


Thanks @tobiaseigen! A few follow up questions:

I’m trying to understand the user experience with the plugin (but can’t right now given the bugs). Is my understanding of how the plugin correct: any guides that I want in my KB would need to be written and published in the form of a post at first; when we apply the KB setting to this post, the KB will create another view of this content in the KB format. However, the original post still exists on the forum.

Separately, curious, what are the advantages of using the KB plugin versus the knowledge explorer plugin?

Hi Nina! I realize this is a pretty long topic, but it’s worth reading through it to find answers to your questions. This post a few above this one I think goes through the differences: Knowledge Base Plugin

You can also install both plugins to try them out - it doesn’t break anything too severely - and then remove the one you don’t want to keep. Later you can also always switch horses if circumstances change.

Here’s an example of the knowledge explorer in action - as you’ll see it supports DiscoTOC which is nice, and a menu of categories and tags. Pretty neat, and also a very clean interface. Global Legal Empowerment Network Community Discussions


@angus or whomever needs to see this…

I received an error lately with your plugin installed and had to disable it. Was suggested that I post here. The thread with all the screenshots and errors can be found here.


Thanks @jonwgeorge. I’ll be able to take a look at this around the middle of next week.


For me, I’m getting the error whenever I click on the :mag: button in the header, and then type a word in the box that pops up.

StandardError (Attempting to access a non preloaded custom field, this is disallowed to prevent N+1 queries.) /var/www/discourse/app/models/concerns/has_custom_fields.rb:164:in []’`

/var/www/discourse/app/models/concerns/has_custom_fields.rb:164:in `[]'
/var/www/discourse/plugins/discourse-knowledge-base/plugin.rb:67:in `knowledge_base_index'
/var/www/discourse/plugins/discourse-knowledge-base/plugin.rb:76:in `block (2 levels) in activate!'
(eval):33:in `_fast_attributes'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:456:in `attributes'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:480:in `_serializable_hash'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:359:in `serializable_hash'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:448:in `block in merge_association'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:445:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:445:in `merge_association'
/var/www/discourse/lib/freedom_patches/ams_include_without_root.rb:54:in `include!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:368:in `block in include_associations!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:367:in `each_key'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:367:in `include_associations!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:362:in `serializable_hash'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:448:in `block in merge_association'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:445:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:445:in `merge_association'
/var/www/discourse/lib/freedom_patches/ams_include_without_root.rb:54:in `include!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:368:in `block in include_associations!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:367:in `each_key'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:367:in `include_associations!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:362:in `serializable_hash'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:343:in `as_json'
/var/www/discourse/app/controllers/application_controller.rb:429:in `serialize_data'
/var/www/discourse/app/controllers/application_controller.rb:438:in `render_serialized'
/var/www/discourse/app/controllers/search_controller.rb:103:in `query'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/base.rb:196:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/rendering.rb:30:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications.rb:180:in `block in instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/notifications.rb:180:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.1/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/abstract_controller/base.rb:136:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionview-6.0.1/lib/action_view/rendering.rb:39:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.5/lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal.rb:191:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_controller/metal.rb:252:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:33:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:49:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/journey/router.rb:32:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/routing/route_set.rb:837:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/conditional_get.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:318:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/session/abstract/id.rb:259:in `context'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/session/abstract/id.rb:253:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/cookies.rb:648:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/callbacks.rb:101:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.5.1/lib/logster/middleware/reporter.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.5/lib/mini_profiler/profiler.rb:296:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.3/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:181:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/engine.rb:526:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:605:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:700:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:562:in `maintain_worker_count'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:295:in `join'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'

hm interesting. The current version of the knowledge-base plugin preloads that field: discourse-knowledge-base/plugin.rb at master · angusmcleod/discourse-knowledge-base · GitHub. Are you using an old version of discourse? (or the plugin?).

In any event, I’ve decided that we’re going to keep / continue to support this plugin, and I’m currently updating / bugfixing it. I’ll take a look.


Up to date on the beta for Discourse (2.4.0.beta10) and also up to date on this and other plugins. Thanks!

Update: Just wanted to say that I confirmed disabling the plugin in the admin settings restores access to the search. When I re-enable it, the search breaks again.

Hey Angus, I’m getting this error when clicking any of the tabs. I have no idea how long it has been broken, any ideas?

while trying to load /k/site-discussions-site-tips/faq-guidelines/6431.json

{"errors":["You supplied invalid parameters to the request: Discourse::InvalidParameters"],"error_type":"invalid_parameters"}