Используем Twitter Bootstrap в RefineryCMS

в 6:30, , рубрики: cms, refinerycms, ruby, ruby on rails, Twitter Bootstrap

Используем Twitter Bootstrap в RefineryCMS RefineryCMS — это еще одна RoR CMS. Поддерживает Rails3.2, удобна. Я не стану тут заниматься пересказом пресс-релизов, если интересно — на сайте можно поиграться в демо. Поскольку родилась она не вчера, из коробки поддерживать Twitter Bootstrap не умеет. Есть костыль refinerycms-bootstrap, но меня он не впечатлил. Поэтому я расскажу, как быстро прикрутить bootstrap самому. NB! Эта заметка не предполагает, что вы уже видели RefineryCMS, но и не рассказывает именно о ней: рассказ пойдет строго о прикручивании TB.

Установка проста, как диетическое яйцо:

$ gem install refinerycms
$ cd ~/Projects && refinerycms MyRefineryApp
$ cd MyRefineryApp && rails server

Теперь по адресу http://localhost:3000 доступна админка. При первом запуске создаете пользователя и — вперед.

Bootstrap it!

Структура каталогов ничем не отличается от обычного приложения. Нам потребуется спрайт с картинками для основных действий админки: logout и view site (его укладываем в /app/assets/images/admin_sprite.png). Начнем мы с того, что скачаем несколько разных тем bootstrap и разложим их в /vendor/assets/… под именами (первое подчеркивание и расширение .scss важны!) _ИМЯ_ТЕМЫ.css.scss. Refinery использует Sass, поэтому потом мы будем просто импортировать наш bootstrap-файл:

@import 'cosmo';

Я тренировался на темах с Bootswatch (и оригинальной, разумеется):

$ ls vendor/assets/stylesheets
_amelia.css.scss  _bootstrap.css.scss  _cerulean.css.scss  _cosmo.css.scss  _spacelab.css.scss

Подготовка

Refinery по умолчанию использует свои встроенные шаблоны, которые можно перезаписывать и править у себя (поиск по директориям приложения приоритетнее). Команда «клонирования» шаблона к себе:

rake refinery:override view=ИМЯ_ШАБЛОНА

Нам потребуются для правки следующие шаблоны:

rake refinery:override view=layouts/application
rake refinery:override view=views/_header
rake refinery:override view=views/_menu
rake refinery:override view=views/_site_bar

Вот они:

$ ls app/views/{refinery,layouts}
app/views/layouts:
application.html.erb

app/views/refinery:
_header.html.erb  _menu.html.erb  _site_bar.html.erb

Осталось только подружить стили с кодом. В файл app/assets/stylesheets/application.css.scss пишем что-то вот такое:

//@import 'cerulean';
//@import 'spacelab';
@import 'amelia';
//@import 'cosmo';

// This is default size of refinery logo. Arghhh
$sb_ref_logo: 29px;
$sb_lineheight: 18px;
$sb_height: $sb_lineheight * 4;

#header { height: $sb_height; }

// take care of menu item hover-selection
.navbar .nav > li > a { padding: $sb_lineheight; }

///////////////////////////////////////////////////////////////////////////////
//  Refinery admin menu: images taken from app/assets/images/admin_sprite.png
///////////////////////////////////////////////////////////////////////////////
ul#main-menu-right > li > a {
  &:hover { background-color: transparent; }
  &#site_bar_refinery_cms_logo {
    line-height: $sb_ref_logo; height: $sb_ref_logo; 
    margin-top: $sb_ref_logo / 3; padding: 0; overflow: hidden; 
    img { line-height: $sb_ref_logo; }
    &:hover > img { margin-top: -$sb_ref_logo - 2px; } 
  }
}

// control buttons
@mixin admin_sprite($num,$size:24px) {
  line-height: $size; height: $size; overflow: hidden; padding: 0; 
  margin: $sb_ref_logo / 2; margin-left: $sb_ref_logo / 1.5; margin-right: 0;
  img { margin-top: -2*$size*$num - 24px; } 
  &:hover > img { margin-top: -2*$size*$num; }  
}
a#adminsite { @include admin_sprite (0); }
a#logout { @include admin_sprite (1); }

Меняем toolbar

Мы будем менять верхний элемент управления только для «просмотра» сайта. В админке он нам без надобности. В основном шаблоне (/app/views/layouts/application.html.erb) добавляем идентификаторы:

<!DOCTYPE html>
<%= render '/refinery/html_tag' %>
  <% site_bar = render('/refinery/site_bar', :head => true) -%>
  <%= render '/refinery/head' %>
  <body>
    <%= site_bar -%>
    <%= render '/refinery/ie6check' if request.env['HTTP_USER_AGENT'] =~ /MSIE/ -%>
    <div id="page_container" class="container">
      <header id="header">
        <%= render '/refinery/header' -%>
      </header>
      <section id="page">
        <%= yield %>
      </section>
      <footer id="footer">
        <%= render '/refinery/footer' -%>
      </footer>
    </div>
    <%= render '/refinery/javascripts' %>
  </body>
</html>

В хедере /app/views/refinery/_header.html.erb — разметку:

<div class="navbar navbar-fixed-top">
   <div class="navbar-inner">
     <div class="container">
       <a data-target=".nav-collapse" data-toggle="collapse" class="btn btn-navbar">
         <span class="icon-bar"></span>
         <span class="icon-bar"></span>
         <span class="icon-bar"></span>
       </a>
      <%= link_to Refinery::Core.site_name, refinery.root_path, :class => "brand" %>

<%= render(:partial => "/refinery/menu", :locals => {
             :dom_id => 'menu',
             :css => 'menu'
           }) %>

    </div>
  </div>
</div>

В меню /app/views/refinery/_menu.html.erb — разметку и самое главное — рендеринг админ-меню refinery (четвертая с конца строка):

<%
  # Collect the root items.
  # ::Refinery::Menu is smart enough to remember all of the items in the original collection.
  if (roots = local_assigns[:roots] || (collection ||= refinery_menu_pages).roots).present?
    dom_id ||= 'menu'
    css = [(css || 'menu clearfix')].flatten.join(' ')
    hide_children = Refinery::Core.menu_hide_children if hide_children.nil?
-%>
<div id="main-menu" class="nav-collapse">
  <nav id='<%= dom_id %>' class='<%= css %>'>
    <ul id="main-menu-left" class="nav">
      <%= render :partial => '/refinery/menu_branch', :collection => roots,
                 :locals => {
                   :hide_children => hide_children,
                   :sibling_count => (roots.length - 1),
                   :menu_levels => local_assigns[:menu_levels],
                   :apply_css => true #if you don't care about class='first' class='last' or class='selected' set apply_css to false for speed.
                 } -%>
    </ul>
    <%= render :partial => '/refinery/bs_site_bar' %>
  </nav>
</div>
<% end -%>

Пора создать шаблон админ-меню (vi app/views/refinery/_bs_site_bar.html.erb):

<% if refinery_user? && "#{controller_name}##{action_name}" != 'pages#preview' %>
  <ul id="main-menu-right" class="nav pull-right">
    <li><%= link_to image_tag("#{"http://refinerycms.com/images/" unless local_request?}refinery/logo-site-bar.png",:alt => "Refinery (tm) Content Manager"),
            'http://refinerycms.com', :target => '_blank', :id => 'site_bar_refinery_cms_logo' %></li>
    <li><%= #site_bar_switch_link 
        link_to image_tag("admin_sprite.png", :alt => "Administer site"),
                (if session.keys.map(&:to_sym).include?(:refinery_return_to) and session[:refinery_return_to].present?
                  session[:refinery_return_to]
                else
                  refinery.admin_root_path
                 end rescue refinery.admin_root_path), :id => 'adminsite'
    -%></li>
    <li><%= link_to image_tag("admin_sprite.png", :alt => "Log out"),
            refinery.destroy_refinery_user_session_path, :id => 'logout' %></li>
  </ul>
<% end %>

Ну и убрать лишнее из app/views/refinery/_site_bar.html.erb:

<% if refinery_user? && admin? && "#{controller_name}##{action_name}" != 'pages#preview' %>
  <div id='site_bar'>
    <div id='site_bar_content' class='clearfix'>
      <div id='editor_switch'>
        <%= site_bar_switch_link -%>
      </div>
      <%= link_to image_tag("#{"http://refinerycms.com/images/" unless local_request?}refinery/logo-site-bar.png", :alt => "Refinery (tm) Content Manager"),
                  'http://refinerycms.com',
                  :target => '_blank',
                  :id => 'site_bar_refinery_cms_logo' %>

      <div id='site_bar_branding'>
        <span id='site_bar_company_name'>
          <%= Refinery::Core.site_name %>
        </span>

        <%= link_to t('.log_out', site_bar_translate_locale_args),
                    refinery.destroy_refinery_user_session_path, :id => 'logout' %>
      </div>
    </div>
  </div>
<% end %>

Вчерне готово. Можно попереключать темы в application.css.scss и ужаснуться фантазии дизайнеров.

Автор:

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js