Layouts Plugin

The only ones I’m aware of are mine and those made by @Alavi1412. It is relatively easy to adapt any existing Discourse widget or combination of widgets to work with this plugin.

I’m not sure what you mean?

Yeah. That’s just the custom html plugin. The issue is with the js in the script tag I included in the custom html, not with the custom html plugin or layouts plugin.

Consider it wiki’d. :spiral_notepad:


Hey, @angus. Something got broken. I’m re-categorizing until it’s fixed.

I saw some post that was a callout to all plugin developers, that I suspect was related, but I can’t find it.

I, [2017-09-25T16:53:06.407281 #15]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
rake aborted!
NoMethodError: undefined method `before_filter' for DiscourseLayouts::WidgetController:Class
Did you mean?  before_action
/var/www/discourse/plugins/discourse-layouts/controllers/widget.rb:4:in `<class:WidgetController>'
/var/www/discourse/plugins/discourse-layouts/controllers/widget.rb:3:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:286:in `load'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:286:in `block in load'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:258:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:286:in `load'
/var/www/discourse/plugins/discourse-layouts/plugin.rb:51:in `block in activate!'
/var/www/discourse/lib/plugin/instance.rb:248:in `block in notify_after_initialize'
/var/www/discourse/lib/plugin/instance.rb:246:in `each'
/var/www/discourse/lib/plugin/instance.rb:246:in `notify_after_initialize'
/var/www/discourse/config/application.rb:211:in `each'
/var/www/discourse/config/application.rb:211:in `block in <class:Application>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/lazy_load_hooks.rb:43:in `execute_hook'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/lazy_load_hooks.rb:51:in `each'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/application/finisher.rb:73:in `block in <module:Finisher>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/initializable.rb:30:in `instance_exec'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/initializable.rb:30:in `run'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/initializable.rb:59:in `block in run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/initializable.rb:58:in `run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/application.rb:353:in `initialize!'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/railtie.rb:185:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/railtie.rb:185:in `method_missing'
/var/www/discourse/config/environment.rb:5:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:292:in `require'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:292:in `block in require'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:258:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:292:in `require'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/application.rb:329:in `require_environment!'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-5.1.3/lib/rails/application.rb:445:in `block in run_tasks_blocks'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:22:in `load'
/usr/local/bin/bundle:22:in `<main>'
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)

It’s due to discourse being on rails 5.1 now, should be an easy fix.


Fixed :sunny:


@pfaffman Could you re-categorize? Thanks.


I assumed that you could! It’s your post. But thanks @jomaxro!


Hi Angus,

After the update, the layouts plugin and widgets are working fine, but the widget selection page (in admin panel) is blank.

1 Like

Hm, I’m not seeing an issue. Did you clear the plugins using the X button? If so try rebuilding your container.

this is the snapshot of the admin-widget selection page.

I have two widgets installed: custom-html and the modified profile widget, both updated after Rails 5.1 update.

Still can’t reproduce this error :confused: . I’ve tried using just your profile widget and the custom html widget. The layouts admin works fine. Also, those logs seem unconnected to the layouts code. Have you tried rebuilding your container (i.e. ./launcher rebuild app)? Are you using the Discourse Master branch? What other plugins do you have installed?

yes, everything as said: we are using the Master branch + we have rebuild recently (yesterday).

math, header search, cake-day, data-explorer, and telegram notification.


1 Like

nada. To help you further, I’ll either need more logs, or access to your instance.


here is the error I got repeatedly these days:

Job exception: Unsupported argument type: 2187 (Fixnum)

/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activerecord-5.1.3/lib/active_record/relation/where_clause_factory.rb:27:in `build'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activerecord-5.1.3/lib/active_record/relation/query_methods.rb:612:in `where!'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activerecord-5.1.3/lib/active_record/relation/query_methods.rb:605:in `where'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activerecord-5.1.3/lib/active_record/relation/finder_methods.rb:78:in `find_by'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activerecord-5.1.3/lib/active_record/querying.rb:7:in `find_by'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activerecord-5.1.3/lib/active_record/core.rb:203:in `find_by'
/var/www/discourse/app/jobs/regular/create_avatar_thumbnails.rb:12:in `execute'
/var/www/discourse/app/jobs/base.rb:153:in `block (2 levels) in perform'

does it help?

even browser is up-to-date! and I’m not sure where this comes from.

1 Like

I recently heard about plugin and wanted to make use of it to enable a navigation sidebar in my topics page.

1 Like

Yup, you can do that with this plugin. You will need your own navigation widget though. Or you could try using the custom html widget.

1 Like

How do I get the custom html widget?

1 Like


I was trying to add the “create new topic” button to the profile widget and failed miserably :smile:

Now, I get an error in the console after rebuilding with official profile widget.

Did something change in Discourse?

Error: Could not find module discourse/widgets/component_connector imported from discourse/plugins/layouts-profile/discourse/widgets/profile


Well it turns out something has changed. I looked at the Discourse Repo and apparently widgets/component_connector was modified 4 days ago.

It’s is not called widgets/component_connector Then name is actually widgets/component-connector

So I edited Line #2 in layouts-profile/assets/javascripts/discourse/widgets/profile.js.es6

From this:

import ComponentConnector from 'discourse/widgets/component_connector';

To this:

import ComponentConnector from 'discourse/widgets/component-connector';

And everything seems to be back to normal now.

Still haven’t figured out how to add the “New topic” button yet though, even though I went through the lovely instructions above in this post. :grin:

One of those days…

1 Like

Thanks for the report :+1:

I’ve updated the widget so that it works with the latest. And added some other minor fixes.

As it sounds like you’ve already read my previous explanation of how to do this and given it a shot, here’s some working methods with an explanation of what is going on. Add the methods to your version of the profile widget and see how you go.

First, let’s add a new button widget to the actions array, at the bottom of the html() method (before actions is pushed to contents).

actions.push(this.attach('button', {
  label: 'topic.create',
  icon: 'plus',
  action: 'createTopic',
  className: 'btn-small'

Then add the createTopic method as a new method in the widget. I’ve added some comments to explain what’s going on. I’ve assumed that you want the button to work in both discovery (i.e. topic lists) and topic routes. This method is designed to work in both.

createTopic() {
  // First we get the composer controller,  as that is what we'll need 
  // to open the composer with. As we want to also check for existing 
  // drafts and the current discovery category, we'll also get the 
  // discovery controller.
  const discoveryController = this.register.lookup('controller:discovery');
  const composerController = this.register.lookup('controller:composer');

  // I'm assuming the action you want to take is createTopic. The other
  // actions you can take are listed at the top of the composer model.
  let params = { action: 'createTopic' };

  // Here we load the relevant composer params from the discovery controller
  // (they may not exist though, e.g. if we loaded a topic directly)
  const categoryId = discoveryController.get('');
  const draftKey = discoveryController.get('model.draft_key');
  const draftSequence = discoveryController.get('model.draft_sequence');

  // let's assign the topic if we're in a topic
  const topic = this.attrs.topic;

  // First we'll set the initial category in the compose category selector.
  // You could set this to any category id you wanted. But let's set it 
  // to the topic category if we're in a topic and, failing that, the 
  // discovery category if there is one.
  if (topic && topic.get('category')) {
    params['categoryId'] = topic.get('');
  } else if (categoryId) {
    params['categoryId'] = categoryId;

  // if there is a draft new topic in discovery, load it, otherwise start
  // a new one.
  if (draftKey && draftSequence) {
    params['draftKey'] = draftKey;
    params['draftSequence'] = draftSequence;
  } else {
    params['draftKey'] = 'new_topic';

  // Finally, let's open the composer with our params!;

Now we’ve got a New Topic button in the profile widget.

If you wanted a createTopic button that only works in discovery routes, that’s actually a lot simpler, as you just need to send createTopic to route:discovery and it will handle the rest. However, as you seem to be using the profile widget in both discovery and topic contexts, the above method will work in both.


That was incredibly kind of you to go thought that tutorial again! I read and went through the steps once again. And read the original instructions one more time, but still :upside_down_face:

I want to thank you regardless though. I will try to go through the instructions one or two more times and let you know what happens :crossed_fingers:

1 Like