How to remove a parent element, but keep its children elements in Thymeleaf? - thymeleaf

I am working on an AngularJS Project hosted on a SpringBoot App with Thymeleaf, and I that need AngularJS to grab JUST the section element from another webpage via views and routing.
However, I can't figure out how to make it so that ThymeLeaf only gives the section element instead of the whole HTML page, while still allowing me to view the webpage as a natural template when developing.
So in the server it is stored as
<html>
<title>Don't keep this </title>
<body>
<section>
Keep this
</section>
</body>
</html>
But when AngularJS reads the page, Thymeleaf makes it read this:
<section>
Keep this
</section>

Yeah, this is pretty simple with fragments. If your html file looks like this:
<!-- whatever.html -->
<html>
<head>
<title>Don't keep this </title>
</head>
<body>
<section th:fragment="section">
Keep this
</section>
</body>
</html>
And your controller, like this:
#RequestMapping(value = "whatever.html", method = RequestMethod.GET)
public String get() {
return "whatever :: section";
// Where the string 'whatever' resolves to the template, and section
// resolves to the text in th:fragment.
}
It will return the html
<section>
Keep this
</section>

Related

Displaying dynamic content in webview UWP

I want to display product specification from an external service. To do that I have to pass the below JS string to Webview.
<!DOCTYPE html>
<html>
<body>
<div id="flix-minisite"></div>
<div id="flix-inpage"></div>
<script
type="text/javascript"
src="http://media.flixfacts.com/js/loader.js"
data-flix-distributor="12612"
data-flix-language="id"
data-flix-brand="Samsung"
data-flix-mpn="UA55JU6600KPXD"
data-flix-ean=""
data-flix-sku=""
data-flix-button="flix-minisite"
data-flix-inpage="flix-inpage"
data-flix-button-image=""
data-flix-fallback-language="e2"
data-flix-price=""
async>
</script>
</body> </html>
I've added the below method:
webview.NavigateToString("htmlString");
Adding this just displays the text from the service, but the images and videos are not getting displayed.
Expected result :
http://media.flixcar.com/delivery/minisite/show/12612/id/957752
What I'm I doing wrong?
For me, it doesn't work because the following script in not correctly added to your html page:
<script type="text/javascript" src="//media.flixcar.com/delivery/static/inpage/9/js/lazy.js"></script>
It is dynamically added by the script http://media.flixcar.com/delivery/static/inpage/9/js/append.js.
The url should be http://media.flixcar.com/delivery/static/inpage/9/js/lazy.js so as be correctly loaded by the webview (which is nothing else than Edge browser).
I also think that you need to update each image attributes. Currently they are added also without protocol which are not supported by all browsers (for me it only works with Chrome).
<div class="flix-feature-image">
<img src="//media.flixcar.com/delivery/static/mobile/standard/img/loading_icon.gif"
data-srcset="//media.flixcar.com/f360cdn/Samsung-1601328499-id-feature-uhd-ju6600-ua65ju6600kpxd-52938564 2x, //media.flixcar.com/f360cdn/Samsung-1601328499-id-feature-uhd-ju6600-ua65ju6600kpxd-52938564 770w">
</div>
Adding protocol will fix the issue:
<div class="flix-feature-image">
<img src="http://media.flixcar.com/delivery/static/mobile/standard/img/loading_icon.gif"
data-srcset="http://media.flixcar.com/f360cdn/Samsung-1601328499-id-feature-uhd-ju6600-ua65ju6600kpxd-52938564 2x, http://media.flixcar.com/f360cdn/Samsung-1601328499-id-feature-uhd-ju6600-ua65ju6600kpxd-52938564 770w">
</div>

why does .net core "Return" verb inside a controller adds "plaintext.css" ?

I was doing some testing with MVC6 .net core, and did a quick hack to return a bootstrap html code by putting dirtyHTML directly inside a controller.
The HTML contains the official example of bootstrap inside a literal string.
Just a quick way of returning some bootstrap html, (as i experiment with controller functionality), to my surprise when i go to a page using a web browser, all html text is shown like plain text, its not rendered.
namespace WebApplication1.Controllers
{
public class MariaController
{
[HttpGet("/index")]
public string index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return dirtyHtml;
}
}
When going to debug mode, initially they show the same asci text, but using firefox i see there is a line inserted before my page code:
<HTML><head>
<link rel="alternate stylesheet" type="text/css"
href="resource://gre-resources/plaintext.css"
title="Wrap Long Lines">`
So then i thought, let's look around in the solution and search for "Wrap Long Lines".. as to see where it comes from,... this is however not found.
So where does that come from ? (as the solution doesnt contain plaintext.css either). And more important to me, can it be disabled?.
I am not sure what you want to achive but following thing is way to go.
"Wrap Long Lines" and css related to that are internal to firefox browser.
You are saying that you return html and it display like html but it does not render html and for that do following thing.
[HttpGet("/index")]
public IActionResult index()
{
string dirtyHtml;
dirtyHtml =
#"<!DOCTYPE html>
<html lang=""en"">
<head>
<title>Bootstrap Example</title>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"">
<script src=""https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js""></script>
<script src=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js""></script>
</head>
<body>
<div class=""container"">
<h1>My First Bootstrap Page</h1>
";
return Content(dirtyHtml,"text/html");
}
See I have return IActionResult and Use Content from return.
Reason for this is when you return string it will display as string and if it is html then it will become encoded as you did not tell browser content type so it consider "text/plain".
An alternative of #dotnetstep's way is using Produces attribute:
[HttpGet("/index")]
[Produces("text/html")]
public string Index()
{
...
}

How can I dynamically add an attribute to a body element in a GSP page

In Grails 2.3.7, is there a way to use an expression in a GSP page to add an attribute to a body element? In the code below, the expression in the p element works, but the same expression in the body element causes a error: Expecting '=' after attribute name (${raw('this="that"')}).
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body ${raw('this="that"')}>
<p ${raw('this="that"')}>Hello!</p>
</body>
</html>
I'm trying to do this in a layout and pick up the corresponding attribute from the original page with pageProperty, but the same error occurs on the body element in the page layout as well.
Replacing an attribute value does work in a body element like this:
<body this="${that}">
but this won't work because I do not want the attribute to appear at all if it has no value.
the problem is, that the body tag is replaced by the <g:layoutBody /> tag and therefore could not be set like this.
One solution is to use to set different stuff in the sitemesh layout.
An example of this is shown here:
<html>
<head>
<g:layoutHead/>
</head>
<body class="${pageProperty( name:'body.class' )}">
<g:layoutBody/>
</body>
</html>

import external header (link) in MVC4 _layout page?

My company has common header that developed in php. I need to import that page into my layouts page in the project. The header can me called "company.com/inc/custom/footer2sn/"
How can call this?
If your page is to include is a static HTML page you can use Partial.
Simply change the somepage.html to somepage.cshtml.
Example:
#Html.Partial("~/Path/to/somefile.cshtml")
Trying to render a normal HTML file will give you an error such as Page cannot be found or no rendering engine could be found.
SO if you have a static HTML page, change the extension to CSHTML and use #Html.Partial()
OR
If the header you want to include is a PHP file it is possible as long as you have a server that is up and running and ready to serve the generated HTML from the PHP page.
You could write a custom HTML Helper
public static class MyHelpers
{
public static HtmlString RenderPHP(this HtmlHelper helper, string path)
{
var requestContext = helper.ViewContext.RequestContext;
UrlHelper url = new UrlHelper(requestContext);
var client = new WebClient();
var returnString= client.DownloadString(new Uri(string.format("Http://{0}{1}", requestContext.HttpContext.Request.Url.Host, url.Content(path))));
return MvcHtmlString.Create(returnString);
}
}
In short, this simply takes the HTML generated from the PHP page and injects it into a section within your page.
To use this inside your page use Razor Syntax like so:
<div id="phpPage">
#Html.RenderPHP("company.com/inc/custom/footer2sn/somepage.php"). <!-- Note this must on a server capable of rendering the php -->
Source
You can use Html.RenderPartial:
#{ Html.RenderPartial("SomeView"); }
But, it's better to have your layouts inherit each other hierarchically, and put your HTML directly in the layer it belongs to for common layout elements:
_Layout.cshtml
<!doctype html>
<html>
<head>
...
</head>
<body>
<header>
...
</header>
#RenderBody()
<footer>
...
</footer>
</body>
</html>
_TwoColumnLayout.cshtml
#{ Layout = "~/Views/Shared/_Layout.cshtml"; }
<div id="container">
<div id="content">
#RenderBody()
</div>
<aside id="sidebar">
...
</aside>
</div>
You can keep building layers like this as deep as you need. Just set Layout to the template it should inherit from and then put #RenderBody() where the content of the next child template or view should go.

properly using jQuery Mobile event handling in version 1.7.1

I am at my wits end with jQuery Mobile events. I do not understand them, despite following the docs to the T. I am using the following code to initialize my pages. The problem is that some seem to fire multiple times and occasionally when I go back to a page nothing will appear, as though .live pageinit simply doesn't fire at all. I am quite confused. Is pageinit the way to go? is .live best practice? Do I need to clean up after myself and use something like pagehide to remove stuff from the DOM? Please help me understand. Thanks!
// page number 1
<header>
includes and stuff
<header>
<body>
<div data-role="page" data-theme="a" id="dashboardPage">
$('#dashboardPage').live('pageinit',function() {
});
// somewhere in here a page transition to anotherPage.html (not necessarily the id of the new page in the <div data-role-"page data-theme...> declaration
$.mobile.changePage("anotherPage.html",{transition : "slide"});
</div>
</body>
// page number 2
<header>
includes and stuff
<header>
<body>
<div data-role="page" data-theme="a" id="specialsPage">
$('#specialsPage').live('pageinit',function() {
});
</div>
</body>
You could try something like this:
<html>
<header>
<!-- BASIC INCLUDES -->
<link rel="stylesheet" href="./css/jquery.structure-1.1.0.min.css" />
<link rel="stylesheet" href="./css/jquery.mobile-1.1.0.min.css" />
<link rel="stylesheet" href="./css/jquery.mobile.theme-1.1.0.min.css" />
<script type="text/javascript" src="./js/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="./js/jquery.mobile-1.1.0.min.js"></script>
<!-- END - BASIC INCLUDES -->
</header>
<body>
<!-- PAGE 1 -->
<div data-role="page" data-theme="a" id="dashboardPage">
<script>
// INITIALIGE PAGE 1 - dashboardPage
$("#dashboardPage").live('pageinit',function(event){
alert( '"initializing" page 1: dashboardPage');
});
</script>
HERE YOU ARE AT PAGE 1 (dashboardPage)!!!<br><br>
CLICK HERE TO GO TO PAGE 2 (specialsPage)
</div>
<!-- PAGE 2 -->
<div data-role="page" data-theme="a" id="specialsPage">
<script>
// INITIALIGE PAGE 2 - specialsPage
$("#specialsPage").live('pageinit',function(event){
alert( '"initializing" page 2: specialsPage');
});
</script>
HERE YOU ARE AT PAGE 2 (specialsPage)!!!<br><br>
CLICK HERE TO GO TO PAGE 1 (dashboardPage)
</div>
</body>
</html>
Hope it helps.
When using JQuery mobile you should consider you have a single page which content is updated dynamically. You do not navigate from one page to the other as you normally would.
Because of this, any code present in a page you navigate to with JQM simply be ignored (tyr changing the header of page number 2, and navigate to this page from page number 1 with changepage, you will not see any difference).
Because of that, all your js code should be directly available within the page in which your user will arrive.
If you add the following code in the scripts of page 1, you will proeperly detect the initialization of of page2 when it is loaded with changepage.
$("#specialsPage").live('pageinit',function(event){
alert( '"initializing" page 2: specialsPage');
});
An important thing to keep in mind is that you user might also directly access your page2, which means that all the code should also be available for page 2. Because of this I would strongly recommend including all your code in a js file referenced in the headers of all your page, and NOT directly in script tags within your pages.

Resources