I am trying to write a code that set CSS for some dynamic elements added on click on a link.
As per the example code in CoffeeScript tutorial it should be working with the following code.
temp = temp+1
$ '.box_'+temp
.css 'background', 'white'
Here temp is a variable integer.
I tried with static values like
$ '.box_1'
.css 'background', 'white'
but it returns something like this with .css not a function error
$('.box_1'.css('left', 100));
Just add parens to remove ambiguity and save yourself the headache.
temp = temp+1
$('.box_'+temp)
.css('background', 'white')
Sexy function calls are optional syntactic sugar, not required. You should not be using language features if doing so makes your code less clear for humans or machines (or in this case, both!)
Related
I am in Terraform 14 and I am trying to add labels to my template file which should generate a YAML:
Template File:
labels:
${labels}
Code:
locals {
labels = merge(
var.labels,
map(
"module", basename(abspath(path.module)),
"module_version", var.module_version
)
)
prometheus_config = templatefile("${path.module}/prometheus.tmpl", {
labels = indent(8, yamlencode(local.labels))
})
When I try to add the labels indenting with 8 this outputs in the template file causing YAML errors:
Error Output:
labels:
"module": "my_module"
"module_version": "1.0"
As you can see the module_version has indent 8 which is correct but the module line is not indented.
I tried many things like moving ${labels} everywhere in the beginning, with multiple indentations but nothing seems to work.
It is for this reason that the templatefile documentation recommends using yamlencode for the entire data structure, rather than trying to concantenate bits of YAML together using just string templates. That way the yamlencode function can guarantee you a correctly-formatted result and you only have to produce a suitable data structure:
In your case, that would involve replacing the template contents with the following:
${yamlencode({
labels = labels
})}
...and then replacing the prometheus_config definition with the following:
locals {
prometheus_config = templatefile("${path.module}/prometheus.tmpl", {
labels = local.labels
})
}
Notice that the yamlencode call is now inside the template, and it covers the entire YAML document rather than just a fragment of it.
With a simple test configuration I put together with some hard-coded values for the variables you didn't show, I got the following value for local.prometheus_config:
"labels":
"module": "example"
"module_version": "1.0"
If this was a full example of the YAML you are aiming to generate then I might also consider simplifying but just inlining the yamlencode call directly inside the local value definition, and not have the separate template file at all:
locals {
prometheus_config = yamlencode({
labels = local.labels
})
}
If the real YAML is much larger or is likely to grow larger later then I'd probably still keep that templatefile call, but I just wanted to note this for completeness, since there's more than one way to get this done.
So using terraform 14 I was not able to transform lists or maps into yaml with yamlencode. Every option I tried using the suggested answer produced results with the wrong indentation. Maybe due to the many indentation levels in the file... I am not sure. So I dropped the use of yamlencode in the solution.
Solution:
I decided to use inline solution so for lists I transform then with string with join and for maps I use jsonencode so:
# var.list is a list in terraform
# local.abels is a map in terraform
thanos_config = templatefile("${path.module}/thanos.tmpl", {
urls = join(",", var.list),
labels = jsonencode(local.labels)
})
The resulting plan output is a bit ugly but it works.
First of all, I hope someone can actually understand this rambling question because I'm struggling to even word what I mean in a coherent way, but here goes:
I don't know why I'm struggling so much to figure this out, but I've been using #import with SCSS for a while now and feel I have my head around it fairly well, but now I want to use the #use rule since the phasing out of #import is a thing. And I can't find any videos or any real articles explaining how to use it properly.
The problem I'm having is I can't get my head around how to actually use it, I feel like I get the basic idea, and how to use the modules in each partial (I think..), but I feel like I don't understand how to actually get all of the partials into a main .scss file to be compiled into css.. This is hard to explain.. I just feel like I would still need to #import at least the files that have #use inside them into a main file for it to be compiled.. I'm guessing this obviously isn't the case, but otherwise I can't work it out.. Do I just #use all the files I want imported into the main file or..?
If anyone could shed some light on this for me, I would be really grateful.
Thanks
The new rules #use/#forward and the remove from #import are indeed a really big impact to SASS. It leads to a complete new form to write sass. A try to make an easy explanation for the beginning to use the new technique:
(1) #use works similar to #import. It adds the code from a (config- or partial-)file or a module to your stylesheet.
(2) The difference is: SASS changes the scope of variables/mixins/functions from global (all imported files = one scope) to local files (variables are only valid in the actual file). If you need to use variables/mixins/functions from another (config- or partial-)file you need to 'include' them to the actual file first.
That means for your project(*):
//file ###> _config.scss
$columnWidth: 50%;
$projectColors: (
primary: red,
secondary: blue,
);
//file ###> _functions.scss
#use 'config' as * // --> to use config vars (here: without namespace)
#function getColor( $name ){
$color: map-get($projectColors, $name);
#return $color;
}
//file ###> _partial.scss
#use 'config' as * // --> use config vars (here: without namespace)
#use 'functions' as * // --> use functions (here: without namespace)
.class {
width: $width;
color: getColor( primary );
}
//file ###> myStylesheet.scss
// no need to #use 'config' or 'functions'
// as they are not direct needed in this file
#use 'partial' //--> write the css
---
( * ) Including files without using a namespace is a special case to make the example more easy. Normaly you will include variables/mixins/functions to a separated namespace and call them by namespace.$variable or namespace.mixin. And there are techniques to move special settings to a #used file as well so you can move variable settings to the project. Please have a look to official and excelent description: https://sass-lang.com/documentation/at-rules/use
NOTES:
(1) As it is heavily discussed: Yes. This is INDEED the intended new way to work with SASS. (https://github.com/sass/sass/issues/2750)
(2) Very interesting: The actual brandnew version from Bootstrap has moved to the new Sass Version. But as I have seen Bootstrap does not use that new feature #use and still works with #import. That may have reasons ... and it seems not to easy to change the technique.
(3) Also it seems to be a little bit complicated there are some advantages comming with that new technique. Using separate namespaces make it much mor easier to work with external modules without causing name conflicts.
Wasted over 3 days of troubleshooting; have gotten nowhere further. Appreciate any assistance at this point. Here's my code:
var gulp = require('gulp'),
path = require('path');
gulp.task('prefix', function() {
var prefixer = require('gulp-autoprefixer');
gulp.src(path.join(__dirname, 'app/styles/assets/**/*.css'))
.pipe(prefixer({ browsers: [ '> 1%' ] }))
.pipe(gulp.dest('./');
});
I placed a single .css file in the specified source directory and added properties/values that would require prefixing, like: transform, column-count and the 'flex' value of the display property.
When run, gulp gives no errors, no file is modified, pretty much nothing happens. I've tried specifying a path to an output file, removing the options from the prefixer() call, hard-coding values into the .src() and .dest() methods, running the whole command in a singular file, inside a sequence runner, reinstalled the module, updated packages and more.
I've read the docs inside and out, am following them to a 'T', and even contacted the module author to look at my code, and he stated it looked fine to him. I simply cannot see what I'm doing wrong.
Let's say you have a file that contains these 2 vars, but also other content
//Other code above
var endpoint='...';
var redirectUrl='...';
//Other code below
Now, is there a way for Grunt to change the value of those vars depending on build params?
Thanks.
If you enclose your line with something easily matchable. (Or if the original values are unique enough, it can be fine as well.)
You can use this plugin:
https://github.com/outaTiME/grunt-replace
To replace it with something else.
I've spent my requisite two hours Googling this, and I can not find any good answers, so let's see if humans can beat Google computers.
I want to parse a stylesheet in Ruby so that I can apply those styles to elements in my document (to make the styles inlined). So, I want to take something like
<style>
.mystyle {
color:white;
}
</style>
And be able to extract it into a Nokogiri object of some sort.
The Nokogiri class "CSS::Parser" (http://nokogiri.rubyforge.org/nokogiri/Nokogiri/CSS/Parser.html) certainly has a promising name, but I can't find any documentation on what it is or how it works, so I have no idea if it can do what I'm after here.
My end goal is to be able to write code something like:
a_web_page = Nokogiri::HTML(html_page_as_string)
parsed_styles = Nokogiri::CSS.parse(html_page_as_string)
parsed_styles.each do |style|
existing_inlined_style = a_web_page.css(style.declaration) || ''
a_web_page.css(style.declaration)['css'] = existing_inlined_style + style.definition
end
Which would extract styles from a stylesheet and add them all as inlined styles to my document.
Nokogiri can't parse CSS stylesheets.
The CSS::Parser that you came across parses CSS expressions. It is used whenever you traverse a HTML tree by CSS selectors rather than XPath (this is a cool feature of Nokogiri).
There is a Ruby CSS parser, though. You can use it together with Nokogiri to achieve what you want.
require "nokogiri"
require "css_parser"
html = Nokogiri::HTML(html_string)
css = CssParser::Parser.new
css.add_block!(css_string)
css.each_selector do |selector, declarations, specificity|
html.css(selector).each do |element|
style = element.attributes["style"]&.value || ""
element.set_attribute('style', [style, declarations].compact.join(" "))
end
end
#molf definitely had a great start there, but it still required debugging a handful of problems to get it working in production. Here is the current, tested version of this:
html = Nokogiri::HTML(html_string)
css = CssParser::Parser.new
css.add_block!(html_string) # Warning: This line modifies the string passed into it. In potentially bad ways. Make sure the string has been duped and stored elsewhere before passing this.
css.each_selector do |selector, declarations, specificity|
next unless selector =~ /^[\d\w\s\#\.\-]*$/ # Some of the selectors given by css_parser aren't actually selectors.
begin
elements = html.css(selector)
elements.each do |match|
match["style"] = [match["style"], declarations].compact.join(" ")
end
rescue
logger.info("Couldn't parse selector '#{selector}'")
end
end
html_with_inline_styles = html.to_s