2012-12-13 7 views
8

Buduję witrynę w Railsach 3.2. Minęły 3 lata, odkąd dotknąłem Railsów lub Ruby, więc jestem zardzewiały na obu, a ostatnim razem, gdy używałem szyn, był Rails 2.3. Nie trzeba dodawać, proszę wybaczyć wszystkie "proste" pytania poniżej.Dynamiczne CSS w potoku Railsowym, kompilacja w locie

Oto specyfikacje

  • Wielu Tennant CMS/Sklep Site
  • Każdy "Store" (aka subdomeny) może mieć swój wygląd, styl itp. dzięki dostosowaniom CSS
    • Dostosowania można wykonywać w interfejsie użytkownika w aplikacji, umożliwiając użytkownikowi zmianę podstawowych zmiennych funkcji Bootstrap (tj. @textColor, @bodyBackground itp)
  • Używam less-rails-bootstrap gem do Twitter Bootstrap przeglądowej/Feel itp

Oto wyzwania

  1. muszę być potrafi dynamicznie wyprowadzać zmienne dla CSS do pliku, który miesza się z Bootstrap, więc zmienne są pobierane w celu utworzenia ostatecznego CSS
  2. Gdy użytkownik zmienia zmienną dla CS S, istniejący styl jest zasadniczo unieważniany. Potrzebuję pełnego CSS zrekompilowanego i zapisanego na dysku, strumieniu pamięci lub w innym miejscu, w którym mogę dostać się do niego (pamiętaj, że to jest użycie less)
  3. Potrzebuję różnych CSS do wypluwania na poddomeny. Wszelkie sugestie, jak się do tego podejść?

bardziej komplikuje sprawę ...

... biorąc pod uwagę, że w istocie będzie musiał znaleźć jakiś sposób, aby skompilować CSS w locie, co oznacza, że ​​muszę to perełki ja zazwyczaj nie będzie w środowisko produkcyjne. Wydajność będzie bardzo ważna. Czy istnieje sposób, aby to odizolować? Gdy CSS zostanie unieważniony i zregenerowany, mogę pobrać zawartość i albo zapisać ją na dysku, albo przechowywać w niektórych plikach memcached/redis/etc. wystąpienie dla wydajności.

Wszelkie komentarze, nawet jeśli tylko wskaże mi w ogólnym kierunku będą mile widziane.

Dzięki!

+0

można dodać reguły takie jak '! Important' w dynamicznie dodawanym skrypcie dla tych rzeczy, które się zmieniają. Wtedy nie musiałbyś robić całej tej rekompilacji – AJcodez

+0

Cóż, celem części tutaj jest możliwość wykorzystania zalet zmiennych w CSS. Te zmienne zostaną ponownie wykorzystane w plikach źródłowych Bootstrap. Przykładem tego jest zmienna '@ purple'. Pozwala to użytkownikowi określić, jaki kolor (odcień/nasycenie, itp.) "Purpurowego", który chcemy użyć. Jest to następnie używane w Bootstrap w wielu miejscach. Regularne CSS nie będzie działać tutaj niestety. –

+0

Ryan, szukam takiej samej odpowiedzi jak ty, ponieważ chcę wykorzystać zmienne Bootstrap. Oczywiście, że pracuje nad rozwojem, ponieważ rzeczy są kompilowane w locie. Robię coś podobnego, ponieważ oszczędzam mniej plików klientów w lib/assets/stylesheets/clients. Następnie w moim pliku application.html.erb sprawdzam, czy strona była dostępna z subdomeną, a następnie podałem odpowiedni plik (nazywam pliki .less po poddomenie). Czy kiedykolwiek to zrozumiałeś? Jeśli nie, dodam nagrodę w postaci własnych punktów na twoje pytanie, więc go nie podrabiam. – AKWF

Odpowiedz

3

Oto rozwiązanie I w końcu wylądował na:

  • skończyło się przełączenie na bootstrap-sass zamiast https://github.com/thomas-mcdonald/bootstrap-sass
  • dokonała następujących zmian do mojego pliku application.rb aby upewnić się, że grupa :asset jest zawsze włączone mimo środowisko:

    if defined?(Bundler) 
        # If you precompile assets before deploying to production, use this line 
        # Bundler.require(*Rails.groups(:assets => %w(development test))) 
        # If you want your assets lazily compiled in production, use this line 
        Bundler.require(:default, :assets, Rails.env) 
    end 
    
  • Użyte pojęcia dostarczone przez Man uel Meure (Thank you Manuel!) firmy Kraut Computing pod numerem http://www.krautcomputing.com/blog/2012/03/27/how-to-compile-custom-sass-stylesheets-dynamically-during-runtime/.

    • Wprowadziłem kilka poprawek dopasowanych do moich własnych potrzeb, ale podstawowe pojęcia zilustrowane przez Manuela były podstawą mojego procesu kompilacji.
  • W moim modelu (pozwala wywołać "Site") Mam fragment kodu, który wygląda tak:

    # .../app/models/site.rb 
    ... 
    
    BASE_STYLE = " 
        @import \"compass/css3\"; 
    
        <ADDITIONAL_STYLES> 
    
        @import \"bootstrap\"; 
        @import \"bootstrap-responsive\"; 
    ".freeze 
    
    # Provides the SASS/CSS content that would 
    # be included into your base SASS content before compilation 
    def sass_content 
        " 
        $bodyBackground: #{self.body_background}; 
        $textColor: #{self.text_color}; 
        " + self.css # Any additional CSS/SASS you would want to add 
    end 
    
    def compile_css(test_only = false, force_recompile = false) 
    
        # SassCompiler is a modification of the information made available at the Kraut Computing link 
        compiler = SassCompiler.new("#{self.id}/site.css", {:syntax => :scss, :output_dir => Rails.root.join('app', 'assets', 'sites')}) 
    
        # Bail if we're already compiled and we're not forcing recompile 
        return if compiler.compiled? && !force_recompile && !test_only 
    
        # The block here yields the content that will be rendered 
        compiler.compile(test_only) { 
        # take our base styles, slap in there some vars that we make available to be customized by the user 
        # and then finally add in our css/scss that the user updated... concat those and use it as 
        # our raw sass to compile 
        BASE_STYLE.gsub(/<ADDITIONAL_STYLES>/, self.sass_content) 
        } 
    end 
    

Mam nadzieję, że to pomaga. Wiem, że jest to odchylenie od pierwotnego stanowiska, ale jego odchylenie, ponieważ wydawało się, że jest to najbardziej osiągalne rozwiązanie problemu.

Jeśli nie odpowiedziałem na konkretne pytanie, które masz, możesz je skomentować, abym mógł rozwinąć w miarę możliwości.

Dzięki!

+0

Jestem ciekawy, czy znałeś sposób, w jaki mogę wdrożyć to w Heroku, ponieważ twierdzą oni, że wszystkie wdrożenia muszą być 'initialize_on_precompile = false' – Trip

+0

@Trip, chciałbym mieć dla ciebie dobrą odpowiedź na ten temat. Trochę to trwało, odkąd byłem na ziemi Railsów i nie pamiętam, czy natrafiłem na ten kawałek - przepraszam. Jeśli masz ochotę rozwinąć tę opcję, możesz edytować moją odpowiedź. –

+1

Ah, więc znalazłem odpowiedź i można ją wdrożyć z ustawionym na true, po prostu trzeba użyć domyślnego buildpack Heroku. Który powinien być domyślnie uruchomiony. Mój błąd pojawił się dwa lata temu, ta sama aplikacja miała niestandardową konstrukcję, którą kilku programistów majstrowało - i nie udało mi się jej zaktualizować. – Trip