I'm trying to convert a raw string to html with the Liquid templating language. What I want to do is convert this:
Hello. This
is a text.
Please convert me.
into this:
<p>Hello. This<br />
is a text.</p>
<p>Please convert me.</p>
What I tried
{{ mytextvariable | newline_to_br | replace: "<br />\n<br />", "</p><p>" | replace: "<p></p>", "" | prepend: '<p>' | append: '</p>' }}
but this gives me (notice double <br />):
<p>Hello. This<br />
is a text.<br />
<br />
Please convert me.</p>
Site note
This will be used for a Shopify site.
You're replacing new lines with break tags when using newline_to_br, so the first replacement won't replace anything, newlines are gone.
From what I can see, Liquid does not support regular expressions, so the replace: "<br />\n<br />" will probably be interpreted literally.
Might be easier to implement as a new filter?
... something like this:
def newline_to_p_or_br(input)
input.to_s.gsub(/(.*?)\n\n/, "<p>\1</p>").gsub(/\n/, "<br />\n")
end
Here is the definition of newline_to_br for reference:
http://rubydoc.info/gems/liquid/2.2.2/Liquid/StandardFilters:newline_to_br
Related
In my project I am trying to use filterXPath for emails. So I get an E-Mail via IMAP and put the mail body into my DomCrawler.
$crawler = new Crawler();
$crawler->addHtmlContent($mail->textHtml); //mail html content utf8
Now to my issue. I only want the plain text of the mail body, but still remain all new lines spaces etc - the exact same as the mail looks just in plain text without html (still with \n\r etc).
For that reason I tried using $crawler->filterXPath('//body/descendant-or-self::*/text()') to get every text node inside the mail.
However my test-mail containts html like:
<p>
<u>
<span>
<a href="mailto:mail#example.com">
<span style="color:#0563C1">mail#example.com</span>
</a>
</span>
</u>
<span>
</span>
<span>·</span>
<span>
<b>
<a href="http://www.example.com">
<span style="color:#0563C1">www.example.com</span>
</a>
</b>
<p/>
</span>
</p>
In my mail this looks like mail#example.com · www.example.com (in one single line).
With my filterXPath I get multiple nodes which result in following (multiple lines):
mail#example.com
· wwww.example.com
I know that probably the
might be the problem, which is a \r, but since I can't change the html in the mail, I need another solution - as mentioned before in the mail it is only a single line.
Please keep in mind, that my solution has to work for every mail - I do not know how the mail html looks like - it can change every time. So I need a generic solution.
I already tried using strip_tags too - this does not change the result at all.
My current approach:
$crawler = new Crawler();
$crawler->addHtmlContent($mail->textHtml);
$text = "";
foreach ($crawler->filterXPath('//body/descendant-or-self::*/text()') as $element) {
$part = trim($element->textContent);
if($part) {
$text .= "|".$part."|\n"; //to see whitespaces etc
}
}
echo $text;
//OUTPUT
|mail#example.com|
|·|
| |
|www.example.com|
| |
I believe something like this should work:
$xpath = new DOMXpath($crawler);
$result = $xpath->query('(//span[not(descendant::*)])');
$text = "";
foreach ($result as $element) {
$part = trim($element->textContent);
if($part) {
$text .= "|".$part."|"; //to see whitespaces etc
}
}
echo $text;
Output:
|mail#example.com||·||www.example.com|
Do note that you are dealing with two different ways to treat whitespace only text nodes: HTML has its own rules about if those are rendered (the difference are mainly between block elements and inline elements and also includes normalization) and XPATH works over a document tree provided by a parser (or DOM API) which has its own configuration about preserving or not those whitespace only text nodes. Taking this into account, one solution could be to use the string() function to get the string value of the element containing the email:
For this input:
<root>
<p>
<u>
<span>
<a href="mailto:mail#example.com">
<span style="color:#0563C1">mail#example.com</span>
</a>
</span>
</u>
<span>
</span>
<span>·</span>
<span>
<b>
<a href="http://www.example.com">
<span style="color:#0563C1">www.example.com</span>
</a>
</b>
<p/>
</span>
</p>
</root>
This XPath expresion:
string(/root)
Outputs:
mail#example.com
·
www.example.com
Check in here
I have the following problem, i have a JSF command button:
<h:commandButton value="#{o.foo}" actionListener="#{someAction}" styleClass="#{row.buttonCssStyle} buttonMenu ">
<f:attribute name="smthing" value="#{o.smthing}" />
</h:commandButton>
This renders as expected
(Sorry for text removal)
But the commandButtons which have ( as last char on a line do NOT linebreak and i dont know how to solve it. We are talking about IE 9
Command buttons generated css:
Any help is highly appreciated, thanks
edit:
from ie debugger:
<input name="formId:we:_idJsp112:_idJsp113:3:_idJsp115" class="missingDatesButtonState buttonMenu " id="formId:afterSales:_idJsp112:_idJsp113:3:_idJsp115" onclick="..." type="submit" _nodup="30804" value="TESTST(RL, EBO und SLP) ( <br/>( ( ( ( ( ( ( asda #### # # # ### # ( asda"/>
Edit #BalusC:
This is the result with line feed:
I consider it is a failure of the IE9 on parsing of the value , when generating the element... since it works for text but not for symbols... I think it is directly related to that....
HTML code inside HTML attributes isn't interpeted as HTML. This isn't a JSF problem.
Just insert a real linefeed character either via
or
in (X)HTML or i18n bundle file,
<h:commandButton ... value="top line
bottom line" />
... or via \n in Java.
<h:commandButton ... value="#{bean.value}" />
value = "top line \n bottom line";
I've got a string and I want to
isolate the first word for styling with style1 and
display the rest of the string with style2 without the first word.
Something like that :
<span class="style1">{{ string|firstword() }}</span>
<span class="style2">{{ string|restofstring() }}</span>
Is it possible ? Thank you in advance.
I believe you can achieve this by using the split command in Twig. To split you need to identify the separator between two words. Assume your words are separated using a space. Then you can get the first and second words like this.
{{ "Monday Tuesday" | split(' ')[0] }}
Will return the "Monday"
{{ "Monday Tuesday" | split(' ')[1] }}
Will return the "Tuesday"
More about split :- http://twig.sensiolabs.org/doc/filters/split.html
Hope this helps,
Cheers!
I found it ! With split() and attribute() TWIG functions.
{% set array = article.titre|split(' ', 2) %}
<span class="style1">{{ attribute(array, 0) }}</span><!-- First word -->
<span class="style2">{{ attribute(array, 1) }}</span><!-- Rest of string -->
Thanks to Anjana Silva who give me the begginning of the idea.
As an alternative to the array syntax, you might find the first filter to be more idiomatic:
{{ "Hello Twig"|split(' ')|first }}
I'm displaying some variable retrieved in my database using Twig :
<p>{{ my_variable }}</p>
The thing is this variable may contain html tags, such as "<br />".
Twig seems to automatically call some htmlentities-like function when displaying variables.
Is there any way to disable it so that when I display a variable containing "Hello<br />world !" I get :
Hello
world !
rather than :
Hello<br />world !
Thanks
Use {{ my_variable|raw }} to prevent my_variable from being automatically escaped.
See Twig documentation: http://twig.sensiolabs.org/doc/filters/raw.html
Try using this
{% autoescape false %}{{ my_variable}}{% endautoescape %}
even better: {{ '<br />|raw('html') }} to avoid unescaping other sensible stuff.
If you just want to use linebreaks in the text stored in your database but don't care to use html , you can also use the nl2br filter as in {{ var|nl2br }}. Allows you to use string linebreak character \n in your text. Filter converts it to <br/>
I have a page where I wish to render the following html (a small JS template)-
<script type="text/html" id="lightbox-template">
<div id="lightbox-background"></div>
<div id="lightbox"><%= content %><div class="bottom"></div></div>
</script>
However, the Asp.NET preprocessor is picking up on the "<%=" tag and trying to interpret it. I wish to escape this tag to allow it to be rendered, preferably from the template rather than the code behind. Is this possible?
I have managed to do this via a Literal control and setting it's text in the code behind.
I ideally wanted to keep it within the aspx page. This is the best solution I could find (from here), which creates splits the closing > into a separate string
<script type="text/html" id="lightbox-template">
<div id="lightbox-background"></div>
<div id="lightbox"><%= "<%= content %" + ">" %=><div class="bottom"></div></div>
</script>
Important bit: <%= "<%= content %" + ">" %=>
This goes into aspx
<div> <%= GetContentString() %> </div>
This goes into aspx.cs
protected String GetContentString()
{
return "this is a content";
}