I'm new to grails (1.3.7) and I've been put in a strange situation with displaying an image from the filesystem. The one.png picture is put into web-app/images/fotos directory. The zz.gsp:
<img src="${resource(dir:'images/fotos', file:'one.png')}" alt="Nothing" />
related to the void action def zz = {} works fine. But if I intend to display the same picture in rawRenderImage.gsp:
<body>
<p>
${fdir} <br/> ${fname} <!-- OK -->
</p>
<g:if test="${fname}">
<img src="${resource(dir:'fdir',file: 'fname')}" alt ="Nothing"/>
</g:if>
</body>
the picture doesn't appear inspite of the parameters fdir and fname pass to the page. The action in the controller is:
def rawRenderImage = {
// def basePath = servletContext.getRealPath("/")
// def basePath = grailsAttributes.getApplicationContext().getResource("/").getFile().toString() + "/images/fotos/"
// def basePath = grailsAttributes.getApplicationContext().getResource("/").getFile().toString()
// def fname = params.photoId + ".png"
// def fname = "/images/fotos/" + params.photoId + ".png"
basePath = "images/fotos" // or basePath=”images” for /images/one.png
fname=”one.png”
[fdir:basePath, fname:fname]
}
Even direct assigns basePath=”images/fotos” and fname=”one.png” don't work, as well as any combinations with basePath to obtain the absolute path. Even the case when I put the picture in images directory doesn't work. I use netbeans, but it also doesn't work in console mode.
Help please.
When passing in your filename and directory as variables in the model, don't quote them in your tag's src attribute. Then the Groovy ${} evaluation will evaluate to the variables and not as Strings.
<g:if test="${fname}">
<img src="${resource(dir:fdir,file:fname)}" alt ="Something"/>
</g:if>
Related
I use Vue. I try to output an image and it works fine when I use src but not when I use :src.
Works
<img src="../assets/image.png" />
Does not work
<img :src="`../assets/${image}.png`" />
What I've tried, but did not work
# first in the path.
~ first in the path.
./ first in the path.
/ first in the path.
require but it throws an error if the image can't load. I prefer the native broken image icon, which does not break the script.
My output
The variable image contains the filename which in this case would be image.
The output from both version is like below:
<img src="../assets/image.png" data-v-469af010=""> <!-- src -->
<img src="/img/image.f556f8c5.png" data-v-469af010=""> <!-- :src -->
For some reason they differ quite alot.
How can I solve it?
I solved this problem with this:
<img :src="cover(url)" /> // I call a method cover.
// Method cover
cover(url) {
if (url !== ''){ // You can check any matching expression.
try {
url = require('#/assets/img/' + url)
} catch (e) {
url = require('#/assets/img/default.jpg'); // I used a default image.
}
}
else
url = require('#/assets/img/default.jpg'); // Default image.
return url;
}
Bind src to the method.
getImgUrl(image) {
return `../assets/${image}.png`
}
in HTML
<img :src="getImgUrl(image)" />
If image variable is name of file
<img :src="'../assets/'+image" />
You should not use $ in template.
I have set of code for updating a password in the table, here I'm using CGI::AJAX module to update the password and get the popup screen on corresponding execution.When using that code with my application it is executing properly but I didn't get the output(means Perl subroutine is not called when JavaScript function to get use.password is not updated into table). I don't get any error either.
#!/usr/bin/perl -w
use strict;
use CGI;
use DBI;
use Data::Dumper;
my $p = new CGI qw(header start_html end_html h1 script link);
use Class::Accessor;
use CGI::Ajax;
my $create_newuser;
my $ajax = new CGI::Ajax('fetch_javaScript' => $create_newuser);
print $ajax->build_html($p,\&Show_html,{-charset=>'UTF-8', -expires=>'-1d'});
sub Show_html
{
my $html = <<EOHTML;
<html>
<body bgcolor="#D2B9D3">
<IMG src="karvy.jpg" ALT="image">
<form name='myForm'>
<center><table><tr><td>
<div style="width:400px;height:250px;border:3px solid black;">
<center><h4>Create New Password's</h4>
<p>  User Name</b>       <INPUT TYPE="text" NAME="user" id = "user" size = "15" maxlength = "15" tabindex = "1"/></p>
<p>  Password:</b>         <INPUT TYPE=PASSWORD NAME="newpassword" id = "newpassword" size = "15" maxlength = "15" tabindex = "1"/></p>
<p>  Re-Password:</b>   <INPUT TYPE=PASSWORD NAME="repassword" id = "repassword" size = "15" maxlength = "15" tabindex = "1"/></p>
<input type="submit" id="val" value="Submit" align="middle" method="GET" onclick="fetch_javaScript(['user','newpassword','repassword']);"/><INPUT TYPE="reset" name = "Reset" value = "Reset"/>
<p>Main Menu <A HREF = login.pl>click here</A>
</center>
</div>
</td></tr></table></center>
</form>
</body>
</html>
EOHTML
return $html;
}
$create_newuser =sub
{
my #input = $p->params('args');
my $user=$input[0];
my $password=$input[1];
my $repassword=$input[2];
my $DSN = q/dbi:ODBC:SQLSERVER/;
my $uid = q/123/;
my $pwd = q/123/;
my $DRIVER = "Freetds";
my $dbh = DBI->connect($DSN,$uid,$pwd) or die "Coudn't Connect SQL";
if ($user ne '')
{
if($password eq $repassword)
{
my $sth=$dbh->do("insert into rpt_account_information (user_id,username,password,user_status,is_admin) values(2,'".$user."','".$password."',1,1)");
my $value=$sth;
print $value,"\n";
if($value == 1)
{
print 'Your pass has benn changed.Return to the main page';
}
}
else
{
print "<script>alert('Password and Re-Password does not match')</script>";
}
}
else
{
print "<script>alert('Please Enter the User Name')</script>";
}
}
my $create_newuser;
my $ajax = new CGI::Ajax('fetch_javaScript' => $create_newuser);
...;
$create_newuser =sub { ... };
At the moment when you create a new CGI::Ajax object, the $create_newuser variable is still undef. Only much later do you assign a coderef to it.
You can either assign the $create_newuser before you create the CGI::Ajax:
my $create_newuser =sub { ... };
my $ajax = new CGI::Ajax('fetch_javaScript' => $create_newuser);
...;
Or you use a normal, named subroutine and pass a coderef.
my $ajax = new CGI::Ajax('fetch_javaScript' => \&create_newuser);
...;
sub create_newuser { ... }
Aside from this main error, your script has many more problems.
You should use strict instead of the -w option.
For debugging purposes only, use CGI::Carp 'fatalsToBrowser' and sometimes even with warningsToBrowser can be extremely helpful. Otherwise, keeping a close eye on the error logs is a must.
my $p = new CGI qw(header start_html end_html h1 script link) doesn't make any sense. my $p = CGI->new should be sufficient.
use Class::Accessor seems a bit random here.
The HTML in Show_html is careless. First, your heredocs allows variable interpolation and escape codes – it has the semantics of a double quoted string. Most of the time, you don't want that. Start a heredoc like <<'END_OF_HTML' to avoid interpolation etc.
Secondly, look at that tag soup you are producing! Here are some snippets that astonish me:
bgcolor="#D2B9D3", align="middle" – because CSS hasn't been invented yet.
<center> – because CSS hasn't been invented yet, and this element isn't deprecated at all.
<table><tr><td><div ... </div></td></tr></table> – because there is nothing wrong with a table containing a single cell. (For what? This isn't even for layout reasons!) This table cell contains a single div …
… which contains another center. Seriously, what is so great about unneccessary DOM elements that CSS isn't even an option.
style="width:400px;height:250px;border:3px solid black;" – because responsive design hasn't been invented yet.
<p> ... </b> – Oh, what delicious tag soup!
        – this isn't a typewriter, you know. Use CSS and proper markup for your layout. There is a difference between text containing whitespace, and empty areas in your layout.
tabindex = "1" … tabindex = "1" … tabindex = "1" – I don't think you know what tabindex does.
<A HREF = login.pl> – LOWERCASING OR QUOTING YOUR ATTRIBUTES IS FOR THE WEAK!!1
onclick="fetch_javaScript(['user','newpassword','repassword']);" – have you read the CGI::Ajax docs? This is not how it works: You need to define another argument with the ID of the element where the answer HTML is displayed.
In your create_newuser, you have an SQL injection vulnerability. Use placeholders to solve that. Instead of $sth->do("INSERT INTO ... VALUES('$foo')") use $sth->do('INSERT INTO ... VALUES(?)', $foo).
print ... – your Ajax handler shouldn't print output, instead it should return a HTML string, which then gets hooked into the DOM at the place your JS function specified. You want something like
use HTML::Entities;
sub create_newuser {
my ($user, $password, $repassword) = $p->params('args');
my ($e_user, $e_password) = map { encode_entities($_) } $user, $password;
# DON'T DO THIS, it is a joke
return "Hello <em>$e_user</em>, your password <code>$e_password</code> has been successfully transmitted in cleartext!";
}
and in your JS:
fetch_javaScript(['user','newpassword','repassword'], ['answer-element'], 'GET');
where your HTML document somewhere has a <div id="answer-element" />.
I want display image in my View. But file isn't found, file exist.
string file = Server.MapPath("~") + #"/App_Data/Plakaty/" + wyd.WydarzenieId.ToString() + ".jpg";
ViewBag.file_exist = System.IO.File.Exists(file);
I try: (Is display only alt:)
#if (ViewBag.file_exist == true) // it's TRUE
{
<img src="../../App_Data/Plakaty/1029.jpg" alt="p" />
<img src="~/App_Data/Plakaty/1029.jpg" alt="p1" />
<img src="#Url.Content("~/App_Data/Plakaty/1029.jpg")" alt="image"/>
<img src="#Url.Content("../../App_Data/Plakaty/1029.jpg")" alt="image2"/>
}
<img src="../../App_Data/Plakaty/1029.jpg" alt="p" />
Taking this as example, is App_Data really in the path for the image to the outside world? Sometimes internal paths are different.
I changed the html "formatter" to embed my image using the following code:
#builder.div(:id => 'image') do
#builder << '<div style="float:center";><img SRC="/home/abc/cert-image.png" ALT="Image"> </div>'
end
The HTML file has the following tag but there is no encoded image inside the HTML page.
div id="image"><div style="float:center";><img SRC="/home/abc/cert-image.png" ALT="Image">
Now if I open this in a browser (Chrome), it does not show me the image. If I change this path above on my local laptop and point to an image, it works (i.e displays it correctly).
What am I missing ?
/home/abc/cert-image.png is a relative path from your HTML file. Nothing is wrong with the html or the formatter, but your path is likely wrong.
Try clicking where the image should be and opening the URL to the image in a new window. That will give you the absolute URL to where the img tag is pointing, and you can fix/debug from there.
EDIT
Ignore that, I found the error in your formatter:
#builder.div(:id => 'image') do
#builder << '<div style="float:center;"><img SRC="/home/abc/cert-image.png" ALT="Image" /> </div>'
end
EDIT 2
Since you just want to base64 encode the image with a data uri, you can do this:
require 'base64'
file = File.open("/home/abc/cert-image.png", "rb").read
b64 = Base64.encode64(file)
Then in your formatter:
#builder.div(:id => 'image') do
#builder << '<div style="float:center;"><img SRC="data:image/png;base64,' + b64 + '" ALT="Image" /> </div>'
end
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>