We are using CAS 5.2.3 which uses an upgraded version of Thymeleaf. Thymeleaf has restricted access to certain request features - '#request.getParameters()' being one. Is there any work around for it? I am getting the following error when trying to access it - "Access to request parameters is forbidden in this context. Note some restrictions apply to variable access. For example, direct access to request parameters is forbidden in preprocessing and unescaped expressions, in TEXT template mode, in fragment insertion specifications and in some specific attribute processors."
Good question. I face this problem a few months before, it is solvable.
After looking through their source code, I found that they are limiting the usage of #request.getParameters() only on specific tag, they didn't forbid to use #request.getParameters() in some situation.
In my use case, I am able to use CData to bypass this checking. Not sure whether it applies to your use case since you didn't provide any code example....
Anyway, the below example want to redirect user to another page, based on the parameter url
Here's an sample code that was broken in CAS 5.2.x, but worked in CAS 5.1.x :
<html>
<head>
<title> Deforestation </title>
</head>
<body th:attr="onload='window.location.href=\''+${#request.getParameter('url')}+'\''">
</body>
</html>
Here's a work around code:
<html>
<head>
<title> Deforestation </title>
</head>
<body>
Logging out. Please wait...
<script th:inline="javascript">
/*<![CDATA[*/
location.href = /*[[( ${#request.getParameter('url')} )]]*/ ;
/*]]>*/
</script>
</body>
</html>
If this didn't solve your problem, please provide your source code so we can have a better look at the problem.
Note: There is a security reason why this stuff is now banned, using this workaround might compromise the security standard, do remember to sanitize the user input if neccesary
Edit:
as per comment, although not elegant, maybe something like the following will work?
<html>
<head>
<title> Data attribute </title>
</head>
<body>
<span id="foobarid"> </span>
<script th:inline="javascript">
/*<![CDATA[*/
$('#foobarid').data('foo-bar',/*[[( ${#request.getParameter('foo') == 'bar'} )]]*/);
/*]]>*/
</script>
</body>
</html>
Apparently one can spend hours, even days on this simple requirement, which Thymeleaf introduced as a poorly dcumented annoyance in later versions. I've spent hours upgrading from an older Thymeleaf version from 5 years ago and got stuck on this very same problem. The lack of documentation didn't either. When I finally took a think break, I've realized the solution to this problem is as simple as using the <c:set> core tag with JSP.
Simply use the th:with tag in some higher level html tag where accessing request parameters is allowed, like this:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns="http://www.w3.org/1999/xhtml"
th:with="action=${param.action != null ?
param.action[0] : 'none'}">
<head>
...
In this example, the request parameter action is stored in a page context local variable named action (the name can be any unique name that you choose). This variable is now accessible anywhere bellow your high level html tag where you've defined it. It can even be used in following th:xx tags in the same html tag after the declaration. So basically, now you can do this:
<th:block th:switch="${action}">
<title th:case="'edit'" th:text="#{page.contacts.edit}"></title>
<title th:case="'delete'" th:text="#{page.contacts.delete}"></title>
<title th:case="*" th:text="#{page.contacts.add}"></title>
</th:block>
and even call a parameterized fragment by simply referring to your variable as ${action}. In this example I have a navbar template fragment, which accepts three parameters. The last of which, is a request parameter that otherwise, is inaccessible due to the newer Thymeleaf request object access restrictions.
<div id="wrapper">
<div class="nav" th:replace="html/fragments/navbar ::
navbar('html/contact','contact-html', ${action})">
</div>
<div class="content">
...
If you need more request params and more local page context variables, just use a comma to separate the declarations in the th:with tag like this:
th:with="action=${param.action == null ? 'none': param.action[0]},
self=${param.self == null ? 'none': param.self[0]}"
I hope this saves you guys some precious time and voids the frustration of refactoring older Thymeleaf html pages. It definitely beats those horrifically unmanageable CDATA scriptlets inside your pages.
Related
I want to set language value of a gsp page dynamically . Currently I am just doing it using basic hardcoded value . I did find something with JS Onload event described here.
But I wanted to find something that is GSP driven . Is there any way ?
My current code looks like <html lang="en">
I think maybe you are thinking of this in a more complex way than it actuall is.
In grails you have your layouts/main.gsp which is your sitemesh.
The tag <html lang='en' is declared at the very top of this
If you simply edit this page and add the following:
<g:set var="locale" value="${session?.'org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'?:java.util.Locale.UK}"/>
<html lang="${locale?.language?:'en'}" class="no-js">
Then when I visit my site:
localhost:8080/?lang=ja_JP view source shows:
<html lang="ja" class="no-js">
You need to do that for each sitemesh that requires to do this - having a read about this property it seems it doesn't do much for the browser but may help non human things such as search engines.
At //Build/2016, Daniel Roth, during ASP.NET Core Deep Dive into MVC talked about TagHelpers and showed Cache TagHelper.
This tag, among other things, allow to cache several portions of the page.
In my project (MVC5) i need to cache some pages, but i can't cache all the page, because in Layout View i have some data about users that can't be cached.
Here is an example of what i need to do:
<html>
<head>
<!--- Head code ---->
<head>
<body>
<div id="page">
<!--- This shouldn't be cached ---->
<div id="top-menu">
<!--- User Data ---->
</div>
<!--- This should be cached ---->
<div id="page-content">
<!--- Page Data ---->
</div>
</div>
</body>
</html>
There's a way to do something like this even in MVC5?
From a quick read through of that, it sounds like you need Donut Caching. This is a method of providing caching for portions of a page rather than all of it.
If you have separated your partials into actions, you can use the outputcache directive to cache these so they aren't executed each time.
Here is a good write up on the technique:
http://www.adamriddick.com/2013/06/asp-net-mvc4-donut-caching-donut-hole-caching/
Quite an old article, however, I believe the technique still holds water.
I have the following content in an HTML file placed under public/company/ with a CSS file css/style.css:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<link href="css/style.css" rel="stylesheet" type="text/css" media="all"/>
</head>
<body>
<div class="title">Name {name}</div>
</body>
</html>
I want to render this HTML file with the CSS stylesheet from an action and replace {name} without changing the physical file content and place. I can render the HTML file but the CSS file would not be found. Can anyone help me render the HTML file with the CSS file and replace the {name}?
css/style.css when called from company/file.html will try to load company/css/style.css.
Click here to see an article the way you can do that. Hope it will help!
But, I'm not sure why you are looking to render that way where Rails has all the features in place.
If your CSS file is located at /public/company/css/style.css, then your static HTML file should link it with an absolute path. Use a leading / in the resource's path indicate an absolute path.:
<link href="/company/css/style.css" rel="stylesheet" type="text/css" media="all"/>
Note that the Rails router will likely catch this request and raise an exception. Depending on the web server, you may need to enable static assets or serve directly, bypassing Rails altogether.
Changing the content of a static HTML file server-side without actually modifying it (ie. adding ERb) isn't straightforward. You could:
inject some javascript into the response to perform modifications client-side. (ugly)
load the static HTML file using Nokogiri, et. al., modify the content, and send the output to the client. (expensive)
Sounds to me like these vanilla HTML/CSS files are third party (designer? client?) and you would like to drop it in /public and have it work automatically with Rails. That would be nice, but it's not that easy. You'd be better off using Rails' built-in templating system, but that means modifying files and moving them to the expected locations.
I have a master page which I am using as a template to allow me to define meta tags per page. My master page takes in a model which contains the meta information, here is an example of what I am trying to do the following:
<meta name="description" content="<%= Model.description %>" />
<meta name="keywords" content="<%= Model.keywords %>" />
However, when I check the HTML once the page is rendered I get this:
<meta name="description" content="<= Model.description %>" />
<meta name="keywords" content="<= Model.keywords %>" />
If I remove the outer quotation marks from the content e.g. content=<%= Model.description %> it renders the data. It doesn't seem to like the surrounding quotation marks.
Is this a bug with the master pages? If so, what would be the best alternative workaround for this? If not, what am I doing wrong?
I have seen that before and it is a pain. Probably you have a runat="sever" attribute in your head tag like this:
<head runat="server">
if you just made it:
<head>
then you should not see this behavior.
This has always been an issue because it is trying to encode the contents in the attributes. You can get around it by doing this instead:
<%= string.Format("<meta name=\"description\" content=\"{0}\" />", Model.description) %>
<%= string.Format("<meta name=\"keywords\" content=\"{0}\" />", Model.keywords) %>
EDIT: This is not an issue specific to MasterPages. I posted a similar question a long time ago here on SO asking about it and if you read the accepted answer you can see that the framework has specific code for various items in the head tag where it will have a slightly different rendering format and will encode the data.
ASP.NET Webform css link getting mangled
I'm attempting to create a facebook app and went through the book http://pragprog.com/titles/mmfacer/developing-facebook-platform-applications-with-rails. Everything works fine on my development machine when I have my canvas render method set as fbml. But, for various reasons I want to build an app with an iframe. When I set my app to use an iframe I am unable to connect to my development machine. I went through a lot of different articles about creating an iframe app, but none seem to work. That includes
http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel
http://wiki.developers.facebook.com/index.php/XFBML
and any other site found googling any combination of facebook, iframe, rails and others.
I have the xd_receiver.htm file in my public directory and my layout looks like
<!doctype html public “-//w3c//dtd xhtml 1.0 strict//en” “http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:fb=”http://www.facebook.com/2008/fbml”>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title><%= controller.controller_name %>: <%= controller.action_name %></title>
<%= stylesheet_link_tag "jquery-ui-1.7.1.custom.css", "styles" %>
<%= javascript_include_tag "jquery-1.3.2.min.js", "application" %>
</head>
<body>
<%= yield %>
<script src="http://static.ak.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>
<script type="text/javascript">
FB_RequireFeatures(["XFBML"], function(){
FB.Facebook.init("my api key", "xd_receiver.htm"); });
</script>
</body>
</html>
My question is, what am I missing that is preventing facebook from connecting to my rails development machine when I set the canvas render method to iframe? Since my development log does not show any attempts of a connection, I'm guessing that it has something to do with the cross domain stuff, but I can't find a good answer about it anywhere.
If you place that file under /public, its important to note that the ERB contained within the template will not get parsed as you expected. I'm not too familiar with the plugin you are trying to use but have used the Facebooker gem (http://facebooker.rubyforge.org/) which provides a tidy way to interact with the Facebook REST API.
I strongly suggest using Facebooker from the beginning.
It'll save you a lot of time.
/xd_receiver
there are facebooker methods for this sort of thing check this out
http://blog.yangtheman.com/2009/08/23/how-to-integrate-facebook-connect-with-a-rails-app/