Page 115 of 173

Controller stylesheet tag – style dla danego kontrolera

Tworząc arkusze stylów dla projektów często zdarza się, że chcemy dodać styl specyficzny dla danego kontrolera. Przykładowo w kontrolerze wyświetlającym pewien specyficzny rodzaj danych, chcemy mieć inne formatowanie. W przypadku Railsów składać się to będzie na dwie części - najpierw w ApplicationControlerze dodamy sobie metodę która ustawiać nam będzie trzy zmienne dostępne zarówno w kontrolerach jak i widokach:

  • @action_name - nazwa akcji
  • @controller_name - nazwa kontrolera
  • @module_name - nazwa modułu

Przy tym ostatnim (@module_name) należy pamiętać, że możemy mieć kilka "poziomów", np: Admin::Core::Logs, tak więc będziemy to trzymać w tablicy ([Admin, Core, Logs]). Przyjmiemy też konwencję, że nazwy będą przechowywane z małej litery.

  def get_module_and_controller_name
    my_class_name = self.class.name
    @action_name = self.action_name
    if my_class_name.index("::").nil? then
      @module_name = nil
      @controller_name = self.class.to_s.split('Controller').first.underlinize
    else
      @controller_name = self.class.to_s.split("::").last.split('Controller').first.underlinize
      if (my_class_name.split("::").length > 2)
        @module_name = my_class_name.split("::")
        @module_name = @module_name[0, @module_name.length-1].collect{|m| m.underlinize}
      else
        @module_name = Array.new(1, my_class_name.split("::").first.underlinize)
      end
    end
  end

Taką metodę ustawiamy jako before_filter.

Teraz jeszcze tylko helper do widoków:

  def controller_stylesheet_link_tag(module_name, controller)

    if module_name.class.to_s.downcase == 'array'
      module_name = module_name.join('/')
    end
    ex = FileTest.exist?(File.join(Rails.root, 'public',
        'stylesheets', module_name, "#{controller}.css"))

    stylesheet_link_tag "#{module_name}/#{controller}" if ex
  end

oraz wywołanie:

controller_stylesheet_link_tag(@module_name, @controller_name)

Warto wspomnieć, że powyższe rozwiązanie działa na 3.0.7. Dla 3.1.0 będzie troszkę inaczej, ale to pozostawiam wam :)

Wersja dla Padrino jest troszkę mniej "fajna" (aczk. wymaga before_filtre'a):

  def controller_stylesheet_link_tag
    path = request.path.split('/')
    styles = ''
    while path.count > 0
      file = File.join(Padrino.root, 'app', 'stylesheets', 'controllers', path)+'.less'
      if File.exists?(file)
        styles += stylesheet_link_tag 'controllers'+path.join('/')
      end
      path.delete(path.last)
    end
    styles
  end

Padrino Mailer + undefined method “default_encoding”

Pracując nad mailingiem w pewnej aplikacji napisanej w Padrino natrafiłem na "głupi" błąd:

NoMethodError: undefined method `default_encoding' for Mail::Message:Class

Z takim oto stacktracem:

NoMethodError: undefined method `default_encoding' for Mail::Message:Class
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:466:in `render'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/rendering.rb:123:in `render'
	/gems/padrino-mailer-0.9.19/lib/padrino-mailer/ext.rb:228:in `render'
	/home/mencio/app/mailers/signup_mailer.rb:9
	/gems/padrino-mailer-0.9.19/lib/padrino-mailer/base.rb:57:in `instance_exec'
	/gems/padrino-mailer-0.9.19/lib/padrino-mailer/base.rb:57:in `email'
	/gems/padrino-mailer-0.9.19/lib/padrino-mailer/helpers.rb:82:in `call'
	/gems/padrino-mailer-0.9.19/lib/padrino-mailer/helpers.rb:82:in `deliver'
	/gems/padrino-mailer-0.9.19/lib/padrino-mailer/helpers.rb:34:in `deliver'
	/home/mencio/app/controllers/signups.rb:9:in `POST /signup'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/routing.rb:340:in `call'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/routing.rb:340:in `route'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:649:in `instance_eval'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:649:in `route_eval'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/routing.rb:605:in `route!'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/routing.rb:605:in `catch'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/routing.rb:605:in `route!'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/routing.rb:596:in `catch'
	/gems/padrino-core-0.9.19/lib/padrino-core/application/routing.rb:596:in `route!'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:766:in `dispatch!'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:559:in `call!'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:731:in `instance_eval'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:731:in `invoke'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:731:in `catch'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:731:in `invoke'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:559:in `call!'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:544:in `call'
	/gems/rack-flash-0.1.1/lib/rack/flash.rb:148:in `call'
	/gems/padrino-core-0.9.19/lib/padrino-core/reloader.rb:31:in `call'
	/gems/padrino-core-0.9.19/lib/padrino-core/logger.rb:282:in `call'
	/gems/warden-1.0.3/lib/warden/manager.rb:35:in `call'
	/gems/warden-1.0.3/lib/warden/manager.rb:34:in `catch'
	/gems/warden-1.0.3/lib/warden/manager.rb:34:in `call'
	/gems/rack-less-1.5.0/lib/rack/less/base.rb:40:in `call!'
	/gems/rack-less-1.5.0/lib/rack/less/base.rb:24:in `call'
	/gems/rack-1.2.1/lib/rack/showexceptions.rb:24:in `call'
	/gems/rack-1.2.1/lib/rack/methodoverride.rb:24:in `call'
	/gems/rack-1.2.1/lib/rack/session/cookie.rb:37:in `call'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:1173:in `call'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:1199:in `synchronize'
	/gems/sinatra-1.1.3/lib/sinatra/base.rb:1173:in `call'
	/gems/padrino-core-0.9.19/lib/padrino-core/router.rb:71:in `call'
	/gems/padrino-core-0.9.19/lib/padrino-core/router.rb:64:in `each'
	/gems/padrino-core-0.9.19/lib/padrino-core/router.rb:64:in `call'
	/gems/rack-1.2.1/lib/rack/content_length.rb:13:in `call'
	/gems/rack-1.2.1/lib/rack/chunked.rb:15:in `call'
	/gems/thin-1.2.8/lib/thin/connection.rb:84:in `pre_process'
	/gems/thin-1.2.8/lib/thin/connection.rb:82:in `catch'
	/gems/thin-1.2.8/lib/thin/connection.rb:82:in `pre_process'
	/gems/thin-1.2.8/lib/thin/connection.rb:57:in `process'
	/gems/thin-1.2.8/lib/thin/connection.rb:42:in `receive_data'
	/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine'
	/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run'
	/gems/thin-1.2.8/lib/thin/backends/base.rb:61:in `start'
	/gems/thin-1.2.8/lib/thin/server.rb:159:in `start'
	/gems/rack-1.2.1/lib/rack/handler/thin.rb:14:in `run'
	/gems/padrino-core-0.9.19/lib/padrino-core/server.rb:43:in `build'
	/gems/padrino-core-0.9.19/lib/padrino-core/server.rb:14:in `run!'
	/gems/padrino-core-0.9.19/lib/padrino-core/cli/adapter.rb:29:in `start'
	/gems/padrino-core-0.9.19/lib/padrino-core/cli/base.rb:23:in `start'
	/gems/thor-0.14.6/lib/thor/task.rb:22:in `send'
	/gems/thor-0.14.6/lib/thor/task.rb:22:in `run'
	/gems/thor-0.14.6/lib/thor/invocation.rb:118:in `invoke_task'
	/gems/thor-0.14.6/lib/thor.rb:263:in `dispatch'
	/gems/thor-0.14.6/lib/thor/base.rb:389:in `start'
	/gems/padrino-core-0.9.19/bin/padrino:8
	/gems/bin/padrino:19:in `load'
	/gems/bin/padrino:19

Niestety nie znalazłem żadnej wartościowej informacji na temat tego jak to naprawić, tak więc napisałem (brzydki ;) ) workaround który dopisujemy w app/app.rb:

module Mail
  class Message
    def self.default_encoding
    end
  end
end

Przynajmniej na "teraz" rozwiązanie to wydaje się działać.

Copyright © 2025 Closer to Code

Theme by Anders NorenUp ↑