SpinaCMS / Spina

Spina CMS
http://www.spinacms.com
Other
2.19k stars 405 forks source link

Using the default layout for custom pages #323

Closed TrueSoft closed 6 years ago

TrueSoft commented 6 years ago

If I want to make a custom page (define my controller and views, just like in a regular Rails application) how can I use the default layout from Spina? Let's say I want to make a contact form page: create ContactController, and the views. To have the same layout, I write in the controller the line

layout 'default/application'

But it doesn't work, because there are variables that don't exist in the controller, such as current_account.name from %title, or the navigation menu. If I try to extend my controller from Spina::ApplicationController instead of ApplicationController, I can't because it generates an error. So how do I make custom pages other than the pages made in Spina admin section?

TrueSoft commented 6 years ago

In the controller's action I added this line

    @page = Spina::Page.where(link_url: request.path)

to have a variable for the current page. It shows the page, but in the menu the menuitem of this current page is not highlighted.

Bramjetten commented 6 years ago

If you want to use the default Spina template you'd have to define current_account and @page. You can take a look at the frontend.rb concern to see how we do that in Spina. Regarding the navigation: I usually render the links without any active/current classes and instead use data attributes like this:

application.html.haml

%body{data: {current_page: @page.id, ancestors: @page.ancestors.ids.join('-'), view_template: @page.view_template}}

_navigation.html.haml

%ul
  - (current_spina_user.present? ? Spina::Page.active : Spina::Page.live).roots.sorted.in_menu.each do |page|
    %li{data: {page_id: page.id}}= link_to page.menu_title, page.materialized_path

navigation.coffee

ready = ->
  current_page = $('body').attr('data-current-page')
  ancestors = $('body').attr('data-ancestors')

  # Remove classes
  $("li[data-page-id]").removeClass('current active')

  # Add current and active class to current page
  $("li[data-page-id=#{current_page}]").addClass('current active')

  # Add active class to ancestors
  if ancestors.length
    for ancestor in ancestors.split('-')
      $("li[data-page-id=#{ancestor}]").addClass('active')

$(document).on 'turbolinks:load', ready

This way it's easier to cache large parts of your HTML.