I have created a function file name as
<?php
use Ens\NewBundle\Controller\Services\MyMailers as MyMailers;
function NotificationOnSignUp($z)
{
$x=new MyMailers;
$x->setToloc($z['to']);
$x->setFromloc('ucerturohit#gmail.com');
$x->setSubject('Wonderful world');
$x->setBody('Hello world');
$z=$x->mail();
if($z==1)
$name='success';
else
$name='failed';
return $this->render('EnsNewBundle:Email:ind.html.twig',array('name'=>$name));
// return $z;
}
this file is not in the controller but I want to render my twig file in this file or I want to set this twig file as Body of the mail. how can i do this??
Create a service, inject the templating service into it and use it to render the template.
Related
I have extended CMS settings to upload two CSS files. Part of the SiteConfig extension code -
<?php
//OTHER CODES HERE
$fields->addFieldToTab('Root.Main', $cssfile = UploadField::create(
'StyleSheet',
'Style Sheet'
));
$fields->addFieldToTab('Root.Main', $clientcssfile = UploadField::create(
'ClientStyleSheet',
'Client Style Sheet'
));
//OTHER CODES HERE
?>
And i have extended the File class
class FileRenameExtension extends DataExtension {
function onAfterUpload() {
$file = $this->owner;
$file->Name = 'CustomStyle.'.$file->getExtension();
$file->write();
}
}
PROBLEM
The code renames the file uploaded from all the fields, but I want to rename the files uploaded from ClientStyleSheet only.
Before it renames the file, if user uploads file with name that already exists, it warns, and if I click Overwrite, it overwrites the files and renames the file. I just want no matter what is the file name, it just saves the file with name that is specified in the File Extension Class
What is the proper way to rename file before its get uploaded?
You better use FileField directly in your case with custom upload() action handler.
With the DataExtension, you modify all instances of File, wherever they are uploaded.
One possible solution: You subclass File and hook into onAfterUpload:
class CSSFile extends File {
function onAfterUpload() {
$file = $this;
$file->Name = 'CustomStyle.'.$file->getExtension();
$file->write();
parent::onAfterUpload();
}
}
Now you use this in your SiteConfig, it should work with UploadField just like a standard File.
If I understand it correctly, you want to enable the user to add a stylesheet to the site. A different solution would then be to allow any filenames and to use the original filename in the template:
<link rel="stylesheet" href="$SiteConfig.StyleSheet.URL">
I would prefer to use this second solution.
I do have a twig extension which has a method that uses another method from a different controller to render a json output via dependency jsonResponse.
How can I render a controller within a twig extension?
The following code below doesn't seem to work, because render() needs a view file instead of a controller. And I am now referencing to a controller.
class AreaExtension extends \Twig_Extension {
public function add()
{
$outputJson = $this->container->get('templating')->render(new ControllerReference('CMSCoreBundle:Area:index'));
}
}
$ref = new ControllerReference('CMSCoreBundle:Area:index');
$this->handler->render( $ref, 'inline', $options );
Where $this->handler is the fragment.handler service.
In your case:
$outputJson = $this->container->get('fragment.handler')->render(new ControllerReference('CMSCoreBundle:Area:index'));
You can find a full example in this symfony twig extension, see:
https://github.com/symfony/symfony/blob/4.1/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php#L28
and
https://github.com/symfony/symfony/blob/4.1/src/Symfony/Bridge/Twig/Extension/HttpKernelRuntime.php#L41
Am not very familiar with twig, am trying to get an image extention, but am not sure how to do this in twig ,in php it's very easy using string functions such as substr and indexof or with the following: ext=pathinfo('/testdir/dir2/image.gif', PATHINFO_EXTENSION), i don't want to code it in controller and pass it to twig as parameter,instead i want to extract it directly in the twig layout,so how am going to do this?
You can get file extension by this way
{{ "filename.txt"|split('.')|last }}
One approach would be to use Twig's slice filter.
For example, if the path to your image file is imgSrc, then imgSrc|slice(-4) will give you the last 4 characters of the filename (eg. .gif, .jpg, jpeg).
You can create Twig extension, that will contain
namespace YourApp\AcmeBundle\Twig;
class MyTwigExtension extends \Twig_Extension
{
public function getFilters(){
return array(
new \Twig_SimpleFilter('ext', array($this, 'ext')),
);
}
public function ext($filepath){
$ext = pathinfo($filepath, PATHINFO_EXTENSION);
return $ext;
}
}
In twig, use the split filter. see http://twig.sensiolabs.org/doc/filters/split.html
you can also simply get the extension in the controller and pass it to twig.
I need a simple way to fallback on a default template if no mobile version exists.
With some regular expressions I recognize mobile platforms and want to render a template with the following pattern:
<template_name>.mobile.html.twig
But if this template doesn't exist, I want it to automatically fallback on:
<template_name>.html.twig
which always exists.
I tried nearly all the answers from this post:
Symfony 2 load different template depending on user agent properties
but with no success. Unfortunately there are no version numbers referenced.
At the moment I am trying to copy and modify the default twig loader.
By the way, What I want to achieve with this is the possibility to deploy different templates for mobile devices by just adding a template of the same name and adding a .mobile.
UPDATE:
http://www.99bugs.com/handling-mobile-template-switching-in-symfony2/
This one is also a good approach. It modifies the format property of the request object which affects the automatic template guessing when you don't specify a template in the controller with the render function (or annotation) but just return an array.
Resulting template name:
view/<controller>/<action>.<request format>.<engine>
So you could switch the request format from html to mobile.html based on the device detection.
The downside of this is that every template needs a mobile.html pendant (which then could just include the non-mobile version if not needed).
UPDATE:
Besides using a custom templating provider there is also the possibility to hook into the kernel.view event.
You could create a service to handle it and then use it in the same way that you do the templating service like so..
Create a service with the templating and request service injected into it..
Service (YAML)
acme.templating:
class: Acme\AcmeBundle\Templating\TemplatingProvider
scope: request
arguments:
- #templating
- #request // I assume you use request in your platform decision logic,
// otherwise you don't needs this or the scope part
- 'html'
Class
class TemplatingProvider
{
private $fallback;
private $platform;
... __construct($templating, $request, $fallback) etc
private function setPlatform() ... Your platform decision logic
private function getPlatform()
{
if (null === $this->platform) {
$this->setPlatform();
}
return $this->platform;
}
private function getTemplateName($name, $platform)
{
if ($platform === 'html') {
return $name;
}
$template = explode('.', $name);
$template = array_merge(
array_slice($template, 0, -2),
array($platform),
array_slice($template, -2)
);
return implode('.', $template);
}
public function renderResponse($name, array $parameters = array())
{
$newname = $this->getTemplateName($name, $this->getPlatform());
if ($this->templating->exists($newname)) {
return $this->templating->render($newname);
}
return $this->templating->renderResponse($this->getTemplateName(
$name, $this->fallback));
}
And then you could just call your templating service instead of the current one..
return $this->container->get('acme.templating')
->renderResponse('<template_name>.html.twig', array());
Can't you check if the template exist before ?
if ( $this->get('templating')->exists('<templatename>.html.twig') ) {
// return this->render(yourtemplate)
} else {
// return your default template
}
OR :
You can create a generic method, to insert in your root controller like :
public function renderMobile($templateName, $params)
{
$templateShortName = explode('.html.twig', $templateName)[0];
$mobileName = $templateShortName.'.mobile.html.twig';
if ( $this->get('templating')->exists($mobileName) ) {
return $this->renderView($mobileName, $params);
} else {
return $this->renderView($templateName, $params)
}
}
with this you can do :
return $this->renderMobile('yourtemplate', [yourparams]);
You can easily do this by harnessing the bundle inheritance properties in Symfony2 http://symfony.com/doc/current/cookbook/bundles/inheritance.html
create a bundle which holds your desktop templates (AcmeDemoDesktopBundle)
create a bundle which will hold your mobile templates (AcmeDemoMobileBundle) and mark the parent as AcmeDemoDesktopBundle
Then when you render a template simply call AcmeDemoMobileBundle:: - if the template exists, it'll be rendered otherwise you'll neatly fall back to the desktop version. No extra code, listeners or anything none-obvious required.
The downside of this of course is that you move your templates out of the individual bundles.
The fallback behavior you describe isn't that easy to implement (we found out the hard way..). Good news is we wanted the same setup as you ask for and ended up using the LiipThemeBundle for this purpose. It allows you to have different "themes" based on for example a device. It will do the fallback part for you.
For example:
Rendering a template:
#BundleName/Resources/template.html.twig
Will render and fallback to in order:
app/Resources/themes/phone/BundleName/template.html.twig
app/Resources/BundleName/views/template.html.twig
src/BundleName/Resources/themes/phone/template.html.twig
src/BundleName/Resources/views/template.html.twig
Edit: so with this approach you can have default templates that will always be the final fallback and have a special template for mobile where you need it.
I have created two functions in controller of Symfony as follow:
first is newAction
public function newAction()
{
return $this->render('AcmeTaskBundle:Default:index.html.twig');
}
then subAction
public function subAction()
{
echo "hello";
}
I want to use some data from index.html.twig into subAction function.
How I can do that?
All you need is to use
$content = $this->renderView('AcmeTaskBundle:Default:index.html.twig')
This will render contents of template in variable
http://symfony.com/doc/current/book/controller.html#rendering-templates
EDIT according to comment
If you need to render only part of template - then you should refactor your templates.
Exclude that part of code from your index.html.twig into separate template file and include it in index.html.twig:
...
{% include 'AcmeTaskBundle:Default:subpage.html.twig' %}
...
And then in your subAction() call:
$content = $this->renderView('AcmeTaskBundle:Default:subpage.html.twig')