Rails Variables inside the CSS file - css

I have CSS file that needs to be embedded by the user. Now for the user to customize the CSS file as he/she wishes (change the colors and font-size mainly) I have to store that information in database file, append that information to specfic CSS file and then enable that user to embed it.
I would get the id of the User that I wish to change. So color codes stored are basically extracted from,
User.find(params[:id]).main_color
# This would return => #fffff
This what my embed code looks like right now,
<link href="link.com/initial.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" data-user="18" src="link.com/some_file.js" />
Here data-user is the id of the user who is modifying the CSS file. (The IFrame is being embedded using the javascript file)
How should I modify my embed code and fetch the custom variables from my database in order to make the CSS cstomizable as the user wants?
Thanks in advance.
P.S I have thought of rewriting the CSS in the view(.html.erb file) and using !important there along with proper color codes selected by the user but that approach is not exactly very efficient.

I think the best way is to keep your script file at the server side, So you can easily modify your script depending on user database options
for example:
place a new route in routs.rb
post '/users/modify_style', :to => 'users#modify_style', :as => modify_style
then allow the route to respond to user by JavaScript file, for example if the user needs to change the main color of HTML template using a button or a link; so the form button in template may look like:
<%= button_to 'apply style', modify_style_path, :data => {:user_id => current_user.id}, :remote => true %>
or
<%= link_to 'apply style', modify_style_path(:user_id => current_user.id), :method => :post, :remote => true %>
so remote: true option will allow sending data to server through AJAX without refreshing the page.
at users_controller.rb
def modify_style
user = User.find(params[:user_id])
#main_color = user.main_color
respond_to do |format|
format.js { render 'some_file.js.erb' }
end
end
and in your js file:
$('#some_element_id_to_change_color_for').css('color', '<%= #main_color %>')
or you can add modify_style action code directly to the original action which load your page to appy user style once the page is loaded.

I would suggest you to directly use it in the erb file something like
my.html.erb
<html>
<!-- my html -- >
</html>
<style>
<%= my_css.html_safe %>
</style>

Related

Handlebars: inherited/implicit parameters

Is there an easy way how to pass a "configuration" parameter to all embedded partials in handlebars?
In my case, I would like to set language by the page layout partial and would like all the embedded partials to have access to it, something like this:
#layout-en.hbs:
SOMEHOW SETTING LANG PARAMETER TO "EN"
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{title}}</title>
</head>
<body>
<p>Top of all English pages</p>
{{{content}}}
<p>Footer of all English pages</p>
</body>
</html>
#layout-fr.hbs - analogous
some-page-en.hbs:
{{#> #layout_en title="Title in English"}}
some content in English
{{#> demo}}
some more content in English
{{/#layout_en}}
some-page-fr.hbs:
{{#> #layout_fr title="Title in French"}}
some content in French
{{#> demo}}
some more content in French
{{/#layout_fr}}
Is it possible for demo to return a button with a different text when included on a page using layout_en and different when on a page using layout_fr?
Or should this be done completely differently?
It's possible to set a variable that is accessible to all views and partials that are rendered in the response. I am doubtful that such a variable could be set from a partial and, even if it could, I would recommend against it because I think it would make the application more difficult to troubleshoot if global variables were being set in views.
Instead, I think a better approach would be to set such a variable in your controller logic.
You have not mentioned what Node web server framework you are using, but I am going to assume you are using express with the express-handlebars package.
The express API provides a locals object on the response (res), to which variables can be attached and made available to all rendered templates.
A simple example of setting a global lang variable within our express handlers looks like:
app.get("/en", (req, res) => {
res.locals.lang = "en";
res.render("some-page-en");
});
app.get("/fr", (req, res) => {
res.locals.lang = "fr";
res.render("some-page-fr");
});
This will allow us to use {{lang}} from within any rendered view/layout/partial and the corresponding value will be rendered.
The problem with this approach is that it does allow for simple conditions within our template of the sort lang === "fr" ? "French content" : "English content". This is because Handlebars does not ship with a way to perform such a conditional check. A custom helper could help, however, if your application will only support the two languages - English and French - then we could replace our lang string variable with a boolean one - ex., isFrench:
app.get("/en", (req, res) => {
res.locals.isFrench = false;
res.render("some-page-en");
});
app.get("/fr", (req, res) => {
res.locals.isFrench = true;
res.render("some-page-fr");
});
As a boolean, this variable can be used with a Handlebars #if helper. The demo partial could then look something like:
<button type="button">
{{#if isFrench}}
Cliquez ici
{{else}}
Click here
{{/if}}
</button>
Additionally, I would recommend using a similar pattern within a single layout file instead of potentially having an English and a French layout with mostly duplicated HTML.
Additional note:
{{#> demo}} on its own is not valid Handlebars syntax. The #> is for rendering Partial Blocks and those must have an accompanying closing tag: {{/demo}}. A regular (non-Block) partial would be rendered with {{> demo}}.

Middleman and Sinatra Contact Form rendering template

I'm trying to create a middleman site with a contact form using sinatra and pony gem
I'm having problems getting middleman and sinatra to play nicely together
THE ISSUE:
"
My Contact From is not rendering my header and footer and also does not like it when I try to include view helpers like = link_to tags When I try that I get this error
undefined method `link_to' for
Its also not picking up my stylesheets
"
Heres my Mailer.rb get method
class MailForms < Sinatra::Base
set :views, Proc.new { File.join(root)}
get '/' do
haml :contact, :layout => :'/contact'
end
end
and it lives in source/mailer.rb
when I go to website.com/contact.hml
I get the form but it has no header or footer all my other pages have them and is working
I can't use = link_to tags or image tags i get an undefined method error
Its also not picking up my styles
heres my config.rb
require 'source/mailer'
map('/contact.html') do
run MailForms
end
set :css_dir, 'stylesheets'
set :js_dir, 'javascripts'
set :images_dir, 'images'
set :relative_links, true
configure :build do
activate :relative_assets
end
heres my layout.haml with my stylesheet link
!!!
%html
%head
%meta{charset: "utf-8"}
%meta{content: "IE=edge,chrome=1", "http-equiv" => "X-UA-Compatible"}
%title= current_page.data.title || "Auto Tint Specalist"
%link{href: "//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css", rel: "stylesheet"}
= stylesheet_link_tag "normalize", "all"
%script{src: "//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"}
= javascript_include_tag "all"
%body{class: page_classes}
= partial 'layouts/header'
= yield
= partial 'layouts/footer'
all my styles are in all.scss in the stylesheets folder

devise password reset view

I'm trying to style my devise forms. So far I have done so by adding classes and IDs into the forms found in app/views/devise. However, I haven't been able to find where the form for /users/password/new (new_password_path) exists. It renders a button with "send me reset password instructions" on it; I did a search through my app and can't find where that comes from... Would that be in the Devise gem itself?
TL/DR: How can I style the forgot password view?
Thanks in advance.
Similar to the Registrations and Sessions behaviour Devise provides a default Passwords view and controller that isn't automatically generated in your own application folder structure.
To override the Forgotten Password view create new.html.erb in a views/devise/passwords folder. You can see the default views on Devise's GitHub: https://github.com/plataformatec/devise/tree/master/app/views/devise/passwords
To override the PasswordsController create passwords_controller.rb in your app/controllers folder that inherits from the Devise controller and override whatever you need. For example to supply a non-default layout.
class PasswordsController < Devise::PasswordsController
include ApplicationHelper
layout "minimal"
end
You then need to change your routes.rb file to specify the custom controller should be used by devise:
devise_for :users, :controllers => {:registrations => "registrations", :sessions => "sessions", :passwords => "passwords"}
In you development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => your_port_num,
:domain => 'site.com',
:user_name => 'admin#site.com',
:enable_starttls_auto => true,
:password => 'none' }
Your path with be redirected in mail.

Admin changes themes

I am making a web-app which admin can change the themes. So I have 2 css files, style.css and style2.css.
In my application_helper I have
def set_themes(themes)
#themes = themes
end
in application_controller I have
helper_method :themes
And I put this on application.html.erb
<%= stylesheet_link_tag set_themes %>
And in Admin index.html I write a select_tag, like this :
Choose themes: <%= select_tag(:themes, options_for_select({"Black" => "compiled/styles", "Green" => "compiled/styles2"}), :onchange => 'set_themes(this.options[this.selectedIndex].value)') %>
And I got ArgumentError. I know that the problem is how I used onchange, because when I change manually from application_helper, it works. But I have no idea how to call methode from application_helper by clicking select_tag.
Can anyone help me? Thank youu :-)
Your definition of the set_themes method requires that the helper method be passed exactly one argument, but in this line:
<%= stylesheet_link_tag set_themes %>
you appear to be invoking it without any arguments (i.e., it is equivalent to calling set_themes()). You should change the call to set_themes in the line above to something else which has the proper arguments, or a direct instance variable, etc.

javascript contents are not getting loaded,if i create a tab/contentPane dymaically with .xhtml as input

I am creating a dynamic tab/contentPane as below in home.xhtml file and i am trying to call a function display which is present in order.xhtml,its not getting called. what ever java script is there in order.xhtml is not getting loaded.
In home.xhtml
if(dijit.byId('ordersummary')!=null){
dijit.byId('ordersummary').destroy();
}
newTab= new dijit.layout.ContentPane({
id : 'ordersummary',
title : 'Order Summary',
href : 'order.xhtml',
closable : true
});
dijit.byId('tabContainer').addChild(newTab);
dijit.byId('tabContainer').selectChild(dijit.byId("ordersummary"));
javascript in order.xhtml
<script type="text/javascript">
//<![CDATA[
function display(){
alert(" I M BEING CALLED");
}
</script>
There are two ways about this, either a make the script type dojo/method.
Or use the extended dojox/layout/ContentPane.
http://livedocs.dojotoolkit.org/dijit/layout/ContentPane#executing-javascript-inside-contentpane
While I'm not familiar with the dojo toolkit, I think you should put the JavaScript function in the main file or load the JavaScript dynamically like;
How do I include a JavaScript file in another JavaScript file?
dijit.layout.ContentPane will not support javascript,i mean it will not execute the javascript content in the input file.
dojox.layout.ContentPane is advanced one and it will support javascript.

Resources