سؤال

I am building a forum and I wish for the admins to be able to edit the css in the admin control panel (like most PHP forums).

I've stored the css in a table called stylesheet.

I need to be able to call this specific row in the stylesheets table in layout/applications so the css shows on ALL pages.

I was wondering if there is a way of using the stylesheet_link_tag to call the location of the css inside the database table?

If not... How exactly do I do it?

I tried using this: Best way to handle dynamic css in a rails app but it did not work.

EDIT: All I am trying to do is instead of calling the assets/stylesheets/layout (<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>) I call the database/stylesheet/id1.code.

I just need to get ID 1 and extract the code from it and display it for every single page as the main CSS.

This is the error I get now:

No route matches {:controller=>"stylesheets", :action=>"show", :id=>nil, :format=>:css} missing required keys: [:id]

Stylesheet Controller

class Admin::StylesheetsController < ApplicationController
    caches_page :show # magic happens here

    def index
        @stylesheets = Stylesheet.all
  end

    def show
        @stylesheet = Stylesheet.find(params[:id])
        respond_to do |format|
          format.html # regular ERB template
          format.css { render :text => @stylesheet.code, :content_type => "text/css" }
        end
    end

  def edit
    @stylesheet = Stylesheet.find(params[:id])
  end

    # When you edit/update the category, update the information
    def update
        @stylesheet = Stylesheet.find(params[:id])
        if @stylesheet.update_attributes(params[:stylesheet].permit!)
            redirect_to edit_stylesheet_path
        else
            render :edit
        end
    end
end

Layout/Application.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>Ruby Ibis | <%= yield(:title) %></title>

    <link rel="stylesheet" href="<%= stylesheet_path(@stylesheet, format: :css) %>" type="text/css" />

  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
   <%= render 'layouts/shim' %>

  </head>
   <body>
    <%= render 'layouts/header' %>
        <div class="container">
      <% flash.each do |key, value| %>
        <div class="alert alert-<%= key %>"><%= value %></div>
      <% end %>
      <%= yield %>
      <%= render 'layouts/footer' %>
      <%= debug(params) if Rails.env.development? %>
    </div>
  </body>
</html> 

Results of test

$ rspec spec/controllers/stylesheets_controller_spec.rb ←[31mF←[0m

Failures:

1) StylesheetsController#show should have the correct css ←[31mFailure/Error:←[0m ←[31mlet(:stylesheet) { Factory(:stylesheet) }←[0m ←[31mNoMethodError←[0m: ←[31mundefined method Factory' for #<RSpec::Core::ExampleGroup::Nested_1 ::Nested_1:0x47793f0>←[0m ←[36m # ./spec/controllers/stylesheets_controller_spec.rb:42:inblock (3 le vels) in '←[0m ←[36m # ./spec/controllers/stylesheets_controller_spec.rb:44:in `block (3 le vels) in '←[0m

Finished in 0.02 seconds ←[31m1 example, 1 failure←[0m

Failed examples:

←[31mrspec ./spec/controllers/stylesheets_controller_spec.rb:43←[0m ←[36m# Style sheetsController#show should have the correct css←[0m

Randomized with seed 18359

هل كانت مفيدة؟

المحلول

Don't worry about caching right now. Just see if it renders at all:

class Admin::StylesheetsController < ApplicationController

  respond_to :css

  def show
    @stylesheet = Stylesheet.find(params[:id])
    render text: @stylesheet.code, content_type: "text/css"
  end

end

Write a test for GET /stylesheets/:id.css. And in the markup:

<link rel="stylesheet" href="<%= stylesheet_path(@stylesheet, format: :css) %>" type="text/css" />

It seems like you're confusing the stylesheet for the forum. The stylesheet is a resource, and it is requested implicitly with the <link> tag. You put the link to the stylesheet as part of the forum html page.

Your stylesheets/:id.css path returns the css only, no markup. A test for this assuming the field in your stylesheet model is called :code would be:

describe '#show' do
  let(:stylesheet) { Factory(:stylesheet) }
  it 'should have the correct css' do
    get :show, id: stylesheet.id
    expect(response.body).to eq(stylesheet.code)
  end  
end

Seems like you're confused about the way Rails works with requests. I'll walk you through the timeline:

  1. Browser requests the forum page. This is handled by ForumsController#show or something like that.

  2. In a before filter or otherwise, you need to determine the id for the stylesheet somehow, for the <link> tag.

  3. Your layout application is wrapped around the page for the action, and the request ends.

  4. Browser notices it needs to request stylesheets / javascripts, one of which is your custom stylesheet.

  5. Your StylesheetsController#show is called, and the stylesheet is rendered back. This and all the other assets requests are completed.

  6. Now the user with the browser can see the custom css.

So you see, the @stylesheet is not set when the page is rendered, and istance variables are set per controller per request. Not globally. Setting @stylesheet in StylesheetsController#show only sets it for the route GET /stylesheets/:id.css.

You might want to consider using sublayouts - http://www.ajostrow.me/thoughts/sublayouts-with-rails-revised

نصائح أخرى

Due to my stylesheets being in the admin namespace, the code we have been trying to used failed. I figured out a way around it, even if it is probably not a good method of doing things.

I ended up linking directly to the stylesheet. It works perfectly, even if it isn't a conventional or probably accepted way. I can look for a better method later, I just needed to finish my project to graduate...

 <link href="/admin/stylesheets/1/" media="screen" rel="stylesheet" type="text/css" />
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top