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
и ужаснуться фантазии дизайнеров.
Автор: