Is it possible to template JavaScript or CSS files with TAL?
(or maybe there is some other templating mechanism in Zope exists)
e.g. templated CSS file will be something like that:
#button {
background-color: <%= buttonColor %>;
background-image: <%= buttonImage %>;
}
If you are using Zope2, use DTML. TAL/ZPT is only appropriate for HTML/XML/SGMLish markups.
If you are using browser views, you can also choose to use any Python-based template system, should you be willing to take care of rendering the template in your view's index() (or __call__()) method.
Related
I have a quick question regarding implementation of a small change in our system, and I want to hear your opinion about my little disagreement with another developer in our company.
Our working environment:
Laravel
AdminLTE
Two laravel guards for 'partner' and 'staff'. Each type of user (partner/staff) has access to a different set of pages, using a different set of controllers and a different subdomain.
Admin LTE comes with some skins that you can apply to your <body>, for example 'skin-blue' theme. This is what our page looks like. Just for a comparison, if you remove the 'skin-blue' class, our website looks like this.
We were asked by our client to change the color of the top navbar for the Staff side. So, because the colors at the moment are being added by an adminLTE skin, I thought it was better to create a second theme for the staff side, calling it "skin-staff", and then in our base blade file, check for which guard is being used, and add the class accordingly.
<body class="#if(get_guard() === 'partner') skin-blue #else skin-staff #endif" ...>
I made a copy of the original skin-blue file, renamed it to skin-staff, and just changed the color of the necessary elements. I thought this was the best way to go about it, but the developer which had to review my github Pull Request said that because this was such a small change, it wasn't necessary to create a new skin. His proposed solution was to simply add the css classes in the blade file, something like:
<head>
…
<style type="text/css">
#if (get_guard() === 'staff')
.skin-blue .main-header .navbar{
background-color:#bdac3c
}
.skin-blue .main-header .navbar .sidebar-toggle:hover{
background-color:#ac9b2b
}
.skin-blue .main-header .logo{
background-color:#bdac3c;
}
… // and other classes
#endif
</style>
Now, to me this is not correct, because we are mixing the logic for staff and partner side without a clear way to differentiate them. If we use skins, we can simply say something like "The top navbar is yellow because we are using class skin-staff". And "We are using class skin-staff because we are on the Staff guard". The propositions are clear and simple. However, by adding raw CSS to our blade file, we end up with something like "The top navbar is yellow because we are using skin-blue and also we are on the Staff guard and also we have added some custom CSS for the Staff guard". The extra changes we introduce to the system don't follow the pattern used by adminLTE, to me they just look like noise. If we had to for example do this five more times, we would end up with a lot of CSS in our base blade file, which I think would look bad and would force us to eventually decide to use the skin system of adminLTE, something we could just do right away.
But, being as stubborn as I know I am, I don't know if I have the right idea or if I just want to do things my way.
What do you guys think? Is it better to create a new skin, even if most of the CSS code inside the skin file will be duplicated, but it allows us to stick to the existing way of doing things, or is it better to just add the code in the blade file and don't think more about it?
Thanks for your ideas
This is very much an opinion based question, there is no clear right or wrong answer here.
Personally, I agree with your coworker, why copy the whole theme, that is hundreds of lines long, just to change a handful of classes?
That said, I don't personally like the styles living in the DOM under a style tag.
Why not create a new CSS file that contains the styles:
.skin-blue .main-header .navbar{
background-color:#bdac3c
}
.skin-blue .main-header .navbar .sidebar-toggle:hover{
background-color:#ac9b2b
}
.skin-blue .main-header .logo{
background-color:#bdac3c;
}
… // and other classes
And then as long as you include this file after the base skin-blue CSS theme, your updated staff skin changes will take precedence.
Something like this:
<link rel="stylesheet" href="{{ asset('css/skin-blue.css') }}">
#if (get_guard() === 'staff')
<link rel="stylesheet" href="{{ asset('css/skin-staff.css') }}">
#endif
This keeps the abstraction of your CSS inside CSS files (and out of the DOM), yet only overwrites exactly what it needs to.
It also means that if you need to update a common style between the two themes, you don't need to make the change in two different files; you just need to modify the skin-blue.css file.
When the user finish writing in the "ckeditor 5" I take the html input and store it in database:
The content will be saved in database as text:
<blockquote><p>Hello <strong>world</strong></p></blockquote><p> </p><figure class="table"><table><tbody><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></tbody></table></figure>
Now when I get this content from database and I want to show it in the front-end, It shows up like this:
How to make the text css style the same as how the user has entered in the "ckeditor 5" ?
According to laravel's documentation
By default, Blade {{ }} statements are automatically sent through
PHP's htmlspecialchars function to prevent XSS attacks. If you do not
want your data to be escaped, you may use the following syntax:
Hello, {!! $name !!}.
You dont need to duplicate the editor styles.
All editor have base class and styles for content inside that class.
for ckeditor5 for exmaple that class 'ck-content'.
From the docs https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/content-styles.html
Important!
If you take a closer look at the content styles, you may notice they
are prefixed with the .ck-content class selector. This narrows their
scope when used in CKEditor 5 so they do not affect the rest of the
application. To use them in the front–end, you will have to add the
ck-content CSS class to the container of your content. Otherwise the
styles will not be applied.
Finally, using WYSIWYG (What You See Is What You Get) editors you should ovveride the editor styles config to provide same styles for the editor and for wrapped display content with same class.
Otherwise, the final solution will not be WYSIWYG.
Solution 1:
Install bootstrap on display.php
https://getbootstrap.com/
Solution 2
You need to apply CSS manually on the display page.
HTML from database on (for example) display.php:
<blockquote><p>Hello <strong>world</strong></p></blockquote><p> </p><figure class="table"><table><tbody><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></tbody></table></figure>
Write CSS on display.php like:
<style>
table tr td{
border:solid 1px #CCC;
}
</style>
I want to generate dynamic CSS using templates and Tilt andSASS in Rails 4.
Let's say I have the following css.sass template:
$class_name: test
$width: 329
$height: 425
.view-#{$class_name}
width: #{$width}px
height: #{$height}px
I need master.css.sass.erb (I am not sure about the format) in which I am going to render my template as many times as I like with different parameters.
In application.css, I am going to have something like this
*= require master.css.sass.erb
Each time I use the template with different parameters, I am going to add a line in my master.css.sass.erb file. I do not know how to pass parameters using Tilt to the css.sass template. Could anyone assist and tell if this is possible?
This is what I have till now:
The template test.css.sass.erb:
$color: <%= color %>
body
background: #{$color} !important
The master.css.sass.erb file:
<%
require 'erb'
config_path = File.expand_path("../test.css.sass.erb", __FILE__)
template = Tilt.new(config_path)
template.render(self, :color => 'yellow')
%> .thisisrendered
color: red
Note that the two files in one folder. The issue is that only the following css is renrered:
.thisisrendered
color: red
To answer your question: when erb is compiled, it only outputs ruby code contained in a <%= code %> wrapper. Your current code is probably running fine (I'm not familiar with Tilt or straight SASS), but you aren't telling it to output the result to the sass file. Change the first line of master.css.sass.erb from <% to <%= and then you can debug from there.
That being said, I would recommend against this process. You're going to be wasting resources compiling the stylesheet every time it is called.
An alternate method would be to just keep your stylesheets static as in your opening example so they can be precompiled and cacheable, and then create a partial like layouts/_conditional_styles.html.erb using stock html and css like:
<% unless #your_sanitized_style_object.nil? %>
<style>
body{
background: <%= #your_sanitized_style_object.background_color.html_safe %> !important;
}
</style>
<% end %>
Which could override the application stylesheet by being rendered after the application css file in your layouts/application.html.erb file such as:
<%= stylesheet_link_tag "application" %>
<%= render "layouts/conditional_styles" %>
To answer your question as to why you use less resources using precompiled assets and then overriding them, consider your example test.css.sass.erb
$color: <%= color %>
body
background:$color !imporant
Assuming the color variable is red, the process would go something like this... First your application will run through it with its erb compiler and give you a test.css.sass file such as:
$color: #ff0000
body
background:$color !important
Then your application will run through the code again with its sass compiler to give you a test.css file such as:
body{ background:#ff0000 !important; }
And after all of that, it will serve up the file. In your development environment you will not see that much of a performance difference as your application defaults to rebuilding the assets for every request. The difference comes when it's time to serve your application to the web in production.
If your assets aren't dependent on variables in the application, the stylesheets can be precompiled. What this means is that your application compiles the asset once, and after it compiles the asset you get a stylesheet like test-f25ab2b1286feb7cc98375sac732f7d0.css.
The stylesheets will be identical but what is unique is all that jargon that rails throws on the end of the file name when it precompiles something. That jargon is known as a fingerprint and its purpose is to tell the server on an incoming request whether or not there is a newer version of the file. If the file hasn't been modified, and the system making the request has already downloaded that file to its cache, then your browser will use the cached version instead of downloading the stylesheet over again.
Now lets say your test.css.sass.erb file is something huge like 50kB for example's sake.
Without precompilation your resource cost is:
having to traverse that 50kB file 2 times on every request to compile it from erb > sass > css
having to serve up that 50kB file on every request.
With precompiled assets that are overridden by conditional styles embedded in the html of the layout as explained in my first answer:
Your compilation cost goes down to almost zero because the stylesheet is precompiled so there's nothing to do to it and your whatever.html.erb template that contains the conditional styles is already being compiled by your erb compiler so you're just adding the work of rendering variables.
You only serve up the precompiled stylesheet once meaning you save ~50kB in bandwidth on every request, using only the bytes needed for the rendered dependent styles.
Hope this helps, for more information on how all of this works I would recommend starting with the Asset Pipeline Rails Guide.
Actually the question is in the subj...
Is it possible to make handlebars template framework, to recognize templates within a div tag and not in script tag?
For example I would like to create template with this markup:
<style>
div.text-x-handlebars {display:none;}
</style>
<div class="text-x-handlebars-template">
<h2>I'm template</h2>
<p>{{welcomeMessage}}</p>
</div>
Yes you can put your templates in <div>s rather than <script>s, for example:
http://jsfiddle.net/ambiguous/RucqP/
However, doing so is fraught with danger. If you put your template inside a <div> then the browser will interpret it as HTML before you've filled it in; so, if your template's HTML isn't valid until after it has been filled in, the browser may attempt to correct it and make a mess of things. Also, if you have id attributes in your templates, then you will end up with duplicate ids (one in the template <div> and a repeat in the filled in template that you put in the DOM) and that will cause all sorts of strange and interesting bugs. The browser will also try to download any images inside the templates in a <div>, this may or may not be a problem (if might even be desirable but probably not desirable if the image uses a template variable in its src attribute).
Basically, you can do it but you shouldn't, you should put your templates in <script id="..." type="text/x-handlebars-template"> elements instead.
How do you test if a div tag has a certain css style? I'm trying to test if it has display:none; or display:block.
I tried the following but its giving me an error:
it {should have_selector('signup_server_generic_errors', /display:\s*none/)}
I'd recommend that instead of trying to locate the css style, you instead write your tests to find the css class name.
This way you can change the underlying css styling while keeping the class the same and your tests will still pass.
Searching for the underlying style is brittle. Styles change frequently. Basing your rspecs on finding specific style elements makes your tests more brittle -- they'll be more likely to fail when all you do is change a div's look and feel.
Basing your tests on finding css classes makes the tests more robust. It allows them to ensure your code is working correctly while not requiring you to change them when you change page styling.
In this case specifically, one option may be to define a css class named .hidden that sets display:none; on an element to hide it.
Like this:
css:
.hidden {
display:none;
}
html:
<div class="hidden">HIDE ME!</div>
capybara:
it {should have_css('div.hidden') }
This capybara just looks for a div that has the hidden class -- you can make this matcher more sophisticated if you need.
But the main point is this -- attach styles to css class names, then tie your tests to the classes, not the styles.
You could use has_css? matcher. It can accept :visible options. For more details you can check docs: http://rdoc.info/github/jnicklas/capybara/Capybara/Node/Matchers#has_css%3F-instance_method
For example you can try:
it { should have_css('div.with-some-class', :visible => true) }
My way to ensure that element have a certain class:
let(:action_items) { page.find('div.action_items') }
it "action items displayed as buttons" do
action_items.all(:css, 'a').each do |ai|
expect(ai[:class]).to match(/btn/)
end
end
or smthing like this
expect(ai[:style]).to match(/color: red/)
I found it here: http://rubydoc.info/github/jnicklas/capybara/Capybara/Node/Element#%5B%5D-instance_method
You can use Capybara's assert_matches_style, or the Rspec HaveStyle matcher (which is using assert_matches_style underneath):
When you use assert_matches_style directly, it's:
find(".element").assert_matches_style("font-size" => "46px")
I'm not too familiar with Rspec syntax, but it should be something like this:
it { should match_style("font-size" => "46px") }