2012-12-13 12 views
8

Sto costruendo un sito in Rails 3.2. Sono passati 3 anni da quando ho toccato Rails o Ruby, quindi sono arrugginito su entrambi, inoltre l'ultima volta che ho usato le rotaie è stato Rails 2.3. Inutile dire che scusate qualsiasi "semplice" domanda qui sotto.CSS dinamico nella pipeline di asset Rails, compilare al volo

Ecco le specifiche

  • Multi Tennant CMS/negozio
  • Ogni "Store" (aka sottodominio) può avere il proprio aspetto, tatto, ecc. tramite le personalizzazioni CSS
    • Le personalizzazioni possono essere eseguite in un'interfaccia utente all'interno dell'applicazione consentendo all'utente di modificare le variabili di base di Bootstrap (ad es. @textColor, @bodyBackground, ecc)
  • Sto utilizzando la less-rails-bootstrap gemma al Twitter Bootstrap sguardo/tatto, ecc

Qui ci sono le sfide

  1. ho bisogno di essere in grado di generare dinamicamente le variabili per il CSS in un file che viene mixato in Bootstrap in modo che le variabili vengano raccolte per creare il CSS finale
  2. Quando un utente modifica una variabile per CS S, lo stile esistente è sostanzialmente invalidato. Ho bisogno del CSS completo ricompilato e scritto su disco, flusso di memoria, o in qualche altro luogo dove posso metterlo tra le mani (ricordate che sta usando less)
  3. Ho bisogno di diversi CSS da sputare per sottodominio. Qualche suggerimento su come affrontarlo?

A complicare ulteriormente la questione ...

... visto che io essenzialmente dovrò trovare un modo per compilare il CSS al volo, che significa che devo includere GEMS io in genere non sarebbe in un ambiente di produzione. Le prestazioni saranno molto importanti. C'è un modo per isolare questo? Una volta che il CSS è stato invalidato e rigenerato, potrei prendere il contenuto e scriverlo su disco o memorizzare in qualche memcached/redis/ecc. istanza per le prestazioni.

Qualsiasi commento, anche se solo per indicarmi in una direzione generale, sarebbe apprezzato.

Grazie!

+0

potresti aggiungere regole come '! Important' in uno script aggiunto dinamicamente per quelle cose che cambiano. Quindi non dovresti fare tutto questo ricompilando – AJcodez

+0

Bene parte dell'obiettivo qui è di essere in grado di sfruttare i vantaggi delle variabili in CSS. Tali variabili vengono riutilizzate nei file di origine Bootstrap. Un esempio di ciò è la variabile '@ purple'. Ciò consente all'utente di specificare il colore (tonalità/saturazione, ecc.) Di "viola" che vogliamo utilizzare. Questo viene quindi utilizzato all'interno di Bootstrap in più posizioni. Il CSS normale non funzionerà qui purtroppo. –

+0

Ryan, sto cercando la stessa risposta, visto che voglio sfruttare le variabili Bootstrap. Ovviamente funziona nello sviluppo poiché le cose sono compilate al volo. Sto facendo qualcosa di simile in quanto sto salvando meno file dei miei clienti in lib/assets/stylesheets/customers. Poi nel mio file application.html.erb sto verificando se il sito è stato acceduto con un sottodominio, quindi servendo il file appropriato (sto nominando i file .less dopo il sottodominio). Hai mai capito? In caso contrario, aggiungerò una generosità dei miei punti sulla tua domanda, quindi non la ingannare. – AKWF

risposta

3

Ecco la soluzione che ho finalmente atterrato su:

  • ho finito di passare a bootstrap-sass invece https://github.com/thomas-mcdonald/bootstrap-sass
  • apportate le seguenti modifiche al mio file application.rb per assicurare che il gruppo :asset è sempre incluso, nonostante l'ambiente:

    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 
    
  • Usato i concetti forniti da uomo uu Meure (Grazie a Manuel!) di Kraut Computing trovato a http://www.krautcomputing.com/blog/2012/03/27/how-to-compile-custom-sass-stylesheets-dynamically-during-runtime/.

    • Ho apportato alcune modifiche per soddisfare le mie esigenze, ma i concetti fondamentali illustrati da Manuel sono stati la base del mio processo di compilazione.
  • Nel mio modello (consente di chiamare "Site"), ho un frammento di codice che assomiglia a questo:

    # .../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 
    

Spero che questo aiuta. So che è una deviazione dal post originale, ma è stata deviata perché questa sembrava essere la soluzione più possibile per il problema.

Se non ho risposto a una domanda specifica che avete, sentitevi liberi di commentare in modo da poter espandere, ove possibile.

Grazie!

+0

Sono curioso di sapere se per me è possibile distribuirlo a Heroku poiché insistono sul fatto che tutte le distribuzioni devono essere 'initialize_on_precompile = false' – Trip

+0

@Trip, vorrei avere una buona risposta per te su quello. È stato un po 'da quando sono stato in terra Rails e non riesco a ricordare se mi sono imbattuto in questo pezzo - Scusa. se ti senti in grado di espandere questo, sentiti libero di modificare la mia risposta. –

+1

Ah, quindi ho trovato una risposta ed è possibile distribuire con esso impostato su true, è sufficiente utilizzare il buildpack predefinito di Heroku. Che tecnicamente dovrebbe essere in esecuzione per impostazione predefinita. Il mio errore è stato due anni fa, la stessa app aveva una custom costruita su cui alcuni sviluppatori stavano lavorando - e non ero riuscito ad aggiornarlo. – Trip

Problemi correlati