Search code examples
ruby-on-railslayoutruby-on-rails-7rails-enginesactionviewhelper

MyEngine::FrontendController#index is missing a template for request formats: text/html render different layout from controller


Layouts are present in app/apps/themes/default_theme/views/layouts I have a frontend controller that renders layouts of different themes based on params. For now , lets assume it renders default_theme. But how do you set a default theme?

module MyEngine
  class FrontendController < ApplicationController
    before_action :set_theme_view_path
    layout :determine_layout

    def index
    end

    private
    
    def set_theme_view_path
      theme =  'default_theme'
      # Add both the layouts and views paths for the theme
      theme_layout_path = MyEngine::Engine.root.join('app', 'apps', 'themes', theme, 'views', 'layouts')
      theme_view_path = MyEngine::Engine.root.join('app', 'apps', 'themes', theme, 'views')
      prepend_view_path(theme_layout_path)
      prepend_view_path(theme_view_path)
    end

    def determine_layout
      theme =  'default_theme'
      "layouts/application"
    end
  end
end

How do you dynamically render a layout at runtime? In my case , just a particular layout from another folder instead of conventional layouts inside views folder?


Solution

  • You don't need to prepend theme_layout_path. Layout name should be relative to views/layouts:

    before_action :set_theme_view_path
    layout :determine_layout
    
    private
    
    def set_theme_view_path
      theme = "default_theme"
      prepend_view_path MyEngine::Engine.root.join("app/apps/themes/#{theme}/views")
    end
    
    def determine_layout
      # "app/apps/themes/default_theme/views/layouts/default_theme_layout.html.erb"
      "default_theme_layout"
    end