Handlebarsjs Templates & using html content - handlebars.js

So, I've got a fairly straightforward handlebars template which an element that looks like this:
<div>
{{include_text}}
</div>
I am trying to insert some html like:
<table>
....lots of table stuff
</table>
When I use the table with the template, what I get looks like:
<div>
<table>
... lots of table stuff
</table>
</div>
and I want:
<div>
<table>
....lots of table stuff
</table>
</div>
Is this possible? If so, how?

Handlebars (and Mustache) escape the double Mustaches.
Use triple ones
{{{include_text}}}
From the official GitHub:
By default, the {{expression}} syntax will escape its contents. This helps to protect you against accidental XSS problems caused by malicious data passed from the server as JSON.
To explicitly not escape the contents, use the triple-mustache ({{{}}}).
Note, the escaping isn't "just there", if your output contains user-entered data, not-escaping might enable them to perform XSS.

Related

How do you select this text above the HTML table using XPath?

Below is the HTML I'm working with. I've removed some lines that aren't relevant to this question, such as the content within the table.
My objective is to capture the names, and the corresponding information found within the table. Each Name/Table combination would be one row.
<div class="row">
<div class="col-sm-4 col-md-4">
<span class="LIST_TITLE">
Contact Person
</span>
</div>
<div class="col-sm-6-left" style="display: table-cell;">
Name A
<table>
</table>
Name B
<table>
</table>
</div>
</div>
I currently have this XPath '//div[#class="row"]/div/span[#class="LIST_TITLE"][contains(text(),"Contact Person")]/ancestor::div/div[#class="col-sm-6-left"]/table', which I am able to loop over to extract out the information in the table.
My issue is how to capture the name for each table, which I am finding difficult as they're both contained within the same tag.
I have tried using './ancestor::div[1]/text()', though this will capture both names.
Any help is greatly appreciated
preceding-sibling::text()[1] will return the text node prior to the context node. If the table elements are used as the context node, that will return you the following text nodes:
Name A
and
Name B
NB I don't know what web scraping tool you are using, but I know that some of them have XPath APIs that won't return text nodes; only elements. If that's the case for you, you might need to switch to a different XPath API that is capable of returning text nodes, e.g. lxml https://lxml.de/xpathxslt.html#xpath

HtmlAgilityPack - Leave markup exactly as inputted

Is there a way to set HtmlAgilityPack to leave the markup exactly as it was inputted? My issue is that I allow users to set the html layout of a data output on their website. The format they use is similar to ASP.NET's repeater control.
Take the following example:
<table>
<ItemTemplate>
<tr>
<td>
<div>Item Markup</div>
</td>
</ItemTemplate>
<AltItemTemplate>
<td>
<div>Alternate Item Markup</div>
</td>
</tr>
</AltItemTemplate>
</table>
When I load this into HtmlAgilityPack, it will add the closing tr tag to the ItemTemplate and remove the actual closing tr tag from the AltItemTemplate. Later in the processing, the <ItemTemplate></ItemTemplate> and the alternate tags are removed, which would result in valid html. When HtmlAgilityPack loads this in, it will not result in valid html.
I can and have successfully parsed this via string manipulation, however, I thought if I could use HtmlAgilityPack then it would be more efficient and easier to work with.
Anyone know if I can use HtmlAgilityPack to do this? or if I should just stick with the string manipulation (.NET's substring, indexof, remove, etc).
Short answer is no. If you need to manipulate the content as a DOM, the HTML has to be correctly nested.
However, if you can live with all TR content as pure text (not DOM), than you could add this at the beginning of your processing:
ElementsFlags.Add("tr", HtmlElementFlag.CanOverlap | HtmlElementFlag.Empty);
But like if say, if you do this, everything between TR tags will be seen as text data, not as a DOM tree, so for example, you won't be able to do XPATH queries on the child DIV nodes.
Well to tell HTMLAgilityPack to not try to fix the tags closers, you need to remove the tag from the elements flags:
dim hp as HtmlDocument
hp.LoadHTML(htmlcode)
hp.DocumentNode.ElementsFlags.Remove("tr")
Now check the hp.DocumentNode and you will see that HTMLAgilityPack didnt attempt to fix the tags closers
Dim dnode As HtmlAgilityPack.HtmlNode = hp.DocumentNode
dim tosee as strin = dnode.OuterHTML

Combine code with info from databound item in ASP.NET markup code blocks

Man, I never really learnt all the embedded code blocks and stuff you can use in ASP.NET. What I'm trying to do is the following:
I have a repeater
It renders a table
In each row, I need to add a data-bind attribute (yes, for Knockout) containing some text and the rowindex.
More specifically, I want to render:
<table>
<tr data-bind="with:myItems()[0]">
...
</tr>
<tr data-bind="with:myItems()[1]">
...
</tr>
<tr data-bind="with:myItems()[2]">
...
</tr>
</table>
I've tried:
data-bind="<%# String.Format("myItems()[{0}]", Container.ItemIndex) %>"
But that doesn't work (data-bind="<%# Container.ItemIndex %> will however. So I'm trying to combine code with information from the databound item.
I know there is a foreach binding in Knockout, but I can't use it because:
I want/need my HTML to be constructed server-side initially
There's other, specific javascript that needs the HTML to exist already so I can't let Knockout populate the table
I'm using an ASP.NET Repeater, which doesn't mix well with Knockout's templates.
I also know, I could just do this in code-behind (with <tr runat="server" ... >) but I'm trying to put all my layout and javascript in markup and js files, not in C# code.
So, can I, in some way, add code in my markup to combine text I choose, with info from the current databound item?
Bummer, apparently, the answer is dead simple, and it didn't work the first time because of another mistake I made:
<tr data-bind="with: myItems()[<%# Container.ItemIndex %>]">
I put more info on my Blog and a working example on GitHub.

Is it possible to 'turn off' indentation in asp.net controls?

When I use built-in controls in asp.net I can see many tab characters added at start of each line of the generated html output. Is it possible to 'turn of' these? I'd like to get rid of this waste.
For example when I use GridView control, it generates <table> tag which looks like this:
<div>
<table>
<tr>
<th>...</th>
</tr>
<tr>
<td>...</td>
</tr>
...
</table>
</div>
But I want to see this:
<div>
<table>
<tr>
<th>...</th>
</tr>
<tr>
<td>...</td>
</tr>
...
</table>
</div>
I wonder who designed this silly stuff. Although it is "just a few bytes", it sends many unneeded waste over internet if you look at it from a long time period point of view. (I understand that indentation makes it more readable, but still at least those inner <th> and <td> tags are a bit too much indented.)
Or do you think I am completely wrong? [Are those tabs important for The World?]
I wonder who designed this silly stuff
Microsoft Corporation.
Or do you think I am completely wrong?
I think you are completely wrong. HTML is to be read and interpreted by browsers. You, as a developer, could use developer tools such as FireBug to inspect the actual DOM tree in a nice way. Humans/users don't give a s..t about how your HTML is indented. They look at the final product rendered by the browser and this is what you should be focusing on. Actually in production in order to optimize bandwidth you should compress your HTML and remove all white-spaces. Could be done with custom response filters.
Personally, when I write a page (I use the Repeater control, so there's a bit of a difference), I always indent my HTML. Yes, even the content within the <th> and <td> tags.
I can understand your point (especially when we talk about using gzipped and minified copies of JavaScript libraries) when you're talking about a production application that's never debugged. However, without HTML indentation, it would be incredibly difficult for me to unwind problems in my layout or errors I made when I wrote CSS or HTML properties.

How can I write code in the code-behind file for my ASP.NET 2.0 page that hides table rows without changing the IDs of the child elements?

I'm stumped by a seemingly simple problem. In my ASP.NET page, I have a table which has a few rows that need to be shown or hidden conditionally from the back end. Sounds simple, right?
What I tried is something like this in the front-end code:
<table>
<tr>
<td id="demorow1">
<p>This row always shows up!</p>
</td>
</tr>
<tr id="conditionalrow" runat="server">
<td id="formoptionsrow">
<!-- This row contains a number of form elements that should only SOMETIMES be shown, as determined by the back-end code. -->
</td>
</tr>
</table>
And in the code-behind file I just do this to hide the code:
conditionalrow.Style["display"] = "none";
This makes the row disappear as intended. I don't mind that it's just invisible, it won't hurt anything. However, this has the side-effect of making several HTML form elements inside of conditionalrow gain ASP.NET's convoluted IDs and NAMEs. This throws off a lot of Javascript functions related to the form that I don't have time to change or rework right now. I need to be able to hide the form (or remove it from the code entirely) from the code behind file, but without changing the IDs and NAMEs of child elements.
I know there's some kind of setting in the newer versions of ASP.NET that allows you to override ASP.NET's ID reassignment. Unfortunately, I'm stuck with ASP.NET 2.0 and don't have the option of using anything newer for this project. What do you recommend?
Instead of making the row a server side control, use a code block to give it an appropriate CSS class.
<tr class="<%:VisibilityClass%>">
Where, in your code behind you have a VisibilityClass string property that return the CSS class name:
public string VisibilityClass
{
get
{
if(shouldBeVisible)
return "visible";
return "hidden";
}
}
You can also use functions if a property is not appropriate.
can you not do a conditionalrow.Visible = false;

Resources