2012-08-13 14 views
10

Chciałbym utworzyć aplikację Rails, która umożliwia użytkownikom wprowadzanie danych, a następnie pozwala im zmieniać motyw strony. W ten sposób ich dane mogą być stylizowane w różny sposób w zależności od wybranego tematu. Jak miałbym to zrobić?Motywy w aplikacji Railsowej

  1. Zmienić arkusz stylów?
  2. Dwa oddzielne widoki z różnymi klasami/elementami?
  3. Dynamicznie po prostu zmienić klasy/identyfikatory/selektory?
  4. ?

Dzięki

+0

czego spróbowałeś? –

+1

Jestem nowy na szynach, więc nie jestem pewien, gdzie i jak zacząć. Nie mogę znaleźć żadnych informacji na ten temat w Internecie. W jaki sposób ludzie z grupy Wordpress tak dobrze zmieniają motywy? – AdamT

Odpowiedz

12

najprostszy sposób na temat witryny jest po prostu odwołuje się do innego arkusza. Możesz zrobić to dynamicznie, używając np .:

# in app/views/layouts/application.html.erb 
<%= stylesheet_link_tag :application %> 
<%= stylesheet_link_tag #{current_theme} %> 

# in app/helpers/application_helper 
def current_theme 
    # You'll have to implement the logic for a user choosing a theme 
    # and how to record that in the model. 
    # Also, come up with a better name for your default theme, like 'twentyeleven' ;) 
    current_user.theme || 'default' 
end 

Następnie możesz mieć kilka manifestów dla tematów. Na przykład, katalog aktywa mogą wyglądać mniej więcej tak:

  • app/aktywa/stylów
    • application.css
    • buttons.css
    • theme1/
      • index.css
      • buttons.css
    • t heme2/
      • index.css
      • buttons.css

To będzie Ci zacząć z czystym CSS kategoryzacji. W pewnym momencie prawdopodobnie będziesz chciał je również obsługiwać w układach javascript i html. Po uruchomieniu znalezienie potrzebę zrobienia czegoś takiego w swoim HTML:

<% if current_theme == 'theme1' %> 
    <li>... 
<% elsif current_theme == 'theme2' %> 
    <b>... 
<% end %> 

następnie nadszedł czas na wdrożenie bardziej solidne ramy Skórki:

  • nazw szablonów html wg tematu (np app/views /themes/theme1/users/index.html.erb) i renderować wersję tematyczną zamiast domyślnej przestrzeni nazw po szablonach (np. app/views/themes/theme1/users/_form.html.erb) i dodać metodę pomocniczą, taką jak render_themed_partial
  • simi lar do powyższych podejść, ale gdy motywy uzyskać bardzo duże, należy rozważyć wprowadzenie ich do swoich klejnotów jak szyny silniki

Uwaga: To wszystko dla motywów statycznych. W przypadku tematów dynamicznych (np. Gdzie administrator może się zalogować i edytować arkusze stylów lub html), będziesz musiał przechowywać informacje o motywach w bazie danych. W zależności od architektury, użytkownik może być w stanie dostarczyć zestaw statycznych motywów, a następnie inny motyw dynamicznie pobierający dane stylów z bazy danych.W tym momencie opracowujesz CMS, więc wykracza to poza zakres tej odpowiedzi :)

+0

To jest fantastyczna odpowiedź dzięki Ben! – kgx

8

Jeśli tworzymy różne arkusze stylów dla każdego tematu i dokonując niewielkich zmian, musimy zrobić to samo zmienić we wszystkich arkuszach stylów. To będzie naprawdę ból głowy. Alternatywnym sposobem jest użycie koncepcji SASS (mixins).

Dodaj w Gemfile

gem 'sass-rails' 

następnie

bundle install 

Teraz trzeba mieć swoje style CSS w jednym pliku SCSS. basic_styles.scss

$font_color: #565656; 
$font-size: 13px; 
$success-color: #088A08; 
$error-color: #B40404; 
@mixin basic_styles($dark_color,$light_color,$bullet_image) 
{ 
.footer 
    { 
    background-color: rgba($dark_color,0.9); 
    color: $light_color; 
    text-align: center; 
    position: fixed; 
    bottom:0; 
    left:0; 
    width: 100%; 
    height: 15px; 
    border-top: 1px solid lighten($dark_color, 9%);  
    padding-left: 10px; 
    padding-right: 10px;  
    font-size: $font_size - 2; 
    } 
    h3,hr,a,input 
    { 
    color: $dark_color; 
    } 
    h3 
    { 
    margin-top: 2px; 
    margin-bottom: 2px; 
    } 
    hr { 
    border-color: lighten($dark_color, 30%) -moz-use-text-color #FFFFFF; 
    border-left: 0 none; 
    border-right: 0 none; 
    border-style: solid none; 
    border-width: 1px 0; 
    } 
    .btn 
    { 
    background-color: $dark_color; 
    border-color: darken($dark_color, 15%);  
    border-radius: 4px 4px 4px 4px; 
    border-style: solid; 
    border-width: 1px; 
    color: #FFFFFF; 
    cursor: pointer; 
    display: inline-block; 
    line-height: 18px; 
    padding: 3px 10px 3px 10px; 
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); 
    vertical-align: middle; 
    } 
    .btn:hover 
    { 
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75); 
    -moz-box-shadow: 0px 0px 2px 1px lighten($dark_color, 10%); 
    -webkit-box-shadow: 0px 0px 2px 1px lighten($dark_color, 10%); 
    box-shadow: 0px 0px 2px 1px lighten($dark_color, 10%); 
    } 
    .success 
    { 
    color: $success-color; 
    } 
    .error 
    { 
    color: $error-color; 
    } 
} 

Następnie można utworzyć dowolną liczbę tematów. Na przykład Theme_Blue.scss

@import "basic_styles"; 
$dark_color: #08c; 
$light_color: #FFFFFF; 
$bullet_image: 'bullet_blue.png'; 
@include basic_styles($dark_color,$light_color,$bullet_image); 

Teraz w HTML

<%= stylesheet_link_tag "Theme_Blue" %> 

użyje wszystkich klas css określone w basic_styles.scss z niebieskimi kolorami.

Możesz dodać dowolną liczbę plików motywów, takich jak Theme_Blue.scss. i przesiąść się

<%= stylesheet_link_tag current_user.theme %> 

W ten sposób, trzeba zmodyfikować tylko basic_styles.scss dla jakichkolwiek modyfikacji.

+0

Naprawdę naprawdę dobra odpowiedź dzięki – jpwynn

+0

Czy istnieje sposób przełączania między zmiennymi i mixins do generowania dwóch różnych application.css? Przykład: application-dark.css i application-light.css. –

2

Udało mi się wydobyć esencję z odpowiedzi Chamnapa (która z jakiegoś powodu nie zadziałała - może wersja Rails?).

class ApplicationController < ActionController::Base 
    layout :layout_selector 

    def layout_selector 
    # puts "*** layout_selector #{session.to_json}" 
    name = ['bootstrap', 'mytheme'][session[:theme].to_i] 
    # puts "*** loading theme #{name}" 
    prepend_view_path "app/themes/#{name}/views" 
    name 
    end 

Można przeczytać o tym tutaj:

Prawdopodobnie będziesz musiał dodać do ścieżki aktywów i listy wstępnie skompilować (lub innego użyj klejnotu bez użycia metody theme).

Dir.glob("#{Rails.root}/app/themes/*/assets/*").each do |dir| 
    config.assets.paths << dir 
    end 

    config.assets.precompile += [ Proc.new { |path, fn| fn =~ /app\/themes/ && !%w(.js .css).include?(File.extname(path)) } ] 
    config.assets.precompile += Dir["app/themes/*"].map { |path| "#{path.split('/').last}/all.js" } 
    config.assets.precompile += Dir["app/themes/*"].map { |path| "#{path.split('/').last}/all.css" } 

Pamiętaj, aby mieć JS i obrazy w podkatalogach z nazwą motywu. Mogą być oddzielne na serwerze, ale do przeglądarki i pamięci podręcznej, /images/logo.png wygląda tak samo dla obu tematów. Więc musisz użyć /images/theme1/logo.png i /images/theme2/logo.png.

Powiązane problemy