2012-08-13 13 views
10

Ich möchte eine Rails-App erstellen, mit der Benutzer Daten eingeben und dann das Thema der Seite ändern können. Auf diese Weise können ihre Daten je nach gewähltem Thema unterschiedlich gestaltet werden. Wie würde ich das machen?Themes in der Rails-App

  1. Stylesheet ändern?
  2. Zwei verschiedene Ansichten mit verschiedenen Klassen/Elementen?
  3. Dynamisch nur Klassen/IDs/Selektoren ändern?
  4. ?

Dank

+0

Was haben Sie versucht? –

+1

Ich bin neu auf Schienen, also bin ich mir nicht sicher, wo oder wie ich anfangen soll. Ich kann keine Informationen online finden. Wie gehen Wordpress-Leute Themen so gut wechseln? – AdamT

Antwort

12

Der einfachste Weg, eine Website zu Thema Link zu einfach zu einem anderen Sheet. Sie können diese dynamisch mit so etwas wie tun:

# 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 

Dann können Sie ein Paar für Themen manifestiert haben. Zum Beispiel kann Ihr Vermögen Verzeichnis wie folgt aussehen:

  • app/assets/Stylesheets
    • application.css
    • buttons.css
    • theme1/
      • index.css
      • buttons.css
    • t heme2/
      • index.css
      • buttons.css

Dies werden Sie mit reiner CSS Thematisierung gestartet. Irgendwann werden Sie wahrscheinlich auch sie Javascript und HTML-Layouts wollen. Wenn Sie beginnen, die Notwendigkeit, etwas zu finden, wie dies in Ihrem HTML zu tun:

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

dann ist es Zeit, ein robusteres Thematisierung Rahmen zu implementieren:

  • Namespace Ihre HTML-Templates nach Themen (zB app/views /themes/theme1/users/index.html.erb) und rendert die thematische Version anstelle des Standard-Namespace
  • nur die Teiltöne nach Vorlage (z. B. app/views/themes/theme1/users/_form.html.erb) und Fügen Sie eine Hilfsmethode wie render_themed_partial
  • simi hinzu lar zu den oben genannten Ansätze, aber wenn die Themen sehr groß werden, sollten Sie sie in ihre eigenen Edelsteine ​​setzen, wie Motoren Schienen

Hinweis: Das alles für statische Themen ist. Bei dynamischen Themen (z. B. wo sich ein Administrator anmelden und die Stylesheets oder HTML bearbeiten kann), müssen Sie die Themeninformationen in der Datenbank speichern. Abhängig von Ihrer Architektur können Sie möglicherweise eine Reihe von statischen Designs bereitstellen und dann ein anderes Design, das die Stylingdaten dynamisch aus der Datenbank extrahiert.An diesem Punkt entwickeln Sie jedoch ein CMS, so dass es außerhalb des Bereichs dieser Antwort liegt :)

+0

Dies ist eine fantastische Antwort, danke Ben! – kgx

8

Wenn wir verschiedene Stylesheets für jedes Thema erstellen und kleine Änderungen vornehmen, müssen wir dasselbe machen Ändere alle Style-Sheets. Es wird wirklich ein Kopfschmerz sein. Alternativer Weg ist die Verwendung von SASS-Konzepten (Mixins).

Fügen Sie in Ihrem Gemfile

gem 'sass-rails' 

dann

bundle install 

Jetzt müssen Sie Ihre CSS-Stile in einer SCSS-Datei haben. 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; 
    } 
} 

Dann können Sie eine beliebige Anzahl von Themen erstellen. Für das Beispiel 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); 

Jetzt in Ihrem html

<%= stylesheet_link_tag "Theme_Blue" %> 

werden die alle CSS-Klassen angegeben in basic_styles.scss mit blauen Farben.

Sie können beliebig viele Theme-Dateien wie Theme_Blue.scss hinzufügen. Und Änderung

<%= stylesheet_link_tag current_user.theme %> 

Auf diese Weise müssen Sie nur die basic_styles.scss für Umstellungen ändern.

+0

wirklich wirklich gute Antwort danke – jpwynn

+0

Gibt es eine Möglichkeit, zwischen Variablen und Mixins zu wechseln, um zwei verschiedene application.css zu generieren? Beispiel: application-dark.css und application-light.css. –

2

Ich habe es geschafft, die Essenz aus Chamnaps Antwort zu extrahieren (was aus irgendeinem Grund nicht funktioniert hat - vielleicht die Version von 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 

Sie können hier auf es nachlesen:

Sie werden wahrscheinlich auf die Asset-Pfad hinzuzufügen haben und Pre-Compile-Liste (oder auch Verwenden Sie den Edelstein ohne Verwendung von theme Methode).

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" } 

Denken Sie daran, JS und Bilder in Unterverzeichnissen mit dem Namen des Themas zu haben. Sie können auf dem Server getrennt sein, aber für den Browser und den Cache sieht /images/logo.png für beide Themen identisch aus. Also müssen Sie /images/theme1/logo.png und /images/theme2/logo.png verwenden.

Verwandte Themen