Grails: URL mapping - how to pass file extension? - grails

I have some folder with different files.
I want to use something like this: http://myserver.com/foo/bar/test.html
I'm using this way to obtain path:
"/excursion/$path**" (controller:"excursion", action:"sweet")
But it doesn't helps with file extensions... How to disable file extensions truncating ?
P.S.
class ExcursionController {
def defaultAction = "sweet"
def sweet = {
render "${params.path}"
}
}
Request http://myserver.com/excursion/foo/bar/test.html
The result is "foo/bar/test" with no extension :(

what does
render "${params.path}.${request.format}"
give you?

Disable file extension truncation by adding this line to grails-app/conf/Config.groovy:
grails.mime.file.extensions = false
This impacts content negotiation, so I suggest you read section 7.8 of the Grails user guide

Related

Unable to get message() String from localization table in Grails

I am using Localizations (messages) plugin to pull i18n definitions from the database rather than from the standard properties files in the i18n folder.
I am trying to use Localization plugin into my Service.groovy file. I am doing like this ..
import org.grails.plugins.localization.*
// some code.....
def body = message(code: "goal.auto.email.alert")
log.info("body : "+body)
When I check log, my body is showing null. I already added record with same code name into my Localization table. But it is not getting String message from the table. I am not able to figure out the problem. Please help. Thanks in advance.
Try the following code
class FirstService {
def messageSource
def test() {
...
def msg = messageSource.getMessage('localization.cache.hits', null, Locale.US)
...
}
}
See the blog.
As of my experience, I think message(code: "goal.auto.email.alert") will not work in Service. So I did this by using sql query ..
def body = sql.rows("SELECT TEXT FROM Localization WHERE CODE='goal.auto.email.alert'")
body = body.text[0]
And now it works for me :)

How do I disable Transformations in TYPO3 RTE Editor?

I created a custom extension for TYPO3 CMS.
It basically does some database queries to get text from database.
As I have seen, TYPO3 editor, transforms data before storing it in database so for example a link <a href="....." >Link</a> is stored as <link href>My Link Text</link> and so on for many tags like this.
when I query data from DB, I get it as it is stored in DB (<link href>My Link Text</link>)
so links are not displayed as they shoud. They display as normal text..
As far as I know there are two ways to go:
disable RTE transformations (how to do that?)
use lib.parseFunc_RTE (which i have no Idea how to configure it properly)
any idea?
thanks.
I guess you're not using Extbase and Fluid? Just as a reference, if you are using Extbase and Fluid for your extension you can render text from the RTE using Fluid:
<f:format.html>{bodytext}</f:format.html>
This uses lib.parseFunc_RTE to render the RTE text as HTML. You can also tell it to use a different TypoScript object for the rendering:
<f:format.html parseFuncTSPath="lib.my_parseFunc">{bodytext}</f:format.html>
Useful documentation:
parseFunc
Fluid format.html
I came across the same problem, but using EXTBASE the function "pi_RTEcssText" ist not available anymore. Well maybe it is, but I didn't know how to include it.
Anyway, here's my solution using EXTBASE:
$this->cObj = $this->configurationManager->getContentObject();
$bodytext = $this->cObj->parseFunc($bodyTextFromDb, $GLOBALS['TSFE']->tmpl->setup['lib.']['parseFunc_RTE.']);
This way I get the RTE formatted text.
I have managed to do it by configuring the included typoscript:
# Creates persistent ParseFunc setup for non-HTML content. This is recommended to use (as a reference!)
lib.parseFunc {
makelinks = 1
makelinks.http.keep = {$styles.content.links.keep}
makelinks.http.extTarget < lib.parseTarget
makelinks.http.extTarget =
makelinks.http.extTarget.override = {$styles.content.links.extTarget}
makelinks.mailto.keep = path
tags {
link = TEXT
link {
current = 1
typolink.parameter.data = parameters : allParams
typolink.extTarget < lib.parseTarget
typolink.extTarget =
typolink.extTarget.override = {$styles.content.links.extTarget}
typolink.target < lib.parseTarget
typolink.target =
typolink.target.override = {$styles.content.links.target}
parseFunc.constants =1
}
}
allowTags = {$styles.content.links.allowTags}
And denied tag link:
denyTags = link
sword = <span class="csc-sword">|</span>
constants = 1
nonTypoTagStdWrap.HTMLparser = 1
nonTypoTagStdWrap.HTMLparser {
keepNonMatchedTags = 1
htmlSpecialChars = 2
}
}
Well, just so if anyone else runs into this problem,
I found one way to resolve it by using pi_RTEcssText() function inside my extension file:
$outputText=$this->pi_RTEcssText( $value['bodytext'] );
where $value['bodytext'] is the string I get from the database-query in my extension.
This function seems to process data and return the full HTML (links, paragraphs and other tags inculded).
Note:
If you haven't already, it requires to include this file:
require_once(PATH_tslib.'class.tslib_pibase.php');
on the top of your extension file.
That's it basically.

Grails URLMapping deep path

I have a URL like:
/test/abs/rdc/tx.js
and I need to be able to get the /abs/rdc/tx.js part for my controller.
I tried (in URLMapping):
/test/$target**
and it returns everything but the .js
I have
grails.mime.file.extensions = true
Any ideas?
UrlMapping and file name extension didn't work as it always returns .html
Grails 2.0 has made some changes to the way the format is parsed. Using the example from the link you provided, just update the code to use response.format:
def path = params.path
if (!FilenameUtils.getExtension(path) && response.format) {
path += ".${response.format}"
}
More info is in the manual under Content Negotiation. Scroll down to the section titled Request format vs. Response format.
You can try this one:
//Grails 2.3.x
"/$controller/$action?/$id?(.${format})?"{
constraints {
// apply constraints here
}
}

Grails: Replacing symbols with HTML equivalent

I'm reading a CSV file and one of the columns has text that contains symbols that is not recognized. After I read the file, symbols such as ' becomes � . I'm also saving this into a DB.
Obviously when I display this on a webpage, it shows garbage. How can I substitute HTML code (ex. &#180 ;) for this with Grails?
I am reading the CSV using the csv plugin. Code below:
def f = "clientDocs/testfile.csv"
def fReader = new File(f).toCsvMapReader([batchSize:50, charset:'UTF-8'])
fReader.each { batchList ->
batchList.each {
def description = substituteSymbols(it.Description)
def substituteSymbols(inText) {
// HOW TO SUBSTITUTE HERE
}
Thanks for any help or suggestions. I've already tried string.replaceAll(regExp).
Grails comes with a basic set of encoders/decoders for common tasks.
What you want here is it.Description.encodeAsHTML().
And then if you want the original when displaying in the view, just reverse it with .decodeHTML()
You can read more about these here: http://grails.org/doc/latest/guide/single.html#codecs
(Edited decode method name typo as per the comment)

Rendering HTML files in Grails

I've looked around but could not find a way of simply including or rendering *.html files in Grails. My application needs to g.render or <g:render> templates which are delivered as html files. For this, as we know, html files have to be converted to _foo.gsp files in order to get rendered. I am totally surprised as to why isn't there a direct support for html or is there one??
Thanks!
One obvious option is to simply rename your HTML files from foo.html to _foo.gsp and then use <render template="foo">. However this is so obvious that I'm sure you've already thought of it.
If you simply want to render a HTML file from within a controller you can use the text parameter of the render controller method
def htmlContent = new File('/bar/foo.html').text
render text: htmlContent, contentType:"text/html", encoding:"UTF-8"
If you want to do the same thing from within a .gsp, you could write a tag. Something like the following (untested) should work:
import org.springframework.web.context.request.RequestContextHolder
class HtmlTagLib {
static namespace = 'html'
def render = {attrs ->
def filePath = attrs.file
if (!file) {
throwTagError("'file' attribute must be provided")
}
def htmlContent = new File(filePath).text
out << htmlContent
}
}
You can call this tag from a GSP using
<html:render file="/bar/foo.html"/>
What is it you are trying to accomplish?
Render html from a controller?
In that case, all you should have to do is redirect the user to file from your control.
redirect(uri:"/html/my.html")
Use html-files instead of gsp template-files?
Thing is, Grails is a "Convention over Configuration"-platform and that means you will have to do some things "the Grails way". The files needs the _ and the .gsp but the name can be whatever you like even if it's easier when you use the same name as the controller. What you gain from doing that is the knowledge that every developer that knows grails and comes into your project will understand how things are tied together and that will help them get started quickly.
Little bit fixed the Don's example, works fine for me
import org.apache.commons.io.IOUtils
class HtmlTagLib {
static namespace = 'html'
def render = {attrs ->
def filePath = attrs.file
if (!filePath) {
throwTagError("'file' attribute must be provided")
}
IOUtils.copy(request.servletContext.getResourceAsStream(filePath), out);
}
}
I wanted to write static html/ajax pages hosted in grails app (v2.4.4), but use the controller for the url rewrite. I was able to accomplish this by moving the file to web-app/ (for ease of reference), and simply use the render() method with 'file' and 'contentType' params, such as:
// My controller action
def tmp() {
render file: 'web-app/tmp.html', contentType: 'text/html'
}
Note: I only tried this using run-app, and haven't packaged a war and deployed to tomcat, yet.
Doc: http://grails.github.io/grails-doc/2.4.4/ref/Controllers/render.html
Closure include = { attr ->
out << Holders.getServletContext().getResource(attr.file).getContent();
}
It is relative to the web-app folder of your grails main application
I was able to use #momo's approach to allow inclusion of external files for grails rendering plugin, where network paths would get botched in higher environments - mine ended up like:
def includeFile = { attr ->
URL resource = Holders.getServletContext().getResource(attr.file)
InputStream content = resource.getContent()
String text = content?.text
log.info "includeFile($attr) - resource: $resource, content.text.size(): ${text?.size()}"
out << text
}

Resources