I have a problem, which only is an issue when my application is deployed - there is no issue when developing.
I have 2 controlleres. One controller residing i a plugin which the second is extending. There exists a specific template in a view folder - /templates/_mytemplate.gsp in the "main" project -that is, not in the plugin.
The "common-controller" has a method for rendering various templates based on a string. And this is where the trouble starts. Using:
String summary = groovyPageRenderer.render(template: "/mycontroller/templates/_mytemplates.gsp", model: [foo: bar])
Works perfectly fine in development but when war-deployed, the string is empty. I have narrowed the problem down to be of resolveSearchPaths method in DefaultGroovyPageLocator [1] which differentiates the lookup path.
Anyone? What would be reasonable solution? Preferable the templates are not located in the plugin....
I ran into a similar issue with a release a few days back and used something like:
try {
//look for template in the main app
def html = render(template:'/mycontroller/templates/mytemplates', model: [foo: bar])
if(html && html.size() > 0) {
render html
}
} catch (Exception e) {
//bad way to handle template not found.
}
//fallback on the template defined in the plugin
render(plugin:'myPlugin', template:'/mycontroller/templates/mytemplates', model: [foo: bar])
This probably isn't the best way to handle this issue but at least gets the deployed war working.
Stupid stupid stupid!
Developing on windows - deploying to Unix. So forgot a camelcase T <- which works on Windows not on Unix :)
So to make it work:
String summary = groovyPageRenderer.render(template: "/mycontroller/templates/_my**T**emplates.gsp", model: [foo: bar])
Related
I have freshly installed vs 2022 and created Umbraco 9.5.1 project. When I go to generated view, for example Views/test.cshtml and try to see the members of Model, I get nothing:
I tried setting the following option:
"Umbraco": {
"CMS": {
"ModelsBuilder": {
"ModelsMode": "SourceCodeManual",
"ModelsDirectory": "~/umbraco/models"
},
But it started giving me the following error:
How can I enable intellisense in the views?
Make sure to include all the generated files in you project/solution, as well as the view files. That should do it?
I am using Json views plugin of grails. Which works in development, but when I run it as a jar file, it is not able to find the templates/gson files for rendering. I get the following error
//code
def template = jsonViewTemplateEngine.resolveTemplate(<path to template>)
def writable = template.make(kase: kase)
//exception
Cannot invoke method make() on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method make() on null object
Json Views we are using are a part of a inline plugin we are developing. Jar we create also runs with that inline plugin (implemented using gradle wrapper)
Any ideas/suggestions?
Environment:
Grails - 3.2.0
Groovy - 2.4.7
Json-Views plugin - 1.1.1
Views are pre-compiled into classes for deployment via Gradle and the compileGsonViews task. This is done using the project.name setting by default.
You will notice in the build/main/gson-classes directory the classes that are produced. For example if your application name is foo you will have classes like foo_book_show_gson.class where the foo_ part is considered the "package" name.
At runtime. The package name to use to resolve views calculated from the info.app.name setting in grails-app/conf/application.yml.
What this means is that if in Gradle your project.name evaluates to foo and the setting in application.yml is also foo then all is well. This is the most common case as typically your application name is the same in both places.
If info.app.name and the Gradle project.name don't match up you can get the problem where views don't resolve.
You have two options to fix this. One is to modify build.gradle to explicitly specify the package name:
compileGsonViews.packageName = 'foo'
Then make sure info.app.name matches that value.
The second option is rename your project directory so that info.app.name and project.name align.
Json View behavior is different in dev mode and war mode.
WritableScriptTemplate template
if (Environment.isDevelopmentEnvironmentAvailable()) {
template = attemptResolvePath(path)
if (template == null) {
template = attemptResolveClass(path)
}
} else {
template = attemptResolveClass(path)
if (template == null) {
template = attemptResolvePath(path)
}
}
if (template == null) {
template = NULL_ENTRY
}
In development mode grails will load your template by file path first then load by class name.
If you are working on case insensitive file system,template file like
'your_template_name' and 'YOUR_TEMPLATE_NAME' will be treated same.
But class name is case sensitive,'your_template_name_class' and 'YOUR_TEMPLATE_NAME_CLASS' is different;
Maybe your template file name is incorrect.
For example, if your classname is:
QueryResult
Your template file should located in:
/views/queryResult/_queryResult.gson
Json View will search class like:
<Project-Name>_queryResult__queryResult_gson
I'm all new to Xamarin and I'm currently working on a sample or a "prove of concept" app using Xamarin.Forms.
I'm supposed to perform a print task from this app though I'm not at this point sure what to print yet (the screen, content of a label, a file etc.).
Either way, what is the easiest way to print from a Xamarin.Forms app?
(current target is primarily Android 4.4+).
I hope this isn't too complicated :)
EDIT:
Ok let me just update this post as the original text might be a bit ambitious/vague.
I have a Xamarin.Forms project (+ an Android part) and I have some HTML available in the XF part of the project that I need to get into a WebView and print it.
From what I understand, the thing with the WebView has to be done on the Android part of the project due to the fact that this is where the printing will be handled.
I was hoping this could be done from code since I don't really need to display the WebView, just print it's content.
The Android part of the project has only the MainActivity and no layouts or XAML files.
I don't know where to add the WebView or how to access it (other than DependecyService seems to be a buzz word here) so I'm kinda stuck here.
I'm thinking that this task should be rather trivial to someone with a little more Xamarin experience than me.
Every platform XF supports has it's own mechanism for printing. XF does not provide any abstractions for printing in a cross-platform manner. You will need to write printing logic for each layer and expose it to XF using DependencyService (or some other DI engine).
Here is a good example, of course, using dependency service:
https://codemilltech.com/xamarin-forms-e-z-print/
I so wanted to do this but it was too hard. Finally built it into Forms9Patch - a MIT licensed open source project.
Verifying that Printing is available
Before printing, you should verify that printing is available on your device. To do so, call:
if (Forms9Patch.PrintService.CanPrint)
{
// do the printing here
}
Print the contents of a Xamarin.Forms.WebView
using Forms9Patch;
...
var myWebView = new Xamarin.Forms.WebView
myWebView.Source = new HtmlWebViewSource
{
Html = "some HTML text here"
};
...
myWebView.Print("my_print_job_name");
Note that your WebView does not have to be attached to a Layout. This allows you to Print without having to display the WebView in your app’s UI.
Printing an HTML string
using Forms9Patch;
...
var myHtmlString = #"
<!DOCTYPE html>
<html>
<body>
<h1>Convert to PNG</h1>
<p>This html will be converted to a PNG, PDF, or print.</p>
</body>
</html>
";
...
myHtmlString.Print("my_print_job_name");
PLEASE NOTE: iOS sometimes places the page breaks in weird places. I have a StackOverflow Bounty on why this happens and how to fix it.
Using EmbeddedResource as a source for a Xamarin.Forms.WebView
This is sort of an experimental feature I’ve built that I’ve found it useful. As such the documentation is sparse. It allow you to put HTML content in a folder in your app’s EmbeddedResources folder and then use it as a source for a WebView. A much nicer solution than using platform specific approach provided by Xamarin. It also supports putting all of the HTML content into a zip file. Please take a look at the source code to see how it works.
You can handle the printing of lists/ invoices .. with the xfinium pdf component from xamarin componentstore. With that you create your _pdffile and then call the following method which starts the adobereader from where you can select a printer (in my case google cloudprint)
public void printPdfToCloud(string _pdffile)
{
try
{
var saveto = System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory.ToString(), "YourApp/"+_pdffile);
string file_path = saveto;
if (System.IO.File.Exists(file_path))
{
Android.Net.Uri pdfFile = Android.Net.Uri.FromFile(new Java.IO.File(file_path));
Intent pdfIntent = new Intent(Intent.ActionView);
pdfIntent.SetPackage("com.adobe.reader");
pdfIntent.SetDataAndType(pdfFile, "application/pdf");
pdfIntent.SetFlags(ActivityFlags.NoHistory);
StartActivity(pdfIntent);
}else
{
// give a note that the file does not exist
}
}
catch (Exception E)
{
// Do some Error dialog
}
}
I am using Grails 1.3.5, SQL Server 2005, iReports 3.7.6, Jasper Plugin 1.1.3. In my GSP page I have given the jasperReprt tag as:
<g:jasperReport jasper="report1" format="PDF">
<input type="hidden" name="test_id" id="test_id"/>
<input type="hidden" name="order_no" id="order_no" />
</g:jasperReport>
For development, in Config.groovy I have specified the
jasper.dir.reports = './reports'
There are two files created in the reports folder when a new report is created and saved, i.e. report.jrxml and report.jasper.
When clicked on the PDF icon in IE or Firefox, an 500 server error is thrown and below is stack trace.
[2010-11-27 01:13:14.998] ERROR groovy.grails.web.errors.GrailsExceptionResolver Invalid byte 1 of 1-byte UTF-8 sequence.
com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:684)
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:554)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1742)
at
But if I delete the report1.jasper, the error is no longer thrown when PDF icon is clicked and the PDF report is shown fine.
Is this the correct way to do it?
My second issue is with using Sub Reports. Sub report is in the same folder as the main report. But When the report is executed from the application, below error is thrown:
[2010-11-27 01:30:27.556] ERROR groovy.grails.web.errors.GrailsExceptionResolver Could not load object from location : ./reports\report1sub_report.jasper
net.sf.jasperreports.engine.JRException: Could not load object from location : ./reports\urine_routinepatient_details_sub_report.jasper
at net.sf.jasperreports.engine.util.JRLoader.loadObjectFromLocation(JRLoader.java:262)
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateReport(JRFillSubreport.java:301)
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:327)
It does not find the sub report. How can I fix it?
Thank you.
Jay Chandran.
Edit:
I have been searching during this whole time, but still could not find a proper solution. So I did some trial and error. I figured out that, deleting report1.jasper and just leaving jasper.jrxml in the report directory works just fine as I said earlier.
For the sub-report issue: It was giving error Could not load object from location : ./reports\report1sub_report.jasper For some strange reason, the main report name report was getting appended to the name sub_report.jasper and was looking for a file named report1sub_report.jasper
So I created a sub-folder under reports folder and named it report1 and updated report1.jrxml file
<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "\\sub_report.jasper"]]></subreportExpression>
I had to add the extra \\ slash even though the "SUBREPORT_DIR" parameter had \\ the slashes at the end of the path as shown below.
<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
<defaultValueExpression><![CDATA["F:\\Workspace\\SpringSource2.5.0\\GrailsProjec\\reports\\report1\\"]]></defaultValueExpression>
</parameter>
Notice the \\ at the end. I don't know why it was not getting appended!
Another way would have been to just change the sub-report name from sub_report.jasper
to report1sub_report.jasper!!! :)
I have tested this in production mode and it works fine. I am not sure if this is the way to do it, but all other possible solutions did not work for me.
Feedback will be very helpful.
I assume you have a version conflict here. iReport stores JRXML files and seems to compile them automatically to .jasper. The Grails Jasper plugin picks up the compile variant and gets into trouble with it. So try to disable compiled output in ireport.
The Grails Jasper plugin 1.1.3 uses internally Jasper 3.7.4, the used ireport is 3.7.6.
Regarding the sub reports: no idea.
The MalformedByteSequenceException is caused by a character encoding conflict. I'd suggest to use UTF-8 instead of Windows' Win-1252 (similar to ISO-8859-1) everywhere.
In Jasper's etc/ireport.conf file, change the default_options to:
default_options="-J-Dfile.encoding=UTF-8 -J-Xms24m -J-Xmx64m"
(Where Xms and Xmx are unrelated memory settings. If there are default settings with that config entry, you can overtake them, else, just leave them out.)
See this forum thread for alternative configurations.
As for the error with subreports, take a look at the backslash \ that's probably wrong.
EDIT : There is some information about two issues which maybe could help in
http://grails.org/plugin/jasper#faqTab
i hope i can help with one of the issues: which one related with subreports dir.
The problem is the plugin code sets SUBREPORT_DIR to the complete file path of main report, including its name. However the code honour the user provided param with the same name, so if you fill this param with whatever value except null the plugin will use it.
For example if you chain directly the jasper controller you can do:
def renderAs(data,format) {
def reportParams=params.clone()
reportParams["_format"]=reportParams["_format"]?:"${format.toUpperCase()}"
reportParams["SUBREPORT_DIR"]=CH.config.jasper.dir.reports+"/"
chain(controller:'jasper',action:'index',model:[data:[]+data],params:reportParams)
}
In your scenario an (ugly) option would be create an hidden input with name SUBREPORT_DIR and value the desired one. I would fill the paremeter in other way.
EDIT:
Another annoying problem is where do we have to put the main reports and compiled subreports:
When you run the app with run-app they work if you put them all in a folder with the same name as CH.config.jasper.dir.reports(reportDir) in the root of the grails app.
But if you want to deploy a war you have to put the main reports in a folder reportDir in the root of war file and compiled subreports in WEB-INF/classes/reportDir.
I've opted to keep all files in grailsApp/reports and copy the resources in the appropiate folders in the war grails task. In my BuildConfig.groovy i've added (reportDir is "reports"):
grails.war.resources = { stagingDir,args ->
def classpathDir="${stagingDir}/WEB-INF/classes"
copy(toDir:"${stagingDir}/reports") {
fileset(dir:"reports",includes:"**")
}
copy(toDir:"${classpathDir}/reports") {
fileset(dir:"reports",excludes:"**.jrxml")
}
}
Hope it helps.
My files are referenced like so (it's all relative):
// WHERE YOU KEEP THE PAGE TITLE XML
public static string myPageTitleXML = "xml/pagetitles.xml";
and
using (StreamReader r = new StreamReader(myPageTitleXML))
{ //etc.. . .etc....etc..
}
I get system.io.directorynotfound, and "this problem needs to be shut down", when I double click the executable. But running it from the console works like a charm. What's wrong here?
I played around with attempting to set Environment.CurrentDirectory but couldn't get anything to work. Why should I have to do that anyway? It defeats the purpose of a relative path no?
responding.. .
"application" does not exist in the current context, i'll keep trying what people have mentioned, this is not a windows.form
testing
Path.GetDirectoryName(Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), myPageTitleXML); gives error URI formats are not supported, as does Path.GetFullPath(). Server.MapPath results in an error as well, this is currently offline
Well assuming this directory is somewhere under the directory in which your code is executing, it sounds like you can use ..
Application.ExecutablePath()
or
Application.StartUpPath()
.. to get an idea as to what your application is seeing when it goes in search of an 'xml' directory with the 'pagetitles.xml' file in it.
If the directory returned by one of these methods does not point where you thought it did, you'll need to move the location of your application or the location of this folder so that it is within the same directory as the app.
Hope this gets you on the right path.
So, when you run it from double clicking the executable, is there a file named pagetitles.xml in a folder named xml, where xml is a folder in the same location as the executable?
It's certainly possible to use relative paths like this, but I wouldn't really recommend it. Instead, maybe use something like:
string fileToOpen = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), myPageTitleXML);
using (StreamReader r = new StreamReader(fileToOpen))
{
//etc.. . .etc....etc..
}
Is this ASP.NET code? If so then you probably need to do MapPath("xml/pagetitles.xml")