local variable in taglib not created - grails

I would like to modify one of the plugins in my Grails project to add something in a TagLib class.
The plugin is pdf version 0.6 and I would like to add a variable that stores a path.
The TagLib is originally as follows:
def pdfLink = { attrs, body ->
//String template = attrs['template']
String pdfController = attrs['pdfController']
String pdfAction = attrs['pdfAction']
String pdfId = attrs['pdfId']
//String pdfParams = attrs['pdfParams']
String url = attrs['url']
String filename = attrs['filename']
....
}
I've added the following:
String pdfPathToSave = attrs['pdfPathToSave']
Where pdfPathToSave is defined in gsp as follows:
<g:pdfLink class="pdf" .... pdfPathToSave="${path}"...></g:pdfLink>
I've put a breakpoint into the taglib and I see that, in attrs['pdfPathToSave'] there is correctly stored the path, but the variable pdfPathToSave is not correctly created.
How can I create a new local variable into TagLib class?

Related

Grails Include template from external location

How do I include external GSPs or template in the GSP file when the template to be included is not under views folder?
Yes, you can easily do that. Here you go:
import grails.gsp.PageRenderer
class MyLib {
static namespace = "foo"
static defaultEncodeAs = "raw"
PageRenderer groovyPageRenderer
def externalTemplate = { attrs, body ->
String externalFilePath = attrs.externalPath
/*
* Put content of that external template to a file inside grails-app/views folder
* with a temporary unique name appended by current timestamp
*/
String temporaryFileName = "_external-" + System.currentTimeMillis() + ".gsp"
File temporaryFile = new File("./grails-app/views/temp/$temporaryFileName")
/*
* Copy content of external file path to the temporary file in views folder.
* This is required since the groovyPageRenderer can compile any GSP located inside
* the views folder.
*/
temporaryFile.text << new File(externalFilePath).text
/*
* Now compile the content of the external GSP code and render it
*/
out << groovyPageRenderer.render([template: "/temp/$temporaryFileName", model: attrs.model])
// Delete the file finally
temporaryFile.delete()
}
}
Now in your actual GSP where you want to include the external GSP, you can write so:
<body>
<foo:externalTemplate externalPath="/home/user/anyExternalFile.gsp" model="${[status: 1}" />
</body>
I know I am late for this reply but I encountered this problem when we tried to put report views outside of the views folder.
We couldn't use the above method because we are running a jar package and we couldn't create files inside views folder.
Here is the solution on Grails 4
first inject
def groovyPagesTemplateEngine
def groovyPageLayoutFinder
then in your controller
File externalFile = new File("/path/to/file.gsp")
if(externalFile && externalFile.exists()){
GroovyPageView groovyPageView = new GroovyPageView()
LinkedHashMap model = [:]
Template template = groovyPagesTemplateEngine.createTemplate(externalFile.text, externalFileName)
groovyPageView.setServletContext(getServletContext())
groovyPageView.setTemplate(template)
groovyPageView.setApplicationContext(getApplicationContext())
groovyPageView.setTemplateEngine(groovyPagesTemplateEngine)
groovyPageView.afterPropertiesSet()
request.setAttribute GrailsLayoutDecoratorMapper.LAYOUT_ATTRIBUTE, null
GrailsLayoutView grailsLayoutView = new GrailsLayoutView(groovyPageLayoutFinder, groovyPageView)
grailsLayoutView.render model, webRequest.getCurrentRequest(), webRequest.getResponse()
webRequest.renderView = false
return
}
else {
// something that shows error
render "not found"
}

Change asp.net mvc bundles fingerprinting

Is there a possibility how to change the way how System.Web.Optimization renders bundles?
From:
<script src="/bundles/js/bundlename?v=GMFuN8gzKMcwk5BwaMfgjUlieAXKThyQd8twrVplJ8A1"></script>
To something custom like this:
<script src="/bundles/js/v-GMFuN8gzKMcwk5BwaMfgjUlieAXKThyQd8twrVplJ8A1/bundlename"></script>
UPDATE: Not ideal but small nasty workaround:
public static class BundlesHelper
{
public static IHtmlString RenderScripts(params string[] paths)
{
#if DEBUG
return System.Web.Optimization.Scripts.Render(paths);
#endif
// Get raw string
var rawString = System.Web.Optimization.Scripts.Render(paths).ToHtmlString();
// Get version value
var version = Regex.Match(rawString, #"\?v=([0-9a-zA-Z_-])+").Value;
// Remove old hash
rawString = rawString.Replace(version, "");
// Remove script end tag
rawString = rawString.Replace("</script>", "");
// Get last index of "/"
var index = rawString.LastIndexOf('/');
// Return new string
return new HtmlString(rawString.Insert(index, "/v-" + version.Replace("?v=", "")) + "</script>");
}
}
No. That's not the point. The query string portion is a cache buster. The file is located where the script src says it is, and that doesn't change. In your desired version the actual physical location of the file would have to change.

Grails i18n localization dynamically from database

Grails i18n From Database but Default Back To File
The below code is implemented based on the above link.
class DatabaseMessageSource extends PluginAwareResourceBundleMessageSource {
Ehcache messageCache
def messageBundleMessageSource
#Override
protected MessageFormat resolveCode(String code, Locale locale) {
println code + " : " + locale.language
def messageKey = new MessageKey(code, locale)
def messageFormat = messageCache.get(messageKey)?.value
if (!messageFormat) {
I18nMessage i18nMessage = I18nMessage.findByCodeAndLanguageCode(code, locale.language)
if (i18nMessage)
messageFormat = new MessageFormat(i18nMessage.text)
else
messageFormat = super.resolveCode(code, locale)
messageCache.put new Element(messageKey, messageFormat)
}
return messageFormat;
}
In the resources.groovy file this bean is configured as
shown in the below code.
beans = {
messageCache(EhCacheFactoryBean) {
timeToLive = 500
}
messageSource(DatabaseMessageSource) {
messageCache = messageCache
basename = "WEB-INF/grails-app/i18n/messages"
}
}
In the gsp page g:message is called as shown below
1.<g:message code="someObject.create"/>
2.<g:message code="someObject.create" default="Create"/>
3.<g:message code="someObject.create" args="['']"/>
For the same code given in the g:message tag, 1,2 is not displaying the text given in the database. The 3rd tag usage is showing the text content added in the database. 1 tag is showing the someObject.create. 2 Tag is showing Create value, 3rd tag shows the db text added.
why 1 and 2 notations are not displaying the dynamic value in the database? and also that the resolveCode() is called for 1Time only.

save form values through script file in umbraco

hello i want to save the value of umbraco form in database for this i have made script file and in this script file i have created function to save data and called this function in same script file and this script file is used in macro and i have called this macro in template of my page but it is not working will this approach is proper or i have to something else my basic aim is to save data in database without creating my usercontrol
code is
#functions
{
public void AddToCart()
{
string con = System.Configuration.ConfigurationManager.AppSettings["umbracoDbDSN"].ToString();
SqlConnection OnCon = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["umbracoDbDSN"].ToString());
ItemsDataContext db = new ItemsDataContext(con);
var request = HttpContext.Current.Request;
string itemcode= request.Form["ItemCode"].ToString();
string itemname = request.Form["ItemName"].ToString();
string itemcategory = Request.Form["ItemCategory"].ToString();
string userid = "Pallavi";
db.sp_AddItems(userid, itemcode, itemcategory, itemname, 0);
HttpContext.Current.Session["UserId"] = "Pallavi";
}
}
#if (!IsPost)
{
AddToCart();
}
and called this macro on template
<umbraco:Macro Alias="Uc_Cart" runat="server"></umbraco:Macro>
You approach is wrong. You must use the methods that Umbraco provides in their API and do not try to write data into the database directly.
Try this code to create an new document from Razor code:
#using umbraco.BusinessLogic;
#using umbraco.cms.businesslogic.web;
#{
DocumentType dt = DocumentType.GetByAlias("Textpage");
User author = umbraco.BusinessLogic.User.GetUser(0);
Document doc = Document.MakeNew("My new document", dt, author, parentID);
}
The example above is for Umbraco 4.x. If you're using Umbraco v6.x you could also use the new API methods:
#{
// get an instance of the contentService
var contentService = ApplicationContext.Services.ContentService;
// create new content, the last param is the userId and is optional [default = 0]
IContent newContent = contentService.CreateContent("My new document", parentID, "Textpage", 0);
// set property values
newContent.SetValue("propertyAlias", "Value");
// save (or save and publish)
contentService.Save(newContent);
}

Relative URL to server path conversion - Grails

In a custom tag, I am receiving as a parameter the url of a file, which I need to open.
I have this
/content/data.html
which is the output from
${createLinkTo(dir:'content',file:'data.html')}:
and I need the 'server path':
C:\mygrailsapp\web-app\content\data.html
You can use the Spring application context to find resources. This works if it's under web-app folder:
class FooController {
def grailsApplication
def myAction = {
String path = params.path // '/content/data.html'
def resource = grailsApplication.mainContext.getResource(path)
String text = resource.inputStream.text
...
}
}

Resources