Cache locale specific templates in Thyemeleaf - thymeleaf

Apparently Thymeleaf doesn't use locale as part of the cache key.
This is causing issue for a particular use case.
- Many locale specific fragments exists which contains static text that are too big to be part of messages.properties file. They are stored in hierarchy similar to following:
+ templates
+--> help.html
+
+--> fragments
+
+----> en
+-------> help-index.html
+
+----> es
+-------> help-index.html
+
+----> fr
+-------> help-index.html
...
The "help.html" page template then include this fragment as
th:include="fragments/help-index :: imp-block"
A custom resource resolver handles the resolving of the template based on the incoming request locale.
The problem is when caching is turned on, Thymeleaf caches the first request's locale specific fragment.
Adding locale as part of the fragment name will work, but that is less than ideal for me.
Is it possible to solve this problem differently?
Any help is much appreciated.

Related

When do I need to encode with multiple codecs in Grails?

I'm not clear of when (or if) I should use multiple Grails encodeAsXXX calls.
This reference says you need to encodeAsURL and then encodeAsJavaScript: http://grailsrocks.com/blog/2013/4/19/can-i-pwn-your-grails-application
It also says you need to encodeAsURL and then encodeAsHTML, I don't understand why this is necessary in the case shown but not all the time?
Are there other cases I should me using multiple chained encoders?
If I'm rendering a URL to a HTML attribute should I encodeAsURL then encodeAsHTML?
If I'm rendering a URL to a JavaScript variable sent as part of a HTML document (via a SCRIPT element) should I encodeAsURL, encodeAsJavaScript then encodeAsHTML?
If I'm rendering a string to a JavaScript variable sent as part of a HTML document should I encodeAsJavaScript then encodeAsHTML?
The official docs - https://docs.grails.org/latest/guide/security.html - don't show any examples of multiple chained encoders.
I can't see how I can understand what to do here except by finding the source for all the encoders and looking at what they encode and what's valid on the receiving end - but I figure it shouldn't be that hard for a developer and there is probably something simple I'm missing or some instructions I haven't found.
FWIW, I think the encoders I'm talking about are these ones:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/JavaScriptUtils.html#javaScriptEscape-java.lang.String-
https://docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html#encode(java.lang.String,%20java.lang.String)
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/util/HtmlUtils.html#htmlEscape-java.lang.String-
.
It is certainly important to always consider XSS but in reading your question I think you are overestimating what you need to do. As long as you're using Grails 2.3 or higher and your grails.views.default.codec is set to html which it will be by default, everything rendered in your GSP with ${} will be escaped properly for you.
It is only when you are intentionally bypassing the escaping, such as if you need to get sanitized user input back into valid JavaScript within your GSP for some reason, that you would need to use the encodeAsXXX methods or similar.
I would argue (and the article makes a mention of this as well) that this should raise a smell anyway, as you probably should have that JavaScript encapsulated in a different file or TagLib where the escaping is handled.
Bottom line, use the encoding methods only if you are overriding the default HTML encoding, otherwise ${} handles it for you.

Are URLs with & instead of & treated the same by search engines?

I'm validating one of my web pages and its throwing up errors as below :
& did not start a character reference. (& probably should have been escaped as &.)
This is because on my page I am linking to internal webpages which has &'s in the URL as below:
www.example.com/test.php?param1=1&param2=2
My question is that if I change the URLs in the a hrefs to include & as below:
www.example.com/test.php?param1=1&param2=2
Will Google and other search engines treat the 2 URLs above as separate pages or will they treat them both as the one below:
www.example.com/test.php?param1=1&param2=2
I dont want to loose my search engine rankings.
There is no reason to assume that search engines would knowingly ignore how HTML works.
Take, for example, this hyperlink:
…
The URL is not http://example.com/test.php?param1=1&param2=2!
It’s just the way how the URL http://example.com/test.php?param1=1&param2=2 is stored in attributes in an HTML document.
So when a conforming consumer comes across this hyperlink, it never visits http://example.com/test.php?param1=1&param2=2.

Localized URLs in Play 2.0?

Yesterday we had a Play 2.0 presentation at our local JUG but we couldn't figure out whether it is possible to have localized URLs (for SEO purposes).
For example /help, /hilfe etc should point to the same controller but the template should be rendered with different language content.
Is there any way to do this in Play 2.0?
I like your question, because it was creative at least for me :) Check this approach it works for me:
conf/routes:
GET /help controllers.Application.helpIndex(lang = "en")
GET /hilfe controllers.Application.helpIndex(lang = "de")
GET /help/:id controllers.Application.helpTopic(lang = "en", id: Long)
GET /hilfe/:id controllers.Application.helpTopic(lang = "de", id: Long)
controllers/Application.java:
public static Result helpIndex(String lang) {
return ok("Display help's index in " + lang.toUpperCase());
}
public static Result helpTopic(String lang, Long id) {
return ok("Display details of help topic no " + id + " in " + lang.toUpperCase());
}
views/someView.scala.html:
Help index<br/>
Hilfe index<br/>
Help topic no 12<br/>
Hilfe topic no 12
(This is different approach than in previous answer, therefore added as separate one)
You can also create some kind of mapping table in DB where you can store full paths to records with different params:
urlpath record_id lang
/help/some-topic 12 en
/hilfe/ein-topic 12 de
than in conf/routes file you need to use rule allowing you to use Dynamic parts spanning several / (see routing doc) ie:
GET /:topic controller.Application.customDbRouter(topic:String)
You can also mix both - standard routing mechanismus with custom one by placing above rule at the end of your conf/routes file if no 'static' rule will be available, then it will try to find it in mapping table or will return notFound() Result.
You use from GlobalSettings.onHandlerNotFound() and check if the is a translated version of the url. Then you can make a redirect. However this ends with urls in default language.
More cleaner would be to use the GlobalSettings.onRouteRequest where you can implement your own logic to get the handler.
Furthermore you can create your own router. There was a discussion about it at google-groups with a scala solution.
It was possible in Play 1.2.x, not in 2.x as far as I know. I mean, it's not possible without duplicating the mappings in your file, adding one for EN, one for DE, etc.
A simpler alternative for SEO may be to "fake" the urls in your Sitemaps file.
So your Routes file has
GET /action/:param/:seo-string Controller.methodAction(param)
so seo-string will be ignored in processing, and you generate several links on your Sitemaps file:
/action/1/english-text
/action/1/german-text
This would set the search engines. For users, so they see the url in the right language, you could change the URL using HTML 5 history.
It's extra work, but if you really want it...

Allow plus sign in URL with MVC 3

I need to be able to allow the "+" sign for certain actions in a controller. I am building a tag filtering engine that allows something like this (ie. stackoverflow) : /Stuff/Tagged/tag-name-1+tag-name-2+other-tag
I know I can set allowDoubleEscaping="true" in the web.config, but it is not best practices for security reasons.
I am guessing there is a way using maybe a custom filer or some other registry in the global.asax?
StackOverflow is probably treating the + as a whitespace. Most likely they map the route /Stuff/Tagged/{*tags} and call string.split() on the tags. This actually works out great if you don't allow whitespace in your tags.
+ means whitespace in an url. You should URL encode them:
/Stuff/Tagged/tag-name-1%2Btag-name-2%2Bother-tag
You can use simple replace:
string url = Url.Action("Index", "YourController");
url = url.Replace("%2b", "+");

Why we don't use such URL formats?

I am reworking on the URL formats of my project. The basic format of our search URLs is this:-
www.projectname/module/search/<search keyword>/<exam filter>/<subject filter>/... other params ...
On searching with no search keyword and exam filter, the URL will be :-
www.projectname/module/search///<subject filter>/... other params ...
My question is why don't we see such URLs with back to back slashes (3 slashes after www.projectname/module/search)? Please note that I am not using .htaccess rewrite rules in my project anymore. This URL works perfect functionally. So, should I use this format?
For more details on why we chose this format, please check my other question:-
Suggest best URL style
Web servers will typically remove multiple slashes before the application gets to see the request,for a mix of compatibility and security reasons. When serving plain files, it is usual to allow any number of slashes between path segments to behave as one slash.
Blank URL path segments are not invalid in URLs but they are typically avoided because relative URLs with blank segments may parse unexpectedly. For example in /module/search, a link to //subject/param is not relative to the file, but a link to the server subject with path /param.
Whether you can see the multiple-slash sequences from the original URL depends on your server and application framework. In CGI, for example (and other gateway standards based on it), the PATH_INFO variable that is typically used to implement routing will usually omit multiple slashes. But on Apache there is a non-standard environment variable REQUEST_URI which gives the original form of the request without having elided slashes or done any %-unescaping like PATH_INFO does. So if you want to allow empty path segments, you can, but it'll cut down on your deployment options.
There are other strings than the empty string that don't make good path segments either. Using an encoded / (%2F), \ (%5C) or null byte (%00) is blocked by default by many servers. So you can't put any old string in a segment; it'll have to be processed to remove some characters (often ‘slug’-ified to remove all but letters and numbers). Whilst you are doing this you may as well replace the empty string with _.
Probably because it's not clearly defined whether or not the extra / should be ignored or not.
For instance: http://news.bbc.co.uk/sport and http://news.bbc.co.uk//////////sport both display the same page in Firefox and Chrome. The server is treating the two urls as the same thing, whereas your server obviously does not.
I'm not sure whether this behaviour is defined somewhere or not, but it does seem to make sense (at least for the BBC website - if I type an extra /, it does what I meant it to do.)

Resources