I have an object inside my Ember app, with a description field. This description field may contain hyperlinks, like this
My fancy text <a href='http://other.site.com' target='_blank'>My link</a> My fancy text continues...
However, when i output it normally, like {{ description }} my hyperlinks are displayed as a plain text. Why is this happening and how can i fix this?
Handlebars escapes any HTML within output by default. For unescaped text in markup use triple-stashes:
{{{ description }}}
There's an alternative when one controls the property: Handlebars.SafeString. SafeStrings are assumed to be safe and are not escaped either. From the documentation:
Handlebars.registerHelper('link', function(text, url) {
text = Handlebars.Utils.escapeExpression(text);
url = Handlebars.Utils.escapeExpression(url);
var result = '' + text + '';
return new Handlebars.SafeString(result);
});
Note - please be careful with this. There are security concerns with rendering unescaped text that has come from user input; an attacker could inject a malicious script into the description and hijack your page, for example.
Related
I am using a third party indexing service (Swiftype) to search through my database. The returned records contains a property called highlight. This simply adds <em> tags around matching strings.
I then bind this highlight property in Ember.JS Handlebars as such:
<p> Title: {{highlight.title}} </p>
Which results in the following output:
Title: Example <em>matching</em> text
The browse actually displays the <em> tags, instead of formatting them. I.e. Handlebars is not identifying the HTML tags, and simply printing them as a string.
Is there a way around this?
Thanks!
Handlebars by default escapes html, to prevent escaping, use triple brackets:
<p> Title: {{{highlight.title}}} </p>
See http://handlebarsjs.com/#html-escaping
Ember escapes html because it could be potentional bad code which can be executed. To avoid that use
Ember.Handlebars.SafeString("<em>MyString</em>");
Here are the docs
http://emberjs.com/guides/templates/writing-helpers/
if you've done that you could use {{hightlight.title}} like wished,...
HTH
I found a similar question here: Wrap URL within a string with a href tags using Coldfusion
But what I want to do is replace tags with a slightly modified version AFTER the user has submitted it to the server. So here is some typical HTML text that the user will submit to the server:
<p>Terminator Genisys is an upcoming 2015 American science fiction action film directed by Alan Taylor. You can find out more by clicking here</p>
What I want to do is replace the <a href=""> part with a new version which would be like this:
...
clicking here
So I'm just adding the text rel="nofollow noreferrer" to the tag.
I must match anchor tags that contain a href attribute with a URL, not just the URL string itself, because sometimes a user could just do this:
<p>Terminator Genisys is an upcoming 2015 American science fiction action film directed by Alan Taylor. You can find out more by http://www.imdb.com</p>
In which case I still only want to replace the tag. I don't want to touch the actual anchor text used even though it is a URL.
So how could I rewrite this Regex
#REReplaceNoCase(myStr, "(\bhttp://[a-z0-9\.\-_:~###%&/?+=]+)", "\1", "all")#
the other way round, where its selecting tags and replacing them with my modified text?
If you're willing, this is a really easy task for jQuery (client-side)
JSFiddle: http://jsfiddle.net/mz1rwo0u/
$(document).ready(function () {
$("a").each(function(e) {
if ($(this).attr('href').match(/^https?:\/\/(www\.)?imdb\.com/i)) {
$(this).attr('rel','nofollow noreferrer');
}});
});
(If you right click any of the imdb links and Inspect Element, you'll see the rel attribute is added to the imdb links. Note that View Source won't reflect the changes, but Inspect Element is the important part.)
If you want to effect every a link, you can do this.
$(document).ready(function () {
$("a").each(function(e) {
$(this).attr('rel','nofollow noreferrer');
});
});
Finally, you can also use a selector to narrow it down, you might have the content loading into a dom element with the id contentSection. You can do...
$(document).ready(function () {
$("#contentSection a").each(function(e) {
if ($(this).attr('href').match(/^https?:\/\/(www\.)?imdb\.com/i)) {
$(this).attr('rel','nofollow noreferrer');
}});
});
It's a bit tougher to reliably parse this in cold fusion without the possibility of accidentally adding it twice (without invoking a tool like jSoup) but the jQuery version is client-side and works by obtaining data from the DOM rather than trying to hot-wire into it (a jSoup implementation works similarly, creating a DOM-like structure you can work with).
When talking about client-side vs server-side, you have to consider the mythical user who doesn't have javascript enabled (or who turns it off with malicious intent). If this functionality is not mission-critical. I'd use JQuery to do it. I've used similar functionality to pop an alert box when the user clicks an outside link on one of my sites.
Here's a jSoup implementation, quick and dirty. jSoup is great for how it selects similarly to jQuery.
<cfscript>
jsoup = CreateObject("java", "org.jsoup.Jsoup");
HTMLDocument = jsoup.parse("<A href='http://imdb.com'>test</a> - <A href='http://google.com'>google</a>");
As = htmldocument.select("a");
for (link in As) {
if (reFindnoCase("^https?:\/\/(www\.)?imdb\.com",link.attr("href"))) {
link.attr("rel","nofollow noreferrer");
}
}
writeOutput(htmldocument);
</cfscript>
Original
I want to parse a string of html code and add newlines after closing tags + after the initial form tag. Here's the code so far. It's giving me an error in the "re.sub" line. I don't understand why the regex fails.
def user():
tags = "<form><label for=\"email_field\">Email:</label><input type=\"email\" name=\"email_field\"/><label for=\"password_field\">Password:</label><input type=\"password\" name=\"password_field\"/><input type=\"submit\" value=\"Login\"/></form>"
result = re.sub("(</.*?>)", "\1\n", tags)
return dict(form_code=result)
PS. I have a feeling this might not be the best way... but I still want to learn how to do this.
EDIT
I was missing "import re" from my default.py. Thanks ruakh for this.
import re
Now my page source code shows up like this (inspected in client browser). The actual page shows the form code as text, not as UI elements.
<form><label for="email_field">Email:</label>
<input type="email" name="email_field"/><label
for="password_field">Password:</label>
<input type="password" name="password_field"/><input
type="submit" value="Login"/></form>
EDIT 2
The form code is rendered as UI elements after adding XML() helper into default.py. Thanks Anthony for helping. Corrected line below:
return dict(form_code=XML(result))
FINAL EDIT
Fixing the regex I figured myself. This is not optimal solution but at least it works. The final code:
import re
def user():
tags = "<form><label for=\"email_field\">Email:</label><input type=\"email\" name=\"email_field\"/><label for=\"password_field\">Password:</label><input type=\"password\" name=\"password_field\"/><input type=\"submit\" value=\"Login\"/></form>"
tags = re.sub(r"(<form>)", r"<form>\n ", tags)
tags = re.sub(r"(</.*?>)", r"\1\n ", tags)
tags = re.sub(r"(/>)", r"/>\n ", tags)
tags = re.sub(r"( </form>)", r"</form>\n", tags)
return dict(form_code=XML(tags))
The only issue I see is that you need to change "\1\n" to r"\1\n" (using the "raw" string notation); otherwise \1 is interpreted as an octal escape (meaning the character U+0001). But that shouldn't give you an error, per se. What error-message are you getting?
By default, web2py escapes all text inserted in the view for security reasons. To avoid that, simply use the XML() helper, either in the controller:
return dict(form_code=XML(result))
or in the view:
{{=XML(form_code)}}
Don't do this unless the code is coming from a trusted source -- otherwise it could contain malicious Javascript.
I want to add a call to a onclick event in any href that includes a mailto: tag.
For instance, I want to take any instance of:
<a href="mailto:user#domain.com">
And change it into:
<a href="mailto:user#domain.com" onclick="return function();">
The problem that I'm having is that the value of the mailto string is not consistent.
I need to say something like replace all instances of the '>' character with 'onclick="return function();">' in strings that match '<a href="mailto:*">' .
I am doing this in ColdFusion using the REreplacenocase() function but general RegEx suggestions are welcome.
The following will add your onclick to all mailto links contained withing a string str:
REReplaceNoCase(
str,
"(<a[^>]*href=""mailto:[^""]*""[^>]*)>",
"\1 onclick=""return function();"">",
"all"
)
What this regular expression will do is find any <a ...> tag that looks like it's an email link (ie. has an href attribute using the mailto protocol), and add the onclick attribute to it. Everything up to the end of the tag will be stored into the first backreferrence (referred to by \1 in the replacement string) so that any other attributes in the <a> will be preserved.
If the only purpose of this is to add a JavaScript event handler, I don't think Regex is the best choice. If you use JavaScript to wire up your JavaScript events, you'll get more graceful degradation if JS is not available (e.g. nothing will happen, instead of having onclick cruft scattered throughout your markup).
Plus, using the DOM eliminates the possibility of missing matches or false positives that can occur from a Regex that doesn't perfectly anticipate every possible markup formation:
function myClickHandler() {
//do stuff
return false;
}
var links = document.getElementsByTagName('a');
for(var link in links) {
if(link.href.indexOf('mailto:') == 0) {
link.onclick = myClickHandler;
}
}
Why wouldn't you do this on the frontend with a library like jQuery?
$(function(){
$("a[href^=mailto]").click(function(){
// place the code you want to execute here
})
});
I want to extract the image url from any website. I am reading the source info through webRequest. I want a regular expression which will fetch the Image url from this content i.e the Src value in the <img> tag.
I'd recommend using an HTML parser to read the html and pull the image tags out of it, as regexes don't mesh well with data structures like xml and html.
In C#: (from this SO question)
var web = new HtmlWeb();
var doc = web.Load("http://www.stackoverflow.com");
var nodes = doc.DocumentNode.SelectNodes("//img[#src]");
foreach (var node in nodes)
{
Console.WriteLine(node.src);
}
/(?:\"|')[^\\x22*<>|\\\\]+?\.(?:jpg|bmp|gif|png)(?:\"|')/i
is a decent one I have used before. This gets any reference to an image file within an html document. I didn't strip " or ' around the match, so you will need to do that.
Try this*:
<img .*?src=["']?([^'">]+)["']?.*?>
Tested here with:
<img class="test" src="/content/img/so/logo.png" alt="logo homepage">
Gives
$1 = /content/img/so/logo.png
The $1 (you have to mouseover the match to see it) corresponds to the part of the regex between (). How you access that value will depend on what implementation of regex you are using.
*If you want to know how this works, leave a comment
EDIT
As nearly always with regexp, there are edge cases:
<img title="src=hack" src="/content/img/so/logo.png" alt="logo homepage">
This would be matched as 'hack'.