I'm running a Jekyll site that uses JSON as data in my _data folder. I'm looping through the file like normal doing things like {% for item in site.data.resources.items %} just fine. However, I'd like to parse YAML front matter that is within a string.
Example:
\n---\nblog: http://google.com\nbackground-img: http://www.ew.com/sites/default/files/i/2013/07/23/Dumb-and-Dumber.jpg\nbuttonText: Download\n---\n
How can I have Liquid parse this within my Jekyll site so I can use it like so:
<img src="{{background-img}}>Image
or something similar?
EDIT: To clarify, that string is in front matter format in a text file that I'm retrieving through an ajax call. So that string is the response I get back and the format won't be changing. My hope was that Liquid could somehow parse this string and look for a front matter type format. If not, I will revert back my JavaScript methods.
This is impossible.
Liquid/YML is being parsed while generating the site and your JSON string comes available long after the site has been generated: It only exists after the moment the JSON request for the string has been succesful.
However, you can use javascript, as you already mentioned. Simply split the string on \n for your key-value pairs and split on : for your key and value. Then use jQuery (or plain javascript) to write the results to the DOM.
Good luck!
Related
i've the following situation with Freemarker.
When returning to a page in .ftl i send from Java a parameter to the url, similar to "AAA% BBB#DDD.COM", in Java it is ok.
When looking at the Url it does instead Write : "AAA%25+BBB#DDD.COM" And then with the following code:
<#if myCase??>
value = ${user}
</#if>
It does write in my html field "AAA%" but not the remaining.
How can i try to solve this issue?
Thanks in advance.
EDIT: After further investigations i do see the code i put before does write this on the Html:
value="AAA%" BBB#CCC.com=""
EDIT2: Let'see if i can give you more informations, first of, here's the relevant Java code :
Map mapping = new HashMap();
if(user != null && !user.isEmpty()){
mapping.put("user",user); //EG: AAA% BBB#DDD.COM (Checked in debug)
}
I have an URL similar to : mysite.xx?user=AAA%25+BBB#DDD.COM so the user it's attached as query param of the url.
I do need to reuse the "user" param to repopulate the Form field relative to the username, this is not a valid email i know, but an alias system already installed by the customer does the aliasing system this way.
What could be the cause of the problem
Given your template:
<#if myCase??>
value = ${user}
</#if>
Output written by Freemarker in output-mode HTML results in following:
value = AAA% BBB#DDD.COM
Freemarker does not understand that (from your context) the value of user should be an attribute-value (assignment). Instead it treats the contents of string user as HTML itself (this could be complete HTML-source as input-field, single tags, etc.). It simply pastes the contents of the model at the position in your template where you have set the variable-interpolation ${user}.
The Freemarker-result is no valid HTML (attribute-value pair), because each attribute should adhere some naming-conventions (i.e. no special-characters). When the attribute has a value, it is followed by an equal-sign and this followed by the value enclosed in double-quotes.
So most browsers convert your result into a valid HTML attribute - actually two attributes: value="AAA%" and BBB#CCC.com="". Opened the output-HTML in Firefox, you will see this in Inspector (NOT IN the raw source-view):
<input type="text" value="AAA%" bbb#ddd.com="">
What is not the cause
FreeMarker is auto-escaping (escpecially when in OutputMode HTML) when it writes the final HTML.
#ddekany Thanks for your comment ! It made me reproduce and discover the real cause.
URL encoding/decoding
In Java you could even encode the string variable user. So it converts % (i.e. percent-sign followed by space) into %25+ which is valid to be used inside an URL.
Run this java snippet online on IDEONE to the effects of URL-encoding and URL-decoding.
Solutions
Use either of these solutions to get desired output by fixing the HTML-attribute value-assignment in your template:
(1) use double-quotes:
<#if myCase??>
value="${user}"
</#if>
(2) use some built-ins to transform the plain string-output:
Use some of FreeMarker's built-ins for strings. In your case you could append ?url to the variable-name and use double-quotes around your variable-interpolation within your template, e.g.:
<#if myCase??>
href="mailto:${user?url}"
</#if>
Caution: validate URL or email-address (even parts of it) as early as possible
BBB#DDD.COM is a valid email-address. But % and whitespaces are not allowed inside an email-address.
On the other side # is typically not part of an URL, except as part inside a query-param value. But your user (URL) does not start with http:// etc.
So depending on the use-case/purpose of your (so called URL) user with value AAA% BBB#DDD.COM it could finally represent part of an URL or email-address.
In your special case, said:
populate the form field relative to the username. Model-variable user does not contain a valid email-address. It is used in conjunction with an alias system already installed by the customer. So aliasing will work this way.
Let's suppose the end-user which does later edit the form-field is responsible of making it valid (or a script does this validation).
Anyway bear in mind that an internet-address (like URL/email) needs some validation:
either before written to the final HTML (using Java or Freemarker)
or after being further processed inside your web-page (using JavaScript).
Otherwise it could possibly not yield the desired effect.
See also
Related questions:
Is there any way to url decode variable on Freemarker?
Java URL encoding of query string parameters
I am attempting to extract information from the following HTML using Nokogiri and XPath.
<p>Friday, February 1<br><strong>Apple <br> Orange</strong></p>
e.xpath('./text()[following-sibling::br]')
Gives me the date just fine. I want to then grab the text inside the strong node and split on br. There may be many fruits separated by br or there may just be one with no br. I would ideally like to accomplish this in xpath instead of code since I'm essentially defining a bunch of parsers via JSON.
Right now I'm thinking that I should use the tokenizer function and pass the text in the strong tag. I thought that should look like this:
e.xpath('./strong[fn::tokenize(.,"<br>")]')
and have also tried
e.xpath('fn::tokenize(./strong,"<br>")')
but I am getting:
.../gems/nokogiri-1.5.6/lib/nokogiri/xml/node.rb:159:in `evaluate': Invalid expression: ./strong/text()[fn::tokenize(.,"br")] (Nokogiri::XML::XPath::SyntaxError)
I'm modeling my usage after the documentation for the method that the error occurs in (line 139):
node.xpath('.//title[regex(., "\w+")]',...
I have a unique scenario. There is a web application which is a simulator to check sending of data in XML and getting the data back in xml and verifying few details in xml.
Now the xml data which I am sending has a lot of details. In that xml I will have to insert a parameter which I have defined in my test. I am not able to get, how to send the data as parameter in the xml before sending it.
the xml structre looks like this
id='12345'><version>1.3.4<</version><accno>1234567890</accno>add<address details</> ..........
Now int this xml structure, I have parameterized <accno>1234567890</accno> ... Mean in begin of the script I am declaring accno='1234567890'
Now I want to using accno as parameter in the xml instead of the hard coded value in the xml. Please suggest how to do this.
XML is not regular, but context-free. Use a proper parser like Nokogiri instead of regex. See RegEx match open tags except XHTML self-contained tags.
As answer, as requested.
I will say editing xml, by regex is a bad idea.
but just to answer the direct question use gsub. eg.
str.gsub(/reg_match/, newstring)
but better way of doing it will be use of hpricot,
Or you can also use ruby templates.
require 'erb'
require 'ostruct'
data = {:accno => "1234567890"}
variables = OpenStruct.new(data)
template = "<id='12345'><version>1.3.4</version><accno><%= accno%></accno>"
res = ERB.new(template).result(variables.instance_eval { binding })
puts res
First identify the pattern, then replace it using gsub!
xml_data.gsub! (pattern, replacement)
http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html#String.gsub_oh
The fast way to do it is with gsub (like Rajkaran says). The right way to do it is rexml or some other xml library. Investment should be related to how much you will use this kind of thing in the future.
I'm creating JSON in an ExpressionEngine template and pointing the Ruby JSON library at the relevant URL. The template looks like this:
[
{exp:mylib:mytag channel="mychannel" backspace="1"}
{"entry_id":"{entry_id}","title":"{title}"},
{/exp:mylib:mytag}
]
When the tag returns data, everything is fine, my Ruby code works perfectly with the array of objects. However, when the tag returns no data (because there are no appropriate entries), Ruby complains that the json string is not the required 2 octets in length. I would expect the output to be [], i.e. an empty but valid JSON array. However, visiting the URL in Firefox/firebug and wget confirms that the response coming back from the URL is zero bytes in length, with status 200 OK.
I tested further by creating a template without tags and just a pair of empty square brackets, with the same result: zero bytes.
Is a pair of empty square brackets somehow a reserved token in the EE template language? Is there some clever optimisation going on that assumes that no-one could ever want a pair of square brackets in an html page?
Are you developing your own add-on, or using the built-in ExpressionEngine tags?
Using the native channel entries queries, you can use a if_no_results conditional tag to control what gets output when there are no matching results:
{exp:channel:entries channel="channel_name"}
{if no_results} ...{/if}
{/exp:channel:entries}
Many third-party add-ons also support the same type of {if_no_results} conditional.
You might also have a look at the third-party ExpressionEngine JSON add-on, which may be able to give you some inspiration on how to approach your situation.
I have an AJAX request that creates a 'post', and upon successful post, I want to get HTML to inject back into the DOM. Right now I'm returning a JSON array that details success/error, and when I have a success I also include the HTML for the post in the response. So, I parse the response as JSON, and set a key in the JSON array to a bunch of HTML Code.
Naturally, the HTML code is making the JSON array break -- what should I do to escape it (or is there a better way to do this?). I get an AJAX response with a JSON array like so:
[{response:"success"},{html:'<div class="this is going to break...
Thanks!
Contrary to what you're probably used to in JavaScript, ' can't begin a string in JSON. It's strictly a ". Single quotes work when you're passing JSON to JavaScript.. much like <br> works when you want to put an XHTML line break.
So, use " to open the HTML string, and sanitize your quotes with \".
json.org has more info WRT what you should sanitize. Though the list of special characters isn't long, it's probably best to use a library like Anurag suggests in a comment.
Apart from escaping double quotes as mention by BranTheMan, newlines also break JSON strings. You need to replace newlines with \n.
Personally I've found this to be enough:
// Don't know what your serverside language is, example in javascript syntax:
print(encodeJSON({
response : "success",
html : htmlString.replace(/\n/g,'\\n').replace(/"/g,'\\"')
}));