Handling Images saved to the database with Symfony - symfony

I'm having issues with a small and trivial application that I created to help me learn Symfony 3. The Application simple allows me to upload an image when I create a new blog post.
I'm using the Symfony 3 documentation to learn about uploading file, and in it, it suggests that I rename the file to a unique name using the md5() hash method to request a strange looking name for the file.
Everything works find until I want to display the image in the index.html.twig file. I was under the impression that I could simply use the asset() method that I was using to import bootstrap and other publicly viewable files, and then simply append the file name to the end of that. But nothing seems to work.
Here are some things that I have tried.
<img src="{{ asset('blog/images/') }}{{ blog.imageUrl }}">
<img src="{{ asset('blog/images/', { 'imageUrl': blog.imageUrl }) }}">
<img src="{{ asset('blog/images/' . blog.imageUrl) }} ">
And there is probably a few more different combinations that I have tried but can remember. Now I have since found the documentation that talks a little about the asset() method, but there is nothing there that seems to state that you can use it and then just append the file name to the end of it, And I haven't found any information that allows me to point directly to the web directories, where the blog/images folder now lives. So any help with this would be awesome. Thank you so much.

Not knowing the content of blog.imageUrl its hard to know what is expected. My guess for the 'correct' answer to your question is that you were very close with option #3, however in twig string concatenation is done using the ~ symbol and not .
So in your case you would use <img src="{{ asset('blog/images/' ~ blog.imageUrl) }}" />
Regards

Make sure that the new name of the file matches the name stored in the database. That and make sure the path you're using is correct.

Related

How to configure LiipImagineBundle to use a dynamic image stored in S3 as watermark?

I'm using LiipImagineBundle and AWS SDK in one project. Everything works fine, but now I want to create a watermark filter. In the Liip doc, they say we must inform in the configuration what the path of the watermark image is.
My problem is that this path is dynamic as it can change from one image to another. And it is also stored in S3.
In an older version of Liip, I had extended the ImagineController to added some logic. However, the bundle has completely changed and what I used to do don't work anymore.
I also saw a solution on github where the developer was adding a configuration to the filter in twig. I tried it but it didn't work:
{% set runtimeConfig = {"watermark": {"size": 1, "image": 'http://' ~ amazon_s3_media_url ~ '/establishment/' ~ establishment.watermarkPath, "position": 'bottom' }} %}
{% set url_photo_medium = photo.imagepath | imagine_filter('photo_high', runtimeConfig) %}
<img src="{{ url_photo_medium }}" alt="">
I'm not sure this would be a great solution even if it works because it is not dynamic. Does anybody know what the best solution for this problem is?
Thanks!
After searching on Github and other sites, I learned that it's not yet possible to use an image stored on S3 as watermark. The reason is that the filter watermark doesn't accept an URL as image path. So the solution is to store the watermark image on the local filesystem.
Moreover, for the dynamic filter, there's a runTimeConfig that can be used directly on Twig:
{% set runtimeConfig = {"thumbnail": {"size": [50, 50] }} %}
<img src="{{ '/relative/path/to/image.jpg' | imagine_filter('my_thumb', runtimeConfig) }}" />

Twig - how to efficiently re-use code

I have a page where I render details of many users. Each user's html is quite heavy (tooltips etc.) so I don't want to copy/paste the same code. I'd like to reuse the same code on different pages as well.
I was using include with parameters but I'm not sure how good the performance will be. Is it better to make a Twig extension and just have there functions producing html based on passed User instance? Or is there another, better approach?
EDIT:
This is the kind of code I'm rendering in multiple places on multiple pages.
<span data-tooltip aria-haspopup="true" class="has-tip" title="{{ user.getJob }}, {{ user.getCompanyy.getName }}">
{{ user.getFirstName }}, {{ user.getLastName }}
</span>
Include is a very good solution and fit exactly your needs.
You could use macros too (documentation). But try to do not use include nor require in a macro because if you have an error in the included template, the line of the error will be the line where you called the template (not the one where you really have a bug) so it could become very difficult to debug.
And like you said, Twig extension could be good too for specifics cases. For instance, if you want to display a price, it's better to make your |price extension instead of include a little template. But extensions are better for highly reusable codes and shorts templates.
By the way, the worst case is using render(controller(...)) only in order to display a template because it's very consuming in terms of memory.
Answer to Edit:
Here you will find a benchmark: So extension seems to be the best solution in case of very lot of parameters. In your simple case, both solutions are good. Personnally, I prefer to use includes when I have lot of HTML and few parameters. But it's very a question of what you prefer.
You could even imagine doing both.
include of the html widget
and an extension in order to concatenate user firstname and lastname
Like this:
<span data-tooltip aria-haspopup="true" class="has-tip" title="{{ user.getJob }}, {{ user.getCompanyy.getName }}">
{{ user|fullName }}
</span>
In conclusion, Twig provides lot of differents tools and it's up to you to choose the once that fits your needs.

Twig absolute path variable in include

my script defines a absolute path in PHP and gives it to the twig template with the render()-function. All works well, I can access my variables with {{ varName }} in the view. But if I try to use a absolute path as a variable inside a include-command like {% include varName %} it will say: Unable to find template. This will even happen if the absolute path is correct.
What am I missing here?
Well it's weird but unfortunately I had no possibility to include a file from somewhere else not in the specific symfony structure. So I had to move all contents to the view folder.
I hope someone fixes this, which is anything but flexible.
To add template search paths to Twig_Loader_Filesystem, you can use
$loader->addPath($templateDir);
or
$loader->prependPath($templateDir);
Where $templateDir is a parent directory and $loader is the variable containing your Twig_Loader_Filesystem object. In your example, you would want $templateDir to be the path where the Bundle directory is located.
Then, in your include do something like this:
{% include 'Bundle\Somedir\somefile.html.twig' %}
Twig will then search all paths in looking for Bundle\Somedir\somefile.html.twig and will return the first one it finds.
The Twig documentation on this subject can be found here: http://twig.sensiolabs.org/doc/api.html#twig-loader-filesystem
Note: Choice of using addPath or prependPath depends on which order you'd like Twig to search the directories in. Paths added using prependPath will be searched before any of the previously loaded paths.
Caution: The search order applies to all templates so if the path/filename you use in the include statement is not unique, you could end up overriding another template.

How to get absolute file system path to an image Symfony2/Twig

I am using Symfony2 with twig to generate HTML, however the HTML I am generating is not intended for a web browser, instead it will be passed to a library that converts HTML to a PDF document.
There are two related issues I am facing.
Issue 1. This PDF will have images included, I don't want these images to be visible directly from the internet (e.g. I don’t want these images to appear under webroot). Usually I put assets in “site/src/path-to-bundle/Resources/public/assets” however, I don't want this image to be visible on the web. Can anyone suggest a good folder to put “assets” in that are not meant to be accessible via the web. (Just trying to be consistent with Symfony2 naming techniques and how other programmers would usually do this)
Issue 2. Since the HTML I am generating is intended for the HTML to PDF generator, it is most practical to refer to images with absolute paths on the file system (web paths or URLs are not suitable in this situation).
For example
<!-- This is the correct HTML code that is needed in this situation -->
<img src="/home/user/absoulte-file-system-path-to/image.png" />
<!-- These are actually incorrect in this situation -->
<img src="assets/image.png" />
<img src="http://www.somedomain.com/assets/image.png" />
I would like to know how to get the absolute path to the image mentioned above (I don’t mind if this is done in the Twig template or in the controller)
in you app/config/config.yml
twig:
globals:
root_path: %kernel.root_dir%
and you can refer to asset with relative path to your root project
<img src="{{ root_path }}/../secret-folder/image.png" />

Plone 4 Zope Display Contents of specific folder TALES

Problem
I have a customer that wishes to display the entire contents of a certain folder (containing images) on their search page, should the search return 0 results. The folder is located at mysite.com/images
Setup:
As a test environment I have setup a seperate site with the following structure:
ROOT
|-Folder1 <-- current directory I am viewing
| |-images
|-Other folders
I modified the folder_summar_view template, to include the following code (I decided to modify a view to see if I could hack that to pieces to make it do what I want):
<div tal:define="image context/images/getFolderContents">
<div tal:content="i" tal:repeat="i image" />
</div>
What I see:
<Products.ZCatalog.Catalog.mybrains object at 0x9d2ddb8>
Things I've tried and further explanations
I was under the assumption that when the context/images/getFolderContents returns a brain for the 'objects' in my images folder, I could then iterate through each 'object' using my tal:repeat statement below it. Then display them on my page.
If I just use the following code:
<div tal:content="context/images/getFolderContents" />
My output is very similar to the above 'What I see' section:
<Products.ZCatalog.Catalog.mybrains object at [...]>
where [...] is another number
I've been doing some research and reading the Plone Theming book, but my code is similar to their tal:repeat examples on page 169, it seems the only difference is they are not using this on a brain (as far as I can tell).
I tried this, although it produced the same results (not sure why I tought it wouldn't):
<div tal:define="image python:context.images.getFolderContents()">
<div tal:content="i" tal:repeat="i image" />
</div>
I don't seem to be able to 'get inside' the returned brain. Everything I've looked for online doesn't quite help that much, I've also trawled through the atct_album_view and folder_listings templates to know avail. - I think I'm overlooking or missing something.
The first link I stumbled across was this, however I have moved on since that as although similar, it's not quite what I was trying to do.
The Plone guys on their chat room were kind enough to give me the context/images/getFolderContents statement, I tried to press on without asking for help again but it seems I've hit a wall.
More stuff I've tried
Using this link as inspiration I decided to try the following:
<div tal:define="image context/images/getFolderContents">
<div tal:content="image/getURL" />
</div>
But that throws an error when I try to view the template. The error reads along the lines of the 'getFolderContents brain does not have the attribute getURL' - Although image/Title displays the name of the folder, but that's not really what I need.
I also found this link however because I am making use of the default search, I don't really want to have to edit python scripts as I fear it may adversely effect the normal Plone site search. Also in this link they seem to be making use of more Python scripts. - To expand on this point, I'm not sure on how these scripts 'link' with page templates (how they know to 'talk' to one another).
Conclusion
In conclusion I need to display all of the images contained within a folder named "images" located at the root of my site, I am unable to access the contents of a returned brain using getFolderContents. And other than displaying the title of the "images" folder or the brain identifcation (<Products.ZCatalog.Catalog.mybrains object at 0x9d2ddb8>) , I have had no luck. Any help or ideas welcomed!
As getFoldercontents returns a list of brains i cant see how your code can work.
Just repeat over it with something like that :
<tal:block tal:repeat="image context/images/getFolderContents">
<a tal:attributes="href image/getURL" tal:content="image/Title"/>
</tal:block>

Resources