I'm currently trying to develop an templating engine for expanding my custom markdown into full HTML.
I initially thought a recursive approach might work. This would use a tag stack to determine if you were inside another tag, and evaluating the logic of each tag when each are closed. I'm having trouble conceiving of a method that doesn't use indexOf over and over again, and that covers all custom directives I want to support.
Syntactically, it uses open and closing tags for each directive. For example:
#foreach(item in list)
<p>text</p>
#endforeach
Produces:
<p>text</p>
<p>text</p>
<p>text</p>
(if there were 3 items in the list)
#foreach(item in list)
<p>textA</p>
#endforeach
#foreach(item in list)
<p>textB</p>
#endforeach
Produces:
<p>textA</p>
<p>textA</p>
<p>textA</p>
<p>textA</p>
<p>textB</p>
<p>textB</p>
(if there were 3 items in each list)
#foreach(item in list)
#foreach(item in list)
<p>text_inside</p>
#endforeach
<p>text_outside</p>
#endforeach
Produces:
<p>text_inside</p>
<p>text_inside</p>
<p>text_inside</p>
<p>text_outside</p>
<p>text_inside</p>
<p>text_inside</p>
<p>text_inside</p>
<p>text_outside</p>
<p>text_inside</p>
<p>text_inside</p>
<p>text_inside</p>
<p>text_outside</p>
Initially, I was thinking about a recursive approach that would use a stack to know whether or not it was inside or outside some other tag. It dawned on me that this is a common function for compilers and as such there should be some popular parsing/compilation algorithm.
I came across the process that a compiler uses (Scanner -> Lexer -> Parser), and I assume that the process of tokenizing input is part of the lexical analysis, but I'm not sure if there is a common algorithm for breaking the code apart for the parser to perform the final logical operation.
At this current point, I'm looking for direction in what method to research, not necessarily someone's implementation (although this might be useful to study).
Related
I use spring boot and thymeleaf. I have many entity and I need to create crud ui. All ui will be similar Is it possible to use reflection to reduce ui to generate?
I would like to loop on the fields and get value in the thymeleaf template
In these days I have been working on an issue very similar to yours.
I have discovered that Thymeleaf has this thing called preprocessing which allows you to have nested expression, so something like this works:
<p th:text="${__${'myObj.myField'}__}"></p>
In this situation, the expression __${'myObj.myField'}__ is evaluated first: after this preprocessing, the expression that will be evaluated by the <p> tag will become:
<p th:text="${myObj.myField}"></p>
Which is the desidered result. Note that, in the preprocessed expression, we are passing the field as a string: therefore, it should be totally possible to create a fragments with a th:each in it which accepts a list of strings in which each string is a field. This list could either be injected directly in the model through Java or could be statically declared in the Thymeleaf's markup. An example of such fragment could be:
<div th:fragment = "show-details">
<tr th:each = "field : ${fieldsToPrint}">
<td th:text = "${__${myObj + '.' + field}__}"></td>
</tr>
</div>
Which could, for example, be used like this:
<div th:replace = "myfragments :: show-details(fieldsToPrint = ${ {'name', 'surname'} }, myObj = ${objFromModel})"></div>
The list of fields could either be generate manually or through Java reflection.
This procedure still involves some work, but way less than creating by hand all the views, especially if you can show all the entities with the same show-details fragments. I have not got around to it yet, but it should be possible to use a similar pattern also for editing such entities.
I have odata coming from backend. I have two select controls on my SAPUI5 page. The first select displays a list of items received from the backend. The second select changes depending on what is selected from the first select control.
Right now I am constructing in the controller a new path for "planets" select. Is it possible to change the "planets" items path depending on the "stars" selected item just in the XML? Without using Javascript?
I would like to do something like this:
<Select id="stars"
items="{
path: '/Stars'
}">
<core:Item key="{StarID}" text="{StarName}" />
</Select>
<Select id="planets"
items="{
path: '("/Stars('" + StarID + "')/toPlanets"'
}">
<core:Item text="{PlanetName}" />
</Select>
Unfortunately, I do not believe that there is any existing functionality to do something like this naively in UI5. The only thing that is similar is binding replacement during XML preprocessing, but you cannot use that for your situation.
I have met this situation a lot of times in the past and have created a helper control for dealing with this (might not be the perfect solution, but it works). It only makes sense to use a similar approach if you have this kind of construct in multiple places (so you avoid having the same boilerplate code in your JS controllers).
You can find here an example implementation of such a control and here an example usage. Basically this allows you to have a reusable mechanism for doing such an "indirect binding" without resorting to event listeners.
I have the follow angular expression in my page and the associated dart function.
<ul>
<li ng-repeat="name in ctrl.getNames()">{{name}}</li>
</ul>
.
List<String> getNames() {
print('ng-repeat triggered');
return ['john', 'smith', 'david'];
}
The problem is by clicking anywhere on the page, or re-sizing the browser window, I would see 'ng-repeat triggered' being printed to my dartium console.
My question is what triggers angular to re-evaluate the expression, the above made it seems like any action on the page will trigger the re-evaluation.
Second, is there a way to reduce the frequeny or control when the angular expression will be evaluated?
Thanks
This is how Angular does change detection. I haven't seen anything about how to influence it.
A new change detection algorithm is on the way AngularDart change detection (I haven't read it myself yet)
In Razor (MVC 4) can I do something like the following (pseudo)code?
<div id="One" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
<div id="Two" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
My intention is, that in DIV "One" an additional attribute will be written, but not in DIV "Two"
So, the THIS_ID_IS(string id) should determine, if the Razor-Parse is INSIDE the given DIV with id="xyz"
Is this possible?
You can use single line if statement to overcome this situation
<div id="One" #(THIS_ID_IS("One") ? "write something" : "") ></div>
Since ids are unique values. All divs will have diffrent ids.
So I dont think there is any need for Conditional Check in razor.
You can Directly add the extra attributes to your Div as follows
<div id="One" attribute-name="Value"></div>
In situations like this I tend to write a helper method to output the markup. This way you a not constrained by the 'rules' of razor. I did a similar thing to output jQuery slider html inside a div.
It also depends on your target audience, I rarely produce the actual views as our designer does most of that. I don't like handing over stuff to the 'creatives' that requires them to write/understand the logic.
It may not be the ideal solution or maybe even overkill in your situation but may be worth a look.
http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs
As much as I would like it to be possible. It looks like it's not the case.
Based on these two articles :
Simple
In depth
It would seem that the Razor engine combines a code and a markup parser.
The main parser decides to use one or the other.
So the parsers are not aware of one another.
Simply put, in your example, <div id="One"></div> and #if(THIS_ID_IS("One")) would be parsed in different scopes and then just concatenated together.
I can have tags inside option tags, and it works (don't know if it's valid HTML4/5, but it works in Firefox at least):
<select>
<option><i class="icon-plus"></i>Add item</option>
<option><i class="icon-remove"></i>Remove item</option>
<option><i class="icon-edit"></i>Edit item</option>
</select>
I'm placing Bootstrap/FontAwesome webfont icons in those option tags.
But I'm using MVC4/Razor, and I can't get the correct syntax to make it render properly. It encodes all those inner tags and I get <, >, etc.
This is what I'm doing:
// first I make a new list with the icons inside
var items = Model.Items.Select(q => new SelectListItem() {
Selected = q.Selected,
Text = "<i class=\"icon-add\"></i>" + q.Text,
Value = q.Value
});
// then render the dropdown
Html.DropDownListFor(m => m.SelectedItem, items, "All")
How do I get this working?
You can't do this out of the box. Depending how often you need to use it - I personally would recommend doing it manually via a loop.
If you want, you could write an extension method/helper for the drop down list.
I found a similar example here, though this guy uses it to custom the 'select' tag, you'll want to custom the 'options' tag: Fun (?) with Linq Expressions in extension methods
Hope this helps.
OK I've selected an easy easy option...
Simply put the FontAwesome classes on the <option> tag instead of a nested child <i> tag. That way the markup is valid.
Of course this needs to be done manually in a loop.