i'm using an ng-repeat directive to show a list of posts,
retrieved through a wordpress-json-api.
i have problems with some characters, as the output of wp-json-api escapes some of them.
myjson :
{
"id": 1,
"type": "mynicetype",
"slug": "myniceslug",
"title": "It’s a strange char" //my apostrophe got changed
... }
and my markup:
<li ng-repeat="post in menu.posts | filter:searchText | filter:query" >
<h4 >name : {{post.title}}</h4>
</li>
get rendered (obviously-awfully) as
name : It’s a strange char
What's the best approach for formatting these html numbers? (before assigning the json.success data to the scope or, more easily, on the fly, inside template? but how?)
(btw i don't get the reason why an apostrophe should receive a special treatment by a json-api, but i could really be misunderstanding something here)
Thanks for any clarification
Related
I am dealing with some JSON-LD data in MarkLogic and have trouble using XPath on property names with "#" symbol. For example:
{
"#type": "News",
"title": "some title",
"description": "some description"
}
My goal is to retrieve the title if the type is "News". I understand "#" is reserved to represent attribute in XPath, so something below should not work.
doc.xpath('.[#type="News"]/title')
With the xdmp.encodeForNCName function, I see the "#" symbol is represented as _40_ in the JSON representation. But it still doesn't work.
doc.xpath('.[_40_type="News"]/title')
While using fn:name() would work too, as suggested by the other answers, you can address nodes with funny spelling in MarkLogic XPath directly too. Probably a deviation from the official XPath standard itself, but MarkLogic allows writing expressions like:
doc.xpath('node("#type")[. eq "News"]/title'
Very useful for JSON properties containing spaces and such as well..
HTH!
You could test the name() in a predicate:
doc.xpath('.[*[contains(name(), "#type")] = "News"]/title')
Here is the dirty solution.
.[#*[name() = '#type']][#*='News']/title
I know you are working with json, but I just checked the xpath in html with similar attribute and value combination. You can see the xpath considered both attribute name and value (as it's not selecting other node with the same name but different value).
Something's been puzzling me for the better half of a workday now: What's actually going on during markdown to HTML conversion in Dita when I try to keep brackets intact.
Specifically, this is my original markdown:
1. Value[:, :]
Which should be written as-is in HTML. However, looking at the HTML element produced by Dita:
<li class="li">
<p class="p">
Value
<span class="xref"></span>
</p>
</li>
Expected output:
<li class="li">
<p class="p">
Value[:, :]
</p>
</li>
Which means the brackets are interpreted as an external references (?)
I produce my markdown to HTML conversion in dita CLI, version 3.1.2 (windows 10), with the following command:
dita --input=root.ditamap --output=./output --format=html5
The root.ditamap simply contains a single topic that is my markdown file.
I tried at the following first:
1) Using \ to escape the string, results in:
1. Value\[:, :\]
2) using html entity in-place of brackets ([ and ]) results in: 1. Value:, :
3) using UTF code in-place of brackets ([ and ]) results in:
1. Value:, :
Then I tried to add more brackets there and it worked!
4) Markdown that worked: 1. Value[[]:, :[]] produced expected output 1. Value[:, :]
My question(s):
1) Which of the three pieces is responsible for this behaviour: Markdown, Dita or HTML? (with this behaviour I mean the interpretation of brackets in a way that made them disappear during the original conversion).
2) Is there a "better"/"universal" way to escape strings in markdown -> html by dita? (By better way I mean something that will leave the original markdown's string meaning the same, and by universal I mean something that can be applied to all strings not only brackets)
At the very least I hope my findings will be useful to someone, even though I realize my use-case is very specific. :)
The variable strCSSClass often has a value but sometimes is empty.
I do not want to include an empty class="" in this input element's HTML, which means if strCSSClass is empty, I don't want the class= attribute at all.
The following is one way to do a conditional HTML attribute:
<input type="text" id="#strElementID" #(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) />
Is there a more elegant way of doing this? Specifically one where I could follow the same syntax as is used in the other parts of the element: class="#strCSSClass" ?
You didn't hear it from me, the PM for Razor, but in Razor 2 (Web Pages 2 and MVC 4) we'll have conditional attributes built into Razor (as of MVC 4 RC tested successfully), so you can write things like this:
<input type="text" id="#strElementID" class="#strCSSClass" />
If strCSSClass is null then the class attribute won't render at all.
Further Reading
Jon Galloway - ASP.NET MVC 4 Beta Released!
Conditional Attributes in Razor View Engine and ASP.NET MVC 4
Note you can do something like this(at least in MVC3):
<td align="left" #(isOddRow ? "class=TopBorder" : "style=border:0px") >
What I believed was razor adding quotes was actually the browser. As Rism pointed out when testing with MVC 4(I haven't tested with MVC 3 but I assume behavior hasn't changed), this actually produces class=TopBorder but browsers are able to parse this fine. The HTML parsers are somewhat forgiving on missing attribute quotes, but this can break if you have spaces or certain characters.
<td align="left" class="TopBorder" >
OR
<td align="left" style="border:0px" >
What goes wrong with providing your own quotes
If you try to use some of the usual C# conventions for nested quotes, you'll end up with more quotes than you bargained for because Razor is trying to safely escape them. For example:
<button type="button" #(true ? "style=\"border:0px\"" : string.Empty)>
This should evaluate to <button type="button" style="border:0px"> but Razor escapes all output from C# and thus produces:
style="border:0px"
You will only see this if you view the response over the network. If you use an HTML inspector, often you are actually seeing the DOM, not the raw HTML. Browsers parse HTML into the DOM, and the after-parsing DOM representation already has some niceties applied. In this case the Browser sees there aren't quotes around the attribute value, adds them:
style=""border:0px""
But in the DOM inspector HTML character codes display properly so you actually see:
style=""border:0px""
In Chrome, if you right-click and select Edit HTML, it switch back so you can see those nasty HTML character codes, making it clear you have real outer quotes, and HTML encoded inner quotes.
So the problem with trying to do the quoting yourself is Razor escapes these.
If you want complete control of quotes
Use Html.Raw to prevent quote escaping:
<td #Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )>
Renders as:
<td rel='tooltip' title='Drilldown' data-container='.drillDown a'>
The above is perfectly safe because I'm not outputting any HTML from a variable. The only variable involved is the ternary condition. However, beware that this last technique might expose you to certain security problems if building strings from user supplied data. E.g. if you built an attribute from data fields that originated from user supplied data, use of Html.Raw means that string could contain a premature ending of the attribute and tag, then begin a script tag that does something on behalf of the currently logged in user(possibly different than the logged in user). Maybe you have a page with a list of all users pictures and you are setting a tooltip to be the username of each person, and one users named himself '/><script>$.post('changepassword.php?password=123')</script> and now any other user who views this page has their password instantly changed to a password that the malicious user knows.
I guess a little more convenient and structured way is to use Html helper. In your view it can be look like:
#{
var htmlAttr = new Dictionary<string, object>();
htmlAttr.Add("id", strElementId);
if (!CSSClass.IsEmpty())
{
htmlAttr.Add("class", strCSSClass);
}
}
#* ... *#
#Html.TextBox("somename", "", htmlAttr)
If this way will be useful for you i recommend to define dictionary htmlAttr in your model so your view doesn't need any #{ } logic blocks (be more clear).
Is there a way like in xml to add a html tag to json string data.
Example:
{"title": "bla bla", "copy": "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium"}
In my example I use an a tag to wrap some text. In xml I could just use a ctata tag to wrap the entire text.
UPDATE:
Ok so from some of your answers it looks like Json is not the route to go for data that will have html tags in it. What would be a better solution. My html pages have some simple FAQ links. When the user clicks them it will load the approperate data which would be the title and the description. All I'm trying to do is simply have a user click some FAQ titles and then it will show a popup that will be sent the page ID which I was using as my json IDS. Right now it works great with the json data but I can't add html links to the description data.
For example:
{
"intro": [
{"title": "title text", "description": "description text1"},
{"title": "title text", "description": "description text1"}
]
}
In the above example, intro is the page ID. So it can grab this array and find its appropriate title and description. After I did this I noticed some of the copy in the descriptions would have html links in them. Can anyone let me know what would be a better solution to how I setup my external data.
You could call the Javascript escape() function before inserting into your JSON. Then call unescape() on the other end.
escape() on W3Schools website
JSON is just a string, so a simple string manipulation would do the trick. You'd have to be VERY careful to not introduce any syntax errors, however. Simply adding <a href="index.php"> would break the string, as the " are JSON metacharacters. you'd have to insert <a href=\"index.php\">, and probably even double-escape those quotes, depending on how you're doing things.
If you're doing your own JSON serialization (and in most contexts you probably don't want to, but that depends on which langauge you're using), you should start by being familiar with the grammar presented on http://www.json.org/. It tells you right on the front page that double quotes in strings can be escaped with backslashes as \".
I know I'm a bit late to the party, but this is what did it for me! The "render" function takes my data in the JSON key "data" and returns the data in "dataname" as well as my desired html tag (span).
{
"data": "dataname", render: function (data) {
return data + '<span></span>';
}
},
"Other data keys to follow"
{
},
If you are trying to put a link in a json string all you need to do is write your link normally as you would in an html but instead of enclosing the href in double quote use single quote. For example
{"name": "<a href='talk.php'>Talk</a>"}
I have been looking for a way to capture structured text (sections, paragraphs, emphasis, lists, etc.) in JSON, but I haven't found anything yet. Any suggestions? (Markdown crossed my mind, but there might be something better out there.)
How about something like this:
[ { "heading": "Foobar Example" },
{ "paragraph":
[
"This is normal text, followed by... ",
{ "bold": "some bold text" },
"etc."
]
}
]
That is:
use a string for plain text without formatting or other mark-up;
use an array whenever you want to indicate an ordered sequence of certain text elements;
use an object where the key indicates the mark-up and the value the text element to which the formatting is applied.
HTML is a well-established way to describe structured text, in a plain-text format(!). Markdown (as you mentioned) would work as well.
My view is that your best bet is probably going to be using some sort of plain-text markup such as those choices, and place your text in a single JSON string variable. Depending on your application, it may make sense to have an array of sections, containing an array of paragraphs, containing an array of normal/bold/list sections etc. However, in the general case I think good old-fashioned blocks are markup will ironically be cleaner and more scalable, due to the ease of passing them around, and the well-developed libraries for full-blown parsing if/when required.
There also seems to be a specification that might accomplish this Markdown Syntax for Object Notation (MSON)
Not sure if for you it's worth the trouble of implementing the spec, but it seems to be an option.