Grails render-plugin does not render images - image

I have now setup the render-plugin and I get nice PDF-files but I also need to put an image into a few columns in my table. These images are conditionally selected by a data field of the instance.
I have the image in the assets/images folder as I think is the correct place.
I use the following GSP-line in the template that will be used by the renderer to create the PDF.
<td><g:if test="${od?.priceFSC > 0.1}"><asset:image src="checkOut16x16.png" width="16" height="16"/></g:if></td>
As a HTML-view the images prints perfect but when render the PDF they are missing.
I checked the documentation and tried the code from the example:
The controller:
def createPDF() {
def file = new File("asets/CheckOut16x16.png")
def OfferHeader offerHeader = OfferHeader.get(params.id)
[offerHeader: offerHeader])
renderPdf(template: "/stocknote/Stocknote", model: [offerHeader: offerHeader,imageBytes: file.bytes], filename: "Stocknote-"+params.id+".pdf")
}
The view:
<rendering:inlinePng bytes="${imageBytes}" class="some-class" />
I didn't care of the condition here I just wanted to see if it would be printed but it's not because the view crasched:
URI
/stocknote/editStocknote/32
Class
org.grails.taglib.GrailsTagException
Message
Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error processing GroovyPageView: [views/stocknote/editStocknote.gsp:32] [views/stocknote/_StocknoteDetail.gsp:3] 'bytes' is required
Caused by
[views/stocknote/editStocknote.gsp:32] [views/stocknote/_StocknoteDetail.gsp:3] 'bytes' is required
I don't know what I've done wrong but error message seems confusing, "Bytes is required" but I have bytes="${imageBytes}".
Hope someone could give me some help or explanation.

Sounds like the path to your file is incorrect, try:
Controller:
def assetResourceLocator
def createPDF() {
def file = assetResourceLocator.findAssetForURI( 'CheckOut16x16.png' )
def OfferHeader offerHeader = OfferHeader.get(params.id)
[offerHeader: offerHeader])
renderPdf(template: "/stocknote/Stocknote", model: [offerHeader: offerHeader,imageBytes: file.getByteArray()], filename: "Stocknote-"+params.id+".pdf")
}
View should be fine as is.

Made a big mistake >_<, The template used to create the PDF is also used by the view from where you order the PDF and at that time the image has not been created by the controller.
So to come through, I had to check the value of the image before rendering.
<g:if test="${imageBytes!= null}"> <rendering:inlinePng bytes="${imageBytes}" /></g:if>
That what was needed.

Related

grails - access image in controller to use in pdf

I'm creating a dynamic pdf with gsp and I'd like to add an image to it but I have no idea how to do this coz simply using <img src="${resource(dir: 'images/vip', file: 'heading.png')}"/> in the gsp does not seem to work. When creating an email you use inline 'pic1', 'image/jpg', resourceLoader.getResource("/images/bawHeader3.png").getFile() in the .sendMail so I was wondering if it's possible to do something similar for pdf. Here's what I got so far:
def downloadBooking() {
def result = Booking.findById(params.id)
renderPdf(template: "/pdf/booking/vipConfirmation", model : result)
}
The above works fine, I just don't know how to add an image into it. Also please show me how I would access the image inside the gsp please.
You need send the bytecode of image to "pdfRenderingService". here is configuration below.
//convert image to bytecode and pass it to the padf rendring service.
def imageBytes=grailsResourceLocator.findResourceForURI('/images/user.png').file.bytes
Passing the value to pdfrendering service.
ByteArrayOutputStream reportBytes = pdfRenderingService.render(template: "/pdf/booking/vipConfirmation", model: [result: result, "imageBytes": imageBytes])
Accessing image in template
<div> <rendering:inlinePng bytes="${imageBytes}" class="header-img"/> </div>
Grails 3.3.9
import org.springframework.core.io.Resource
def assetResourceLocator
Resource resource = assetResourceLocator.findAssetForURI('logo.png')
ByteArrayOutputStream bytes = pdfRenderingService.render(template: "/pdfs/invoice", model: [imageBytes: resource.getInputStream().bytes]) as ByteArrayOutputStream

Returning errors to gsp page in Grails after checking for hasErrors and Validating

I'm building this web app that works with user profiles. A user edit a profile and if he enters wrong data, the profile shows the invalid fields in red and shows the message. Very simple scenario. But for some reasons it doesn't work the way I assumed. I might be missing something somewhere. Here is what I do in my controller.
As you can see in the code below, I create a new Profile, I bind the params to it using an include list to only bind those params that profile accepts, and then call hasErrors on the profile instance. In debug mode, I can see that myProfile has errors when the user enters something wrong, but when I get back to the editProfile page, it doesn't show what field has the error. my gsp form has the render error tag and also hasError for each field.
def update (){
def myProfile = new Profile()
dataBind(params, myProfile, include:[.....])
if (myProfile.hasErrors()){
respond myUser.errors, view: 'editProfile'
return
}
else{
redirect(action:"viewProfile")
}
}
My gsp is something like this, I don't have access to my home computer right now to post the exact gsp page:
<g:hasErrors bean="${myUser}" field="name">
<g:message error="${myUser.errors.getFieldErrors("name")}" />
</g:hasErrors>
Instead of trying to pass the errors back, pass the entire object to your gsp. Assuming the bean you have in your gsp page is 'myUser', then this is what the render statement should be:
render view: 'editProfile', model: [myUser: myProfile]
When you use respond bean.errors, the bean will be called based on class name, not variable name.
In your case, you need to access the bean in you gsp as profile like so:
//variable in controller
def myProfile = new Profile()
//bean in views
<g:hasErrors bean="${profile}" field="name">
<g:message error="${profile.errors.getFieldErrors("name")}" />
</g:hasErrors>
If you need to call your bean with a specific name like myUser, just pass it in the model:
render (view:'editProfile', model:[myUser: myProfile])

Syntax Issue- Razor MVC4

I'm trying to display a partial view using a custom helper method. The only problem is, I can't get past this syntax issue. The model set for this cshtml file is an IEnumerable collection of models I've defined as Operation. I'm sure this is an easy fix. Here's an example of what I'm seeing:
I have this block of code:
#using(Html.BeginForm()) {
<div id="editor_rows">
#foreach (var item in Model){
Html.RenderPartial("OperationEditorRow", item);
}
</div>
}
This gives me the following error at runtime:
Unexpected "{" after "#" character. Once inside the body of a code block (#if {}, #{}, etc.) you do not need to use "#{" to switch to code.
But if I remove the # sign in front of the foreach statement, everything is interpreted as plain text. So I tried placing an # in front of Html as follows:
#using(Html.BeginForm()) {
<div id="editor_rows">
#foreach (var item in Model){
#Html.RenderPartial("OperationEditorRow", item);
}
</div>
}
This comes back with a compilation error that says:
Cannot implicitly convert type void to object
If I run the project from here, I get a runtime error that says:
The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments
I'm assuming this is related to the previous error. If anybody has a suggestion for me, please help.
Problem solved. I worked on this with a coworker. It turns out the error refferring to the write method pointed to a problem inside my partial view. I was using #{} around a block of code inside of there, which was most likely throwing the other syntax errors also. Thanks for the responses.
Add {}'s around your render call like #{RenderPartial...}

how to display images in Grails?

I am trying to render the images from /WEB-INF/images/sps in the GSP page using the following code:
def index = {
def baseFolder = grailsAttributes.getApplicationContext().getResource("/").getFile().toString()
println baseFolder
def imagesFolder = baseFolder + '/images/sps'
println imagesFolder
def imageList1 = new File(imagesFolder).list()
println imageList1
def imageList = Arrays.asList(imageList1)
println imageList
imageList
//redirect(action:"displayImages", params:["imageList":imageList])
//render(view:"displayImages")
}
The controller is able to read the images from the fileSystem. But when I try to display them using the following code, the images are not coming.
index.gsp
<g:each in="${imageList}" var="image">
<img src="${resource(dir: 'images', file: image.filename)}" alt="Grails"/>
</g:each>
What mistake am I doing?
EDIT:
When I try with single image, it is working fine - I am able to view the image that is in the WEB-INF/images folder
<img src="${resource(dir: 'images', file: '1.jpg')}" alt="Grails"/>
And there is no HTML code thats getting generated for the loop code(above index.gsp code). Its just blank.
My requirement is to display all the image files that are on the file system folder.
It was simpler. You should return a model from an action as a Map: [imageList: imageList] for imageList to be available by name in GSP.
And yes, can you move images folder to web-app - is it OK that all the world can request your images via HTTP?
you are returning a list of File objects, where you will call the toString method of the file object which most likely returns the absoute file path of the file object.
this would give you something like this in the html source code
<img src="/app/images/c:\path\to\imagefile.png">
try calling
<img src="${resource(dir: 'images', file: image.name)}" alt="Grails"/>
and if that doesnt work, show us the html code that it produces.
In light of new knowledge, the above won't work. The return of File.list() is actually String[] where each string is a file name rather than a complete path.
Anyways, getting a look at the html source would shed light on what exactly gets printed out.
I suspect that maybe g:each doesn't support iterating over simple array types like String[], you could try converting it to a List.
def imageList = Arrays.asList(new File(imagesFolder).list())
Have you tried converting it to a list and using g:each with that?
why are you storing your images in WEB-INF/images? why not just images? i think the code ${resource(dir:'images')} would point to the latter.
You can't render images that are located under WEB-INF using the standard image tag. The images aren't web accessible. You'll need another controller that will stream the images back to the view for you. So something like this:
class AvatarController {
def show = {
def userInstance = User.get(params.id)
def avatarFilePath = new File(userInstance.avatarURL)
response.setContentType("application/png")
response.setContentLength(avatarFilePath.size().toInteger())
OutputStream out = response.getOutputStream();
out.write(avatarFilePath.bytes);
out.close();
}
}
And then to display this image:
<img src="/app/avatar/1234" />
I'll let you work out the conversion of this into your own needs. The key, however, is that you must stream the image back since it isn't web accessible in its current location.
You're better off just serving them outside of WEB-INF, however.
don't store data in WEB-INF, store your images in /web-app/images/
in your controller:
def baseFolder = servletContext.getRealPath("/")
def folder = baseFolder + '/images/' // web-app/images/
def imagesFolder = new File(folder)
def files = imagesFolder.listFiles().toList()
List<String> imageList = []
files.each {
imageList.add(it as String)
}
return imageList
3 in your view:
<g:each in="${imageList}" var="image">
<img src="${resource(dir: 'images', file: image)}" alt="Grails"/>
</g:each>

How to load Blobproperty image in Google App Engine?

I wrote some codes.
I could save image in BobProperty.
But I cannot load image into HTML page...
source code:
class Product(db.Model):
image = db.BlobProperty()
...
class add:
productImage = self.request.get('image')
product.image = db.Blob(productImage)
product.put()
but i wrote {{product.image}} into html code. But there were like ��袀 ���� ���� ���� (����������� ��(:(������� (������� (��>̢��� (�������>������Y������K��׏
What should i do if i want load image from datastore?
I use an auxiliary view:
def serve_image(request, image):
if image == "None":
image = ""
response = HttpResponse(image)
response['Content-Type'] = "image/png"
response['Cache-Control'] = "max-age=7200"
return response
and in the model:
def get_image_path(self):
# This returns the url of serve_image, with the argument of image's pk.
# Something like /main/serve_image/1231234dfg22; this url will return a
# response image with the blob
return reverse("main.views.serve_image", args=[str(self.pk)])
and just use {{ model.get_image_path }} instead.
(this is django-nonrel, but I guess you could figure out what it does)
Also, there is a post here about this; you should check it out.

Resources