How to match a hexadecimal value in liquid templates with regex? - html

Desired result
Content editors can enter hexadecimal values in Shopify for a background-color. How can you check with Liquid template's control flow if a given input is a valid hexadecimal?
The regex that needs to be implemented:
^#(?:[0-9a-fA-F]{3}){1,2}$
The Liquid snippet where it should be added:
<div class="a-module" style="background-color: {{ bg_color }};">
...
</div>
The variable bg_color may only be a hexadecimal including the pound # character.
How can above be achieved with regex?
Other solutions?
If this is not possible what are other methods to match a string in liquid templates?
Research
I could not find much about regex in liquid templates.
There is this issue: Regex for matching a tag in a Liquid template : ">" inside html tag
But I do not understand how it is to be implemented.

There is no regex in Shopify liquid, so there is no way to check it that way.
A better approach will be to use one of the color filters.
You can do something like this:
{% assign is_color = bg_color | color_to_rgb %}
{% if is_color %}
It's color
{% endif %}
Where if the color is valid it will return a rgb output, but if it's not it will return a null result making the variable false.
If you really need to use regex, the only option is to rely on Javascript and handle it once the DOM is ready.

What about create your own filter. And in this filter checking hexadecimal.
/^#[0-9a-f]{3,6}$/igm
https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-filters

Related

Can a liquid for loop contain a page variable in Jekyll?

Let's say I have a bunch of _data files that I use to create a list for specific pages. All of the pages that have these lists have a custom front matter variable of pageName. The value of pageName just so happens to match the _data file with the list.
Rather than pasting the html blocks of code into each page, I'd like to use an include to pull in a generic block of html. To do that, the include has to be dynamic or contain liquid markup to become dynamic.
That might be more context than you need, but my question boils down to this, is something like this possible:
{% for item in site.data.{{page.pageName}} %}
{{ item.label }}
{% endfor %}
Unless I'm missing something, this doesn't work so I'm wanting to know if there's a way of achieving similar functionality.
I found this similar question, but it doesn't seem to answer whether it can be used to access a page variable to build a file name.
You can use the bracket notation like this :
{% for item in site.data[page.pageName] %}

Twig escaping HTML and rendering as raw

I hope someone can assist me on this issue.
I am pulling details from a database to display on a twig template (using Symfony2) but the way in which it is saved in the db makes it difficult to interpret the HTML.
Basically, the HTML tags are already translated as entities in the table, e.g.:
<p>Bach Flower Crab Apple Remedy:&nbsp;the "cleansing" Remedy can be used both internally and externally&nbsp;</p><p><strong>
And so on. I have researched the rendering options in twig and tried the following (based on me rendering a loop of product descriptions):
{% set strategy = 'html' %}
{% autoescape 'html' %}
{{ product.description|escape('html')|raw }}
{% endautoescape %}
and also just:
{{ product.description|raw }}
The first method just echoes the existing content (as entities) and the second method just renders the HTML tags to the page as follows:
<p>Bach Flower Crab Apple Remedy: the "cleansing" Remedy can be used both internally and externally.</p><p><strong>...
So, as you can see, I cannot find a way to actually interpret the HTML tags in order to display the description as it should be.
Is there a way to do this? I can't do it in the PHP as all it's doing is sending an object to the template which is looped through:
public function showAction(Request $request, $store_id=0)
{
$max = 1000;
$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$products = $repository->getProductsByStoreId($store_id,$max);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$products,
$request->query->get('page', 1),
20
);
$return['products'] = $pagination;
$return['categories'] = $this->getCategories();
return $this->render('AppBundle:tables:productstable.html.twig', $return);
}
Your core issue is that you do not have HTML in your database to begin with. At best Twig could be outputting some HTML entities, which will render visibly as "<p>...", and at "worst" Twig will escape the text to render it accurately as it actually is, which is "<p>...". Expecting Twig to output actual HTML which will render a paragraph is unrealistic, since that's not what your original data contains at all.
You'll have to HTML-decode that text in PHP first, and then output it in Twig with ..|raw. raw means that Twig will output it as is without further escaping it. Since it's nonsense to get the data from the database to then html_entity_decode it, you need to fix your data input here! Don't HTML encode data which is going into the database, it serves no purpose.
I think you have to write custom escaper plugin to decode html entities and use it like this:
{{ product.description|myawesomehtmlentitiesdecoder|raw }}
http://twig.sensiolabs.org/doc/filters/escape.html#custom-escapers for reference.
But generally, it's better to store HTML in database and then apply needed security filters on output.

Django Templates: How to display html code?

I'm trying to display some HTML markup in a blog, and would like to know if there is a way to wrap a section of my Django template directly, without putting it into a context variable.
For example, I would like to output a bunch of code, some of it JavaScript, and some of it HTML, and some of it CSS. If I enter in the code directly into my Django template, and wrap it in some pre tags:
<pre>
/* Here is the markup I want to display: */
... lots of HTML
</pre>
the HTML tags are rendered.
Of course, to display:
<
I should use
<
and to display
>
I should use
>
I tried adding the Django tag {% autoescape on %} around the code section, but it had no effect because I'm not rendering a context variable.
I would like to know if there is an easier way than replacing every occurrence of < with < and every occurrence of > with >
I also know that if I put the code that I want to display into a context variable, then in my template, just displaying that context variable would automatically escape the code.
But I would rather just be able to directly cut and paste the code I want to display into my template. Is there a way to do this and display the HTML tags (i.e.
<h1> Heading Level 1 </h1>
without writing it in my template as:
<h1> Heading Level 1 </h1>
You have to use xmp tags.
<xmp>
<h1>Testing Html</h1>
</xmp>
This question is old, but it pops on search engines and no answer is correct imo.
SÅ‚awek Kabik's is deprecated, Smit Patel's is overly complicated (it bloats views).
In order to do what OP asked for, you have to use the force_escape built-in filter in a {% filter %} tag.
Example:
<pre>
<code>
{% filter force_escape %}
<span class="hello">Anything HTML really</span>
{% endfilter %}
</code>
</pre>
Output:
<pre>
<code>
<span class="hello">Anything HTML really</span>
</code>
</pre>
NOTE: Before you try to implement manually, please have a look at ckeditor.
ckeditor documentation
if this is not what you are looking for, then only proceed with answer.
Just Wrap your variable inside following Django template tag.
{% autoescape off %}
{{your_variable_here}}
{% endautoescape %}
put HTML code in "your_variable_here" variable And Django Will Display It as HTML. All HTML Tags will Work.
EDIT:
Sorry, I missed important part to mention.
in views do this
from django.template.loader import render_to_string
rendered = render_to_string('my_template.html', {'foo': 'bar'})
and pass this rendered string to template variable and render the given template inside other template by putting lines
{% autoescape off %}
{{rendered}}
{% endautoescape %}

Is there a way to evaluate string with liquid tags

I need to provide page content reference list (it should contain references on sections on page).
The only way which I can see is to use page.content and parse it, but I stumbled on problem with data evaluation. For example I can pull out this string from page.content: {{site.data.sdk.language}} SDK but there is no way to make jekyll process it, it outputs as is.
Also I want to make it possible to create cross-pages links (on specific section on page, but that link generated by another inclusion and doesn't persist in page.content in HTML form).
Is there any way to make it evaluate values from page.content?
P.S. I'm including piece of code which should build page content and return HTML with list (so there is no recursions).
P.P.S. I can't use submodules, because I need to run this pages on github pages.
Thanks.
Shouldn't {{ site.data.sdk.language | strip_html }} do it? I don't know, most probably I didn't understand the problem. Can you elaborate more? Maybe provide a link to a post you're referring to?
Thinking about the similar
{% assign title = site.data.sdk.language %}
which is a stock Liquid tag and does the job well, so instead of
{% section title={{site.data.sdk.language}} %}
write your code as
{% section title = site.data.sdk.language %}
The key here is that once you enter {%, you're in Liquid. Don't expect Liquid to go "Inception" all over itself. {{ is just a shorthand for "print this to output", but an parameter passing is not output, it's just reading a variable.
You should be able to also go wild and do:
{% section title = site.data.sdk.language | capitalize %}
For more re-read the docs: https://github.com/Shopify/liquid/wiki/Liquid-for-Designers

How to support line number when using pygments with Jekyll

How can I number the code lines which are highlighted using pygments in Jekyll?
According to the Liquid Extensions wiki page of the Jekyll documentation, the highlight Liquid tag has an optional second parameter, which may have the value linenos to turn on line numbering:
{% highlight language linenos %}
your code here
{% endhighlight %}
Use it with caution. With linenos the line numbers are actually inserted in the code's text, so will be impossible to copy the code block without them. (This could be solved by letting the visitor to $('.lineno').toggle() the line numbers' visibility. Works in Firefox, not sure if is portable.)
Update: Better use linenos=table:
{% highlight language linenos=table %}
your code here
{% endhighlight %}
That will place the code in a table with two cells: first td all the line numbers, second td the code itself. This makes possible to select only the code, without the line numbers.