Can I override app/views/layouts/application.html.erb from a plugin?

I have a very specific scenario where I need to load and cache the site header and footer from our primary website. This is fairly trivial to do in ERB:

<!-- My Customization -->
  <% cache("footer_#{I18n.locale}", expires_in: 1.week) do %>
    <%= raw open("https://myserver.com/#{I18n.locale}/remote/footer").read %>
  <% end %>
<!-- End Customization -->

Note in my example that I am passing along the I18n locale as well.

Neither the caching nor passing the locale will work with the html custom header option provided with Discourse so Iā€™m left with two options, both of which would need to be implemented as a plugin.


OPTION 1: Use Javascript

There are outlets placed where my header and footer would go, but I donā€™t know how to cache the requests and I can see this quickly becoming taxing on both the server and the Ember app if server-side caching is not used.

OPTION 2: Override the application.html.erb template

First off: I am very aware that I would have to keep my custom plugin in lock-step with any changes to Discourse to ensure that my override doesnā€™t interfere with upgrades.

This would be my preference but I canā€™t seem to find any convention that will let me override the ERB templates from a plugin.

Has anyone tried this? Am I on a fools errand?

Thanks in advance for your help.

2 Likes

Yes, you can override the set_layout method in application_controller.rb. Take a look at this (unfinished) plugin for an example:

https://github.com/scossar/feature-phone-first

9 Likes

This does EXACTLY what I needed. THANKS @simon!

2 Likes

Sorry to resurrect this very old topic, hope it is OK.

Can we override (in a plugin)?

app/views/layouts/application.html.erb

Like this:

register_asset '../views/layouts/application.html.erb'

I suspect the answer is ā€œNO!ā€ā€¦ if ā€œnoā€ (because ā€˜assetsā€™ are not ā€˜viewsā€™ in Rails, so can we have a future plugin method:

register_view

So we can simply do this in the future (for example):

register_asset 'layouts/application.html.erb'

and override 'layouts/application.html.erb

This seems like a good idea to me, not being a Discourse plugin expert by any stretch of the imagination.

Thanks for your consideration.

Just do it in a theme instead. You can add a standard caching layer in front of whatever API the information is fetched from.

1 Like

We can use embedded ruby code in a theme?

I must be confusedā€¦ thinking theme work was not the place for embedded ruby.

Edit:

Just reviewed the following topic and as suspected there is no reference I can find to adding enbedded ruby in a thene :slight_smile:

Developerā€™s guide to Discourse Themes

Rereadingā€¦

I was forgetting about the cache stanza and was assuming this would hit the server for every request, so thought a client-side fetch would also work.

Instead, something that could work is to have the remote server push the content into the HTML Footer section of a Theme Component.

1 Like