jade: escape html in mixin argument - javascript

What I've tried:
mixin simpleDivInject(text)
div
h1 #{text}
mixin simpleDivInject("line one <br/> line two")
Desired outcome
<div>
<h1>line one <br/> line two</h1>
</div>
The actual outcome
<div>
<h1>line one <br/> line two</h1>
</div>
How can I achieve the desired outcome. I have tried a few more things (such as storing the string in a var ect.), but no luck so far.

Actually I just figured it out. Answering here in the hopes it is helpful to someone else down the line. The escaping is not occurring in the mixin argument system, but in the vinilla jade system, so:
mixin simpleDivInject(text)
div
h1!= text
mixin simpleDivInject("line one <br/> line two")
Solves the problem

Related

Save line breaks from String in JavaScript object to transfer over to breaks in HTML

sorry if this a pretty basic question but I'm trying to store a multi-paragraph chunk of text in an object in a Pinia store to be converted to text in HTML, but I can't figure out how to transfer paragraph breaks through the Pinia store.
export const useContentStore = defineStore('contentStore', {
state: () => {
return {
guides: [{
description: 'Paragraph one. Paragraph two. Paragraph three.',
}],
}
},
})
<template>
<main class="content-page">
<body>
<p>{{ content.description }}</p>
</body>
</main>
</template>
I'd like there to be some space between each paragraph, I don't know if that would be adding another line between them or something different. I've already tried escaping like \n, adding <br> tags in the text, and using template literals.
This is what my end goal is:
Paragraph one.
Paragraph two.
Paragraph three.
Thanks for any help you can give!
p {
white-space: pre-wrap
}
<p>
Paragraph one.
Paragraph two.
Paragraph three.
</p>
As you can see above, if you use css property white-space: pre-wrap, it can do what you ask, but be carefull, it may cause other weird interactions.
It will preserve whitespaces, newlines, tabs and <br />.

Why using .filter() together with .match() is only returning the first element matching the condition?

I have some HTML code where at the most nested level there is some text I'm interested in:
<div class="main">
<div class="container">
<div class="output_area">
<pre>WHITE 34</pre>
</div>
<div class="output_area">
<pre>RED 05</pre>
</div>
<div class="output_area">
<pre>WHITE 16</pre>
</div>
<div class="output_area">
<pre>BLACK</pre>
</div>
</div>
</div>
What I need to do is I need to return the output_area elements only when their nested <PRE> element contains a word + a number (for example WHITE 05, and not just BLACK).
So this is what I did:
I made an array from all output_area elements:
output_areas = Array.from(document.getElementsByClassName('output_area'));
I filtered the output_areas array to only return those output_area elements whose nested <PRE> satisfies my condition of a word + a number, using a regexp, like so:
output_areas.filter(el => el.textContent.match(/^WHITE \d+$/g));
Now, what happens is this function will only return the first matching result, so I will get an object of length 1 containing just :
<div class="output_area">
<pre>WHITE 34</pre>
</div>
and the output_area element containing <PRE> with "WHITE 16" is not returned.
As you can see at the end of the regular expression I put a "g" to request a global search and not just stop at the first result.
Not understanding why this did not work, I tried to verify what would happen if I would use includes() to perform a search:
output_areas.filter(el => el.textContent.includes('WHITE')
(let's just forget about the numbers now, it's not important)
And what happens? This will also return only the first output_area...
But why??? What am I doing wrong?
I am not ashamed to say I've been banging my head on this for the last couple of hours... and at this point I just want to understand what is not working.
The only clue I think I got is that if I simplify my search using just a == or !=, for example:
output_areas.filter(el => el.textContent != "")) // return all not empty elements
I get back all output_area elements and not just the first one!
So I suspect there must be some kind of problem when using together filter() & match(), or filter() & includes(), but with relation to that my google searches did not take me anywhere useful...
So I hope you can help!
You should use trim here to remove space before and after the text
output_areas.filter( el => el.textContent.trim().match( /^WHITE \d+$/g ))
const output_areas = Array.from(document.getElementsByClassName('output_area'));
const result = output_areas.filter(el => el.textContent.trim().match(/^WHITE \d+$/g));
console.log(result);
<div class="main">
<div class="container">
<div class="output_area">
<pre> WHITE 34 </pre>
</div>
<div class="output_area">
<pre> RED 05 </pre>
</div>
<div class="output_area">
<pre> WHITE 16 </pre>
</div>
<div class="output_area">
<pre> BLACK </pre>
</div>
</div>
</div>
Answering myself as for some reason it then begin to work without any changes from my side... Yes, just one of those typical IT cases we all know... :)
Jokes aside, I think for some reason the webpage (the DOM) got stuck...
Probably the Jupyter Runtime (which was serving the page) had crashed without me noticing, and this caused somehow the kind of inconsistency I was looking at.
Moral of the story: if you see weird behaviour in the interaction with a Python Notebook, always go check the Jupyter Runtime status before getting stupid at trying to fix impossible errors.
I'm not sure what the issue with the Jupyter notebooks is, but generally speaking - based only on the HTML in the question - what I believe you are trying to do can be achieved using xpath instead of css selectors:
html = `[your html above]
`
domdoc = new DOMParser().parseFromString(html, "text/html")
const areas = domdoc.evaluate('//div[contains(./pre," ")]', domdoc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < areas.snapshotLength; i++) {
console.log(areas.snapshotItem(i).outerHTML)
}
The output should be the 3 divs meeting the condition.

Select line in paragraph using jQuery based on line break

This question may be related.
I have a Django recipe app that uses a form containing of a CharField TextArea. This field is used to enter a list of directions (string). I have chosen to separate each direction with a line break (ENTER in form), and use the following in my template (html) to keep line breaks as in original form
<div id="items">
<p>
{{ recipe.directions_field|safe }}
</p>
</div>
This will basically appear as something like
<div id="items">
<p>
Line one <br/>
Two <br/>
Three <br/>
</p>
</div>
What I want to do is to use jQuery to "check" (strikethrough) one single line (may contain of several words) in my template. I have tried the following, but as expected, this checks the entire paragraph.
<script>
$(document).ready(function() {
$("#items p").click(function () {
$(this).toggleClass('stroked');
});
});
</script>
Where my css has
.stroked{ text-decoration: line-through; }
In my Django view I replaced "\n" with html line break in order to make sure line breaks are not removed when shown in template.
directions = directions.replace("\n", "<br/>")
I think a solution like this would work if I could just find an easy way to use <br/> as a splitter instead of ". " or any other symbol. I couldn't make that work with <br/> in the example.
Any suggestions, either using a solution like this or another way? I guess there are many ways to solve this, but hope to find an easy implementation.
Thanks for any reply.
It's much easier if you wrap every single line into <span></span>, like this:
<div id="items">
<p>
<span>line one <br/></span>
<span>line two <br/></span>
<span>line three <br/></span>
</p>
</div>
So what you need to do in javascript is:
$(function(){
$('#items > p > span').click(function(){
if($(this).attr('class') == 'stroked'){
$(this).removeAttr('class');
}
else{
$(this).addClass('stroked');
}
});
});

How to keep line breaks in CKEditor WYSIWYG editor

I have an HTML code as follows
<div class="editable" ...>
<div class="code">
This is an example.
This is a new line
</div>
</div>
In CSS, code has "word-wrap: pre" attribute, such that the text in the inner DIV will show two lines. I use CKEditor with DIV replacement method to edit it. However, it becomes
<div class="code">
This is an example.This is a new line
</div>
The text inside the HTML tag will become one line long, beginning and trailing spaces and new line are stripped. So in CKEditor, although I have specified the config.contentsCss, it still shows one line because CKEditor has merge those two lines into one (I checked this in Chrome "Inspect Element" in CKEditor's iframe editor). Therefore, I see the source code or saved HTML, two lines format is not preserved because they are only one line.
I've googled and tried the CKEditor HTML writer or addRules to restrict the indent format and new line in begin/close tags, however, those seems work on HTML tags, not the document text. Is there any other methods to preserve line breaks of text?
I found it.
// preserve newlines in source
config.protectedSource.push( /\n/g );
http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-protectedSource
$(document).on('paste', 'textarea', function (e) {
$(e.target).keyup(function (e) {
var inputText = $(e.target).val();
$(e.target).val(inputText.replace(/\n/g, '<br />'))
.unbind('keyup');
});
});
Use the <pre> HTML tag. Like this:
<div class="editable" ...>
<div class="code"><pre>
This is an example in a "pre".
This is a new line
</pre></div>
</div>
<div class="editable" ...>
<div class="code">
This is an example NOT in a "pre".
Therefore this is NOT a new line
</div>
</div>
Or you can put a <br/> tag in between your lines. Its the ssame as hitting enter.
In my particular case, it was an extra tag, univis, that I needed to give similar semantics (i.e., leave indentation and inebreaks alone), and what we ended up doing was:
CKEDITOR.dtd.$block.univis=1;
CKEDITOR.dtd.$cdata.univis=1;
CKEDITOR.dtd.univis=CKEDITOR.dtd.script;
But that looks like it might or might not be extensible to classes.
I got some Craft sites running and I don't want to paste the config file everywhere. For everyone else still having the problem: Just use redactor. Install and replace the field type. Correct everything once and you're done.

"Soft link" element in HTML

Suppose that there is a given HTML subtree which is repeated across multiple points in my code:
<div class='content'>
...
<p>This is repeated many times</p>
....
<p>This is repeated many times</p>
...
<p>This is repeated many times</p>
</div>
Is there a way to create a kind of "soft link" for the first <p> so that each repetition could just point to it? Or there is a better alternative for this kind of problem?
Update
It seems that my question is unclear, So I will try to clarify it by giving an example of a imaginary solution. Suppose that HTML provides an <alias>, which acts like a pointer to another element. So, instead of repeating the same element over and over, I could do something like that:
<div class='content'>
...
<p id='repeat'>This is repeated many times</p>
....
<alias from='repeat'/>
...
<alias from='repeat'/>
</div>
And the HTML would be rendered in the same way.
So, as #Cerbrus and #bfavaretto have commented, the answer unfortunally is no, there is no way to use something such as an <alias> without resorting to JavaScript. Since search engines ignore JavaScript, they would ignore part of the page, and that would really be bad for the site as a whole.
Try this:
<div class='content'>
...
<p id='firstP'>This is repeated many times</p>
...
<p>This is repeated many times</p>
...
<p>This is repeated many times</p>
</div>
<a href='#firstP'>Link to the first <p> tag.</a>
Example
If I've understood the question.
same as others : cant do this in HTML.
because HTML havnt alias tag!
but i think it could be doing with linking "js" and "html events".
you must write a bridge.
for example: set id for your tagS. and set "change like event" for your alias tag!
and write a bridge js function to your ID.

Categories

Resources