somebody can help me please. I'm new in CodeIgniter and Twig. I have declared in my controller the following:
$datasession = array(
'nick' => $sess_nick,
'login_ok' => true
);
$this->session->set_userdata($datasession);
redirect('app'); //app is a controller that render the template view.
then, the question is: How can I get those variables from the twig template? I tried using:
{{ session.userdata.nick }}
but it shows like empty string.
thanks by advance.
To add the session variable on your twig template, you have to add the following line in your Twig library or controller.
$datasession = array(
'nick' => $sess_nick,
'login_ok' => true
);
$this->session->set_userdata($datasession);
$this->_twig->addGlobal("session", $this->CI->session);
Then on your twig template, you can print the session like this
{{ session.userdata.nick }}
Since in CodeIgniter, the session stored by user is usually in the userdata array. Otherwise, you can just simply call the session variable and name
{{ session.nick }}
Src: http://llanalewis.blogspot.co.uk/2013/08/codeigniter-add-session-in-twig.html
Ok, thanks to Latheesan Kanes for your help. It was so much helpful your guideness. I want to share the way I solved this problem.
As Latheesan mentioned we have to use the addGlobal() method (I added this method in my Twig library folder)
like following:
$this->_twig->addGlobal("session", $this->CI->session);
But don't forget before to load the Session library. This way.
$this->CI->load->library('session');
This way you can have your session globally in all your twig views.
I'm using CodeIgniter 3RC3 and the Twig-Codeigniter library (thanks Erik & Bennet!).
To enable easy session access in twig, I added one line to the /application/libraries/Twig.php file's __construct() method:
public function __construct()
{
$this->_ci = & get_instance();
$this->_ci->config->load(self::TWIG_CONFIG_FILE); // load config file
// set include path for twig
ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . APPPATH . 'third_party/Twig/lib/Twig');
require_once (string)'Autoloader.php';
// register autoloader
Twig_Autoloader::register();
log_message('debug', 'twig autoloader loaded');
// init paths
$this->template_dir = $this->_ci->config->item('template_dir');
$this->cache_dir = $this->_ci->config->item('cache_dir');
// load environment
$loader = new Twig_Loader_Filesystem($this->template_dir, $this->cache_dir);
$this->_twig_env = new Twig_Environment($loader, array(
'cache' => $this->cache_dir,
'auto_reload' => TRUE));
// ADD SESSION TO TWIG - JZ
$this->_twig_env->addGlobal('session', $this->_ci->session);
// SESSION IS NOW AVAILABLE IN TWIG TEMPLATES!
$this->ci_function_init();
}
Now that we have our session loaded into our twig instance, we access session variables (such as CI's userdata) in our twig templates like so:
<span>__ci_last_regenerate: {{ session.userdata.__ci_last_regenerate }}</span>
phptwigcodeigniter
I successfully used session variables in Twig with this code:
In controller:
$datasession = array(
'language' => "PHP",
'framework' => "CodeIgniter"
);
$this->session->set_userdata($datasession);
$this->twig->addGlobal("session", $this->session);
In template:
{{ session.language }}
{{ session.framework }}
I'm using https://github.com/kenjis/codeigniter-ss-twig
Related
This is a continuation of a previous question.
Where is ->getForm() method located for Symfony3 CreateFormFactory
I got past that hurdle and now the system is unable to locate the template directory. I am still following the Symfony guide. https://symfony.com/doc/3.4/components/form.html#rendering-the-form
Referring to line 23 of the guide looks like the real directory needs to be passed to twig. See the image below for reference.
I know it looks redundant but It was an attempt to just tell Twig where the template is located. This returned an error.
Uncaught Twig\Error\LoaderError: The "C:\oerm_dev\www\dev\future5_2\vendor\symfony\twig-bridge../../templates/billing" directory does not exist ("C:\oerm_dev\www\dev\future5_2\vendor\symfony\twig-bridge../../templates/billing"). in C:\oerm_dev\www\dev\future5_2\vendor\twig\twig\src\Loader\FilesystemLoader.php:106
As you can see on the left where the template directory is located. It seems as though Twig wants to look in its own folder instead of the folder location is given. I have tried a couple of different variations.
$loader = new FilesystemLoader(['../../templates/billing',
$vendorTwigBridgeDirectory.'requeueCharge.html.twig']);
This produces an error also.
Uncaught Twig\Error\LoaderError: The "C:\oerm_dev\www\dev\future5_2\vendor\symfony\twig-bridge\requeueCharge.html.twig" directory does not exist
Which the error message is true, the location does not exist. But then I am still left with how to redirect twig to the folder where the view is located?
UPDATE
I just went ahead and created the folder and moved the layout.html.twig file to the location. Now the error message is
Uncaught Symfony\Component\Form\Exception\LogicException: No block "form_start" found while rendering the form.
Template.php(380): Twig\Template->displayWithErrorHandling(Array, Arr in C:\oerm_dev\www\dev\future5_2\templates\billing\requeueCharge.html.twig on line 8
Line 8 in that file reads as follows:
{% extends 'layout.html.twig' %}
{% block title %}{% endblock %}
{% block body %}
<div class="container">
<h3></h3>
{{ form_start(reportForm) }}
{{ form_widget(reportForm) }}
<button type="submit" class="btn btn-primary">Search</button>
{{ form_end(reportForm) }}
The problem was not in the template/billing but code needed to point to the built-in templates that come with the component twig-bridge. In the example, the folder Resource/views/Forms is a real directory that has to be used.
What I found out is that I need to read more closely and investigate every line of code that is presented. So, that is a self-evaluation. This is what solved the riddle.
I ended up with this:
use Symfony\Bridge\Twig\Extension\FormExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
use Symfony\Component\Form\FormRenderer;
use Symfony\Component\Form\Forms;
use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;
use Symfony\Component\Security\Csrf\CsrfTokenManager;
use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
use Symfony\Component\Translation\Loader\XliffFileLoader;
use Symfony\Component\Translation\Translator;
use Twig\Environment;
use Twig\Extension\DebugExtension;
use Twig\HeaderExtension;
use Twig\Loader\FilesystemLoader;
use Twig\RuntimeLoader\FactoryRuntimeLoader;
class RequeueChargesController extends Controller
{
public function requeueCharge()
{
$defaultFormTheme = 'form_div_layout.html.twig';
$vendorDirectory = dirname(__DIR__, 2).'\vendor';
$translator = new Translator('en');
$translator->addLoader('xlf', new XliffFileLoader());
//$form->handleRequest();
$session = new Session(new PhpBridgeSessionStorage());
$csrfGenerator = new UriSafeTokenGenerator();
$csrfStorage = new SessionTokenStorage($session);
$csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);
$appVariableReflection = new \ReflectionClass('\Symfony\Bridge\Twig\AppVariable');
$vendorTwigBridgeDirectory = dirname($appVariableReflection->getFileName());
$loader = new FilesystemLoader(['../../templates/billing/',
$vendorTwigBridgeDirectory.'/Resources/views/Form']);
$twig = new Environment($loader, [
'debug' => true,
]);
$twig->addExtension(new HeaderExtension());
$twig->addExtension(new DebugExtension());
$twig->addExtension(new TranslationExtension($translator));
$formEngine = new TwigRendererEngine([$defaultFormTheme], $twig);
$twig->addRuntimeLoader(new FactoryRuntimeLoader([
FormRenderer::class => function () use ($formEngine, $csrfManager) {
return new FormRenderer($formEngine, $csrfManager);
}
]));
$twig->addExtension(new FormExtension());
$formFactory = Forms::createFormFactoryBuilder()
->addExtension(new HttpFoundationExtension())
->addExtension(new CsrfExtension($csrfManager))
->getFormFactory();
$form = $formFactory->createBuilder(TaskType::class)
->getForm();
return $twig->render('requeueCharge.html.twig', [
'payments' => 'Charge',
'reportForm' => $form->createView()
]);
}
}
The example code that was given in https://symfony.com/doc/3.4/components/form.html#rendering-the-form needed little alteration to work.
You can compare the example with what I had to do to get it working in the OpenEMR codebase. If you have any questions, try me.
I am trying to upload file with Symfony3 but with no luck. I have a Profile entity which is linked to User entity with 1-1 relationship. The profile contains a picture column.
I have created a ProfileType and Profile Model. Upon submitting the form, the model contains only the File name and nothing else. The $_FILES array is also empty. This is the code.
$builder
->add("name", TextType::class, array(
"required" => true,
))
->add("email", EmailType::class, array(
"required" => true,
))
->add("city", TextType::class, array(
"required" => false,
))
->add("country", ChoiceType::class, array(
"required" => false,
))
->add("picture", FileType::class, array(
"required" => false,
));
class ProfileModel
{
private $name;
private $email;
private $city;
private $country;
private $picture;
In Controller I am creating the form like this.
$profileForm = $this->createForm(ProfileType::class, $profileModel);
When I get the picture, It contains just the name.
$file = $profileForm->get("picture")->getData();
Hewwo rashidkhan~
Symfony doc is quite complete on the upload process, did you read it?
http://symfony.com/doc/current/controller/upload_file.html
After a few modifications, I choose to use it as service.
Here is the process:
1) Add a few parameters to app/config/config.yml:
under parameters:
parameters:
locale: en
profile_directory: '%kernel.root_dir%/../web/upload/profile'
another_directory: '%kernel.root_dir%/../web/upload/another'
under twig
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
globals:
profile_directory: '/upload/profile/'
another_directory: '/upload/another/'
The two profile_directoryadded just now will be used as variables in both your upload service and twig to point the targer directory.
I added another_directory to explain something more a bit after.
2) Create the service:
Create a new file under src/YourBundle/Services/FileUploader.php
From here, my code is a bit different than what you can find on the Symfony site.
FileUploader.php content:
<?php
namespace YourBundle\Services;
use YourBundle\Entity\ProfileModel;
use YourBundle\Entity\Another;
class FileUploader {
private $profileDir;
private $anotherDir;
public function __construct($profileDir) {
$this->profileDir=$profileDir;
$this->anotherDir=$anotherDir;
}
public function upload($class) {
if($class instanceof ProfileModel) {
$file=$class->getPicture();
$fileName='picture-'.uniqid().'.'.$file->guessExtension();
$file->move($this->profileDir, $fileName);
$class->setPicture($fileName);
}
if($class instanceof Another) {
$file=$class->getPicture();
$fileName='picture-'.uniqid().'.'.$file->guessExtension();
$file->move($this->anotherDir, $fileName);
$class->setPicture($fileName);
}
return $class;
}
}
3) Register the service to app/config/services.yml:
under services:
services:
app.file_uploader:
class: YourBundle\Services\FileUploader
arguments:
- '%profile_directory%'
- '%another_directory%'
Each argument must be in the same order as your privatein the FileUploader.php file.
Those arguments are the ones we setted in app/config/config.yml under parameters.
4) Edit your controller:
The controller part is quite simple.
Add use Symfony\Component\HttpFoundation\File\File; in the import section
Under newAction
public function newAction(Request $request)
{
$profileModel = new ProfileModel();
$form = $this->createForm('YourBundle\Form\ProfileModelType', $profileModel);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// We upload the file with this line
$profileModel=$this->get('app.file_uploader')->upload($profileModel);
$em = $this->getDoctrine()->getManager();
$em->persist($profileModel);
$em->flush();
return $this->redirectToRoute('profile_model_show', array('id' => $profileModel->getId()));
}
return $this->render('YourBundle:Default:new.html.twig', array(
'profileModel' => $profileModel,
'form' => $form->createView(),
));
}
Under editAction
public function editAction(Request $request, ProfileModel $profileModel)
{
// Add this live above everything else in the code.
$profileModel->setPicture(new File($this->getParameter('profile_directory').'/'.$profileModel->getPicture()));
[...]
}
I haven't gone more far, so I can only explain what to modify after...
In your editAction, you will also have to check that $_FILES isn't empty.
If it's not, then you do the upload process.
If it's, then make sure to not edit the picture column in the SQL query (you will have to do a custom query)
5) Your twig views:
Under show.html.twig
Change
<tr>
<th>Picture</th>
<td>{{ profileModel.picture) }}</td>
</tr>
to
<tr>
<th>Picture</th>
<td><img src="{{ asset(profile_directory~profileModel.picture) }}"></td>
</tr>
Same goes for the index.html.twig.
And you can add (not replace) it to the edit.html.twig to get a preview of the actual picture.
6) Explanations:
In app/config/config.yml we added a few directory to use as parameters in your files.
It will later make it easier to change those directories if needed. (Won't have to edit tons of files... YAY!)
Twig directories always start from the /web folder.
Those directory are used when we register our service as arguments.
They will set our variable in the service file FileUploader.php.
Unlike the Symfony site exemple, we pass the whole object to the upload service.
We then, check from which class this object was created and do our upload process based in it.
Your upload process in the controller is then shortened to a single line.
In twig, we will also use the directory variable set in app/config/config.yml undet the twigproperty.
Like said above, if our upload directory change, we will then just have to edit the app/config/config.yml file.
I hope this will help you solve your upload issues.
Cordially,
Preciel.
You should try
$form = $this->createForm(ProfileType::class, $profileModel);
$form->handleRequest($request);
$file = $profileModel->getBrochure();
More: http://symfony.com/doc/current/controller/upload_file.html
Guys if you want to upload any kind of file in Symfony then I have very simple solution, which I have mentioned in the below. Why I am giving simple solutions because whenever new version come, you have to do some settings in services.yaml or you have to create extra files apart from your main controller.
So solutions is: Just use move($storing_place, $actual_filename) function in your main controller.
Put below codes in your controller file.
$folder_path = 'public/uploads/brochures/';
$file = $request->files->get('myfile');
$fileName = $request->files->get('myfile')->getClientOriginalName();
$file->move($folder_path, $fileName);
return new Response($file);
Hope given solution will help in your project.
I can easily render a template with variables from a file with some code like:
$renderer = new PhpRenderer();
$vm = new ViewModel();
$resolver = new TemplateMapResolver();
$resolver->setMap($this->templateMap);
$renderer->setResolver($resolver);
// Set the template to use and pass in variables as you normally would a view
$vm->setTemplate($template);
if ($vars) {
$vm->setVariables($vars);
}
$content = $renderer->render($vm);
I am curious how I can provide a string to setTemplate rather than a path to a template file. This way, the content being passed in can come from various sources such as an administrator's panel or database.
In the configuration example in the documentation you can see that it is possible to define a template_map inside your view_manager config array. A template map is like an array of aliases for your template files. So inside your module.config.php:
'view_manager' => array(
//...
'template_map' => array(
'name_from_admin_panel' => __DIR__ . '/../view/layout/view.phtml',
'name_from_database' => __DIR__ . '/../view/layout/view.phtml',
)
//...
)
Now you can use these names from your template map to set the template in your ViewModel as normally:
$template = 'name_from_admin_panel';
$viewModel->setTemplate($template);
I am working with the TWIG framework for php, and would like to know how i would be able to include these php files inside my php code like i normally do.
<?php
session_start();
include("includes/db.php");
include("functions/searchfunctions.php");
include("functions/userSearchSession.php");
?>
The db file establishes the connection through mysqli to the database.
In your comments you mentioned you are using the Slim framework, which has an extension to support Twig templates.
Using the extension however, requires some additional setup though, you must install the extention, called Slim Views, and also the Twig core from within composer. Slim Views does not list Twig as a dependancy.
To get this working:
Use composer to get add both Slim Views And Twig
$ php composer require slim/views
$ php composer require twig/twig:~1.0
Configure your Slim Framework $app to use the new tempting engine.
$view = $app->view();
$view->parserOptions = array(
'debug' => true,
'cache' => dirname(__FILE__) . '/cache'
);
$view->parserExtensions = array(
new \Slim\Views\TwigExtension(),
);
At this point, Slim Framework is now using Twig when rendering pages. You can now do all of your includes and pass the variables to Twig:
<?php
// ./Slim_app.php
require 'vendor/autoload.php';
/*
* foo.php contains the following:
* <?php
* $foo = bar;
*
*/
require 'foo.php';
$app = new \Slim\Slim(array(
'view' => new \Slim\Views\Twig()
));
$view = $app->view();
$view->parserOptions = array(
'debug' => true,
'cache' => dirname(__FILE__) . '/cache'
);
$view->parserExtensions = array(
new \Slim\Views\TwigExtension(),
);
$app->get('/hello', function () use ($app, $foo) {
//twig_template.html.twig exists in the templates directory.
//(./templates/twig_template.html.twig)
$app->render('twig_template.html.twig', array('foo' => $foo));
});
$app->run();
?>
{# ./templates/twig_template.html.twig #}
{{ foo }}
Navigating to Slim_app.php/hello now displays the following:
More info on using Twig.
I have templates folder in my public folder.
I want to have opportunity to upload different layouts form my admin panel and put them to public/templates folder.
How can I change standard layout then?
$template = 'christmas.phtml';
$viewModel = new ViewModel();
$viewModel->setTemplate('/../../public/templates/'.$template);
isn't working :(
I also tried this way (changing layout) up from current:
$this->layout('../../public/templates/'.$template);
I found the solution. I've added one line to my module.config.php:
'view_manager' => array(
...
'template_path_stack' => array(
__DIR__ . '/../view',
__DIR__ . '/../../../public' // newLine
),
),
Then simply use this in controller:
$template = 'sometemplate.phtml';
$this->layout('templates/'.$template);
can you try $viewModel->setTemplate(APPLICATION_PATH .'/../public/templates/'.$template); or $viewModel->setTemplate('./../../public/templates/'.$template); instead of $viewModel->setTemplate('/../../public/templates/'.$template);. Because I guess you want to go up from the application directory, not from the root directory and $template = 'christmas.phtml'; should be $template = 'christmas';
If there is no APPLICATION_PATH constant you can define it in index.php file. If you dont like to define it, you can use realpath('<path/to/your/public/templates/>') method.