Use of #{if-else} tags in PLAY templates - html

I am working since last few months with PLAY 1.2.5 using Java and HTML for views. I am aware of using JAVA code in PLAY templates using %{ if ------else}% (kind of as we use scriplets in J2EE. But now I came across use of tags like #{if}---{/if}. I searched around and found that this also is a way of using if-else. But my query is that in a similar piece of code I saw the following:
#{if some variable value in Controller == 'true'} ------- #{/if} #{else}------ #{/else} .
Now I don't understand how this Controller variable is accessed in controller within these tags. I have looked around and found that no such variable was rendered by render() or renderArgs() from the controller.
Is there any other way of using those variables/methods on templates which are declared in controllers or model for that matter?

Related

Extend Markdown Parser to render custom code blocks

I am building a static blog, which uses Marked to parse markdown. I want to be able to have code blocks with tabs.
I want to parse code that looks like this:
```JavaScript
var geolocation = require("nativescript-geolocation");
```
```TypeScript
import geolocation = require("nativescript-geolocation");
```
To something like this (from the angular2 docs), where the tab names would be JavaScript and TypeScript.
I am programming in JavaScript (nodeJs), so I could manually render this if required? What would a custom implementation of a code block tab look like?
I am not sure if there is a special name for these, as I can't really seem to find any examples or templates.
I think answer is: 'Marked' does not support custom tags. I've spend few hours trying to find some way to extend it and finally switched to showdown.
It appears to be really easy to implement one ( her is expandable section tag example ).
Extension 'showdownjs/prettify-extension' implements code highlighting using Google Prettify.

How to use Thymeleaf th:text in reactJS

I am running a springboot application with Thymeleaf and reactJS. All the HTML text are read from message.properties by using th:text in the pages, but when I have th:text in reactJS HTML block, reactJS seems angry about it.
render() {
return (
<input type="text" th:text="#{home.welcome}">
)
}
The error is:
Namespace tags are not supported. ReactJSX is not XML.
Is there a walkaround besides using dangerouslySetInnerHTML?
Thank you!
There is no sane workaround.
You are getting this error because Thymeleaf outputs XML, and JSX parsers do not parse XML.
You did this because JSX looks very, very similar to XML. But they are very, very different, and even if you somehow hacked Thymeleaf to strip namespaced attributes and managed to get a component to render, it would be merely a fleeting moment of duct-taped-together, jury-rigged code that will fall apart under further use.
This is a really, really bad idea because JSX is Javascript. You are generating Javascript on the fly. Just to name a few reasons this will not work in the long term:
This makes your components difficult if not impossible to test.
Reasoning about application state will be a nightmare as you will struggle to figure out if the source of a certain state is coming from Thymeleaf or JS.
Your application will completely grind to a halt if Thymeleaf outputs bad JS.
These problems will all get worse with time (Thyme?) as as developers abuse the ease with which they can render server-side data to the client-side, leading to an insane application architecture.
Do not do this. Just use Thymeleaf, or just use React.
Sample Alternative: I primarily work on a React application backed by a Java backend. So I understand how someone could stumble upon this hybrid and think it might be a good idea. You are likely already using Thymeleaf and are trying to figure out how you can avoid rewriting your servlets but still get the power of React.
We were in a similar boat two years ago, except with an aging JSP frontend, but the difference is negligible. What we did (and it works well) is use a JSP page to bootstrap the entire React application. There is now one JSP page that we render to the user. This JSP page outputs JSON into a single <script> tag that contains some initial startup data that we would otherwise have to fetch immediately. This contains resources, properties, and just plain data.
We then output another <script> that points to the location of a compiled JS module containing the entire standalone React application. This application loads the JSON data once when it starts up and then makes backend calls for the rest. In some places, we have to use JSP for these, which is less than ideal but still better than your solution. What we do is have the JSP pages output a single attribute containing JSON. In this way (and with some careful pruning by our XHR library) we get a poor man's data interchange layer built atop a JSP framework we don't have time to change.
It is definitely not ideal, but it works well and we have benefited vastly from the many advantages of React. When we do have issues with this peculiar implementation, they are easy to isolate and resolve.
It is possible wrap ReactJS apps in Thymeleaf. Think if you want a static persistent part (like some links, or even just displayed data), you could use Thymeleaf. If you have a complicated part (something that requires DOM repaints, shared data, updates from UI/Sockets/whatever), you could use React.
If you need to pass state you could use Redux/other methods.
You could have your backend send data via a rest API to the React part and just render your simple parts as fragments or as whole chunks of plain HTML using Thymeleaf.
Remember, Thymeleaf is really just HTML. React is virtual DOM that renders as HTML. It's actually fairly easy to migrate one to the other. So you could write anything "Static" or that does not respond much to UI, in Thymeleaf/HTML. You could also just render those parts in React too, but without State.
Thymeleaf 3 allows you to render variables from your Java to a separate JS file. So that is also an option to pass into JSX
function showCode() {
var code = /*[[${code}]]*/ '12345';
document.getElementById('code').innerHTML = code;
}
Now you can use data- prefix attributes (ex. data-th-text="${message}").
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#support-for-html5-friendly-attribute-and-element-names

specifying html markup when using Laravel scaffolding

Ive built the all the views (html, css, jquery) for a web app and now im starting work on the back end, using Laravel / Mysql.
I recently came across scaffolding in Laravel, similar to Ruby on Rails, which is great, but the forms ive built for my views all contain special classes and markup is there a way to specify the classes and other markup to be applied to form when using scaffolding ?
If I got you correctly, you can set an extra variable on controller, or check URI or route on views, and specify extra classes by looking to the view.
E.g: In the controller, you can do something like this:
return View::make('views.myview')->with('type','form');
And in the view, you can use simple if clause(s):
#if(isset($type))
<div class="{{$type}}">
#else
<div class="default">
#endif
For adding extra markup and assets to views, I use teeplus/asset, which is ported from Laravel 3 to 4 (old habits die hard :)).
packagist URL
documentation

Passing Razor Markup to view and process it

I've searched the internet for days now with no luck finding this.
My model has a property which holds a chunk of html containing Razor markup.
exmaple:
public class ViewModel
{
public string Content = "<div>#Html.TextBox(\"UserName\")</div>";
}
In the view, I display that with
#Html.Raw(Server.HtmlDecode(Model.Content).toString())
I need to be able to convert the Razor markup into html, although because the Content is dropped in through the model, the view engine doesn't process it.
I have tried simply dropping in the Content, using just .Raw(Model.Content), .Encode(Model.Content), nothing works.
Any thoughts?
You could use the RazorEngine package which allows you to parse and execute Razor code. This being said I would not recommend you giving your users the power of editing directly Razor templates. You are opening a huge security hole in your website.
There are other templating engines such as DotLiquid for example which are better suited for scenarios where you don't trust user input.

Multiple views for 1 controller - Play Framework [duplicate]

If i want to have a common piece of UI across multiple pages, such as a menu, what is the recommended way to do this?
It would contain both template code and a back-end controller (similar to "snippets" in the LiftWeb framework).
I am aware that there is a menu module for Play, but I'm more interested in how this would be achieved in general.
There are two ways to include common view code into the Play Framework.
You can use the #{include} tag or the #{extends} tag.
The extends tag, as the name suggests, extends from a parent view. The extends tag is used by default in the skeleton code set up by Play when you create a new application. It extends the main.html. You add your code here.
The includes tag, allows you to inject a common piece of view code into your templates at a specified point. This works in much the same was a php include/require, or jsp includes work.
The problem will come when your template code also requires data or logic from the model (via the controller). If this is the case, then you will need to use the #Before or #With notation in your controller to ensure that the common piece of controller code is executed each time. You can add any data to the renderArgs list, so that it is available for use within the view.
A simple example of using renderArgs would be.
#Before
private static void commonData() {
// do your logic here
renderArgs.put("menu", menu);
renderArgs.put("selected", selectedMenuItem);
}
the values you have put into renderArgs (menu and selected in the example) will be available just in the same way as if you passed them into the render method.