Playing around with twig templates (not a part of Symfony, in CodeIgniter) and it doesn't look like I can get a global sandbox to work correctly. I'm pretty sure I'm just doing something stupid, but I really can't see it.
Functions to make twig work:
public function twig_setup($configs = NULL)
{
Twig_Autoloader::register();
$env = array(
'cache' => config_item('cache_dir'),
'strict_variables' => TRUE,
'auto_reload' => TRUE,
'extension' => 'php',
'filesystem' => NULL
);
if (!is_null($configs))
{
$env = array_merge($env, $configs);
}
$this->set_extension($env['extension']);
if (is_null($env['filesystem']))
{
$env['filesystem'] = VIEWPATH;
}
else
{
$env['filesystem'] = VIEWPATH .'/'. ltrim($env['filesystem'],'/');
}
$this->set_filesystem($env['filesystem']);
// These two things should not get set to the environment
unset($env['extension']);
unset($env['filesystem']);
$this->set_environment($env);
}
public function set_sandbox($tags, $filters, $methods, $properties, $functions, $is_global = TRUE)
{
$user_policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions);
$user_sandbox = new Twig_Extension_Sandbox($user_policy, $is_global);
$this->twig->addExtension($user_sandbox);
}
public function disable_logic()
{
$tags = array('for', 'block', 'include');
$filters = array();
$methods = array();
$properties = array();
$functions = array('parent', 'block');
$this->set_sandbox($tags, $filters, $methods, $properties, $functions);
}
Usage:
$twig = new TwigThing();
$twig->twig_setup();
$twig->disable_logic();
Now, once I render a template, I should not be able to use something like raw or url_encode
{{ my_var|url_encode }}
That should kick out an error, or something, but it just encodes the var...wtf am I doing wrong here?
Related
I trying to add new function to Twig Extension file which includes template and parses variables from included template. And I have no clue how to get variable from imported template.
My Templates
Config.html
{% set myVariable= "MyVariable" %}
template.html
{{layout("config") }}
My Config Variable: {{ myVariable }}
This is my Twig Extension Class.
class TwigExtensions extends \Twig_Extension {
public function getFunctions()
{
return array(
new \Twig_SimpleFunction(
'layout', array($this, 'twig_layout', ), [ 'needs_environment' => true, 'needs_context' => true, 'is_safe' => ['all'] ]
)
);
}
function twig_layout(\Twig_Environment &$env, &$context, $template, $variables = [], $withContext = true, $ignoreMissing = false, $sandboxed = false)
{
$file_name = (string)$template . ".html";
if ($withContext) {
$variables = array_merge($context, $variables);
}
$result = '';
try {
$result = $env->resolveTemplate($file_name)->render($variables);
// how to get variables from $file_name tempalte
} catch (Throwable $e) {
return "NULL"
}
return $result;
}
}
I'm migrating from zend framework 1 to 3 , and I have a function that returns twig template but I don't know what should I use to render view twig template on zf3
How to:
use class of viewer
set my template path
set array to render it in template
return template
code:
protected function convertItemList($aItemList)
{
$aSet = [];
//$config['template_paths'] = [APPLICATION_PATH . '/../library/Core/Backend/SRO/Views/'];
//$oView = new Core_Twig_View($config);
if (!$aItemList) {
return [];
}
foreach ($aItemList as $iKey => $aCurItem) {
$aSpecialInfo = [];
$aInfo = $aCurItem;
$aInfo['info'] = $this->getItemInfo($aCurItem);
$aInfo['blues'] = $this->getBluesStats($aCurItem, $aSpecialInfo);
$aInfo['whitestats'] = $this->getWhiteStats($aCurItem, $aSpecialInfo);
//$oView->assign('aItem', $aInfo);
$i = isset($aCurItem['Slot']) ? $aCurItem['Slot'] : $aCurItem['ID64'];
if ($aCurItem['MaxStack'] > 1) {
$aSet[$i]['amount'] = $aCurItem['Data'];
}
$aSet[$i]['TypeID2'] = $aInfo['TypeID2'];
$aSet[$i]['OptLevel'] = $aInfo['OptLevel'];
$aSet[$i]['RefItemID'] = !isset($aCurItem['RefItemID']) ? 0 : $aCurItem['RefItemID'];
$aSet[$i]['special'] = isset($aInfo['info']['sox']) && $aInfo['info']['sox'] ? true : false;
$aSet[$i]['ItemID'] = $aCurItem['ID64'];
$aSet[$i]['ItemName'] = $aInfo['info']['WebName'];
$aSet[$i]['imgpath'] = $this->getItemIcon($aCurItem['AssocFileIcon128']);
//$aSet[$i]['data'] = $oView->render('itemData.twig');
}
return $aSet;
}
I use this module https://github.com/OxCom/zf3-twig.
You can install it by github instructions and add this parameter to zf3 configuration array:
'service_manager' => array(
'factories' => array(
...
'TwigStrategy' => \ZendTwig\Service\TwigStrategyFactory::class,
...
),
)
1) After this you can use Twig in some action of some controller by this code:
function someAction(){
...
$viewModel = new ZendTwig\View\TwigModel(['foo'=>'bar']);
return $viewModel;
}
2) To set other template:
function someAction(){
$viewModel = new ZendTwig\View\TwigModel(['foo'=>'bar']);
$viewModel->setTemplate('application/controller/name'); //set path here
return $viewModel;
}
3) You can to set array variables by TwigModel "__construct" parameter:
function someAction(){
$viewModel = new ZendTwig\View\TwigModel($someVariablesArray);
$viewModel->setTemplate('application/controller/name'); //set path here
return $viewModel;
}
4) If you need to return html code, you need to do something:
Add in services config one more param:
'service_manager' => array(
'factories' => array(
...
'TwigStrategy' => \ZendTwig\Service\TwigStrategyFactory::class,
'TwigRenderer' => \ZendTwig\Service\TwigRendererFactory::class,
...
),
)
Add TwigRenderer service in your controller factory:
class YourControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new YourController($twigRenderer);
}
}
and get twigRenderer in your Controller:
private $twigRenderer;
public function __construct($twigRenderer)
{
$this->twigRenderer = $twigRenderer;
}
After this get html:
function someAction(){
$viewModel = new ZendTwig\View\TwigModel(['foo'=>'bar']);
$viewModel->setTemplate('mails/order/order_in_process');
$html = $this->twigRenderer->render($viewModel);
return $html;
}
Sorry for my english!
I was looking at this code and noticed it seemed a lot of code just to run 2 checks, and I remembered coding in C# and there was a way to shorten the code to just one check but add a (something ? something) in it, is there a way to do something like this in PHP?
if ($config->get('core:twig.caching.enabled')) {
$this->twig = new \Twig_Environment($loader, array(
'cache' => $config->get('core:template.cache_directory'),
));
}
else {
$this->twig = new \Twig_Environment($loader);
}
I would do it this way:
$cache = $config->get('core:twig.caching.enabled');
$arr = ($cache) ? array('cache' => $cache) : array();
$this->twig = new \Twig_Environment($loader, $arr);
Because I'm not 100% sure what $config->get('core:twig.caching.enabled'); do return the above solution will work as your original one.
But if the return value is only true or false and if its ok to hand over array('cache' => true) or array('cache' => false) than you can reduce this furthermore:
$this->twig = new \Twig_Environment($loader, array(
'cache' => $config->get('core:twig.caching.enabled')
));
I am looking for a way to access and change the DATABASE_CONFIG variables, based on user input. Using CakePHP I created a custom datasource, based on the one provided in the docs, to access an external API. The API returns a JSON string containing the 12 most recent objects. I need to be able to change the page number in the API request to get the next 12 results, as well as accept a free text query entered by the user.
app/Config/Database.php
class DATABASE_CONFIG {
public $behance = array(
'datasource' => 'BehanceDatasource',
'api_key' => '123456789',
'page' => '1',
'text_query' => 'foo'
);
}
app/Model/Datasource/BehanceDataSource.php
App::uses('HttpSocket', 'Network/Http');
class BehanceDatasource extends DataSource {
public $description = 'Beehance datasource';
public $config = array(
'api_key' => '',
'page' => '',
'text_query' => ''
);
public function __construct($config) {
parent::__construct($config);
$this->Http = new HttpSocket();
}
public function listSources($data = null) {
return null;
}
public function describe($model) {
return $this->_schema;
}
public function calculate(Model $model, $func, $params = array()) {
return 'COUNT';
}
public function read(Model $model, $queryData = array(), $recursive = null) {
if ($queryData['fields'] === 'COUNT') {
return array(array(array('count' => 1)));
}
$queryData['conditions']['api_key'] = $this->config['api_key'];
$queryData['conditions']['page'] = $this->config['page'];
$queryData['conditions']['page'] = $this->config['text_query'];
$json = $this->Http->get('http://www.behance.net/v2/projects', $queryData['conditions']);
$res = json_decode($json, true);
if (is_null($res)) {
$error = json_last_error();
throw new CakeException($error);
}
return array($model->alias => $res);
}
}
Is there anyway to access and change the $behance array, or is there another way to go about accessing an external API with cakePHP that I am totally missing?
I have to generate an URL in a task but I get an incorrect url of type:
./symfony/user/edit/id
when I need
/user/edit/id
My first try was:
protected function execute($arguments = array(), $options = array())
{
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', $options['env'], true);
$this->context = sfContext::createInstance($configuration);
$baseurl = $this->context->getController()->genUrl(array('module' => 'user','action' => 'edit', 'id' => $id));
// ...
}
My second try, following this answer gives the same incorrect url:
protected function execute($arguments = array(), $options = array())
{
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', $options['env'], true);
$this->context = sfContext::createInstance($configuration);
$routing = $this->context->getRouting();
$baseurl = $routing->generate('user_edit', array('id' => $id));
// ...
}
How can I get the correct URL ?
Have you tried the solution from the snippet? I use this one in many projects.
I was also using almost the same second solution you describe but a bit different:
// you get the context the same way
$context = sfContext::createInstance($configuration);
$this->controller = $context->getController();
$baseurl = $this->controller->genUrl('user_edit?id='.$id);
Check parameters for genUrl, you can give true/false as second argument for absolute url.
I solved adding the --application option!
protected function configure()
{
$this->addOptions(array(
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend'),
));
//...
}
I didn't know that it was required even if I write directly its name in the getApplicationConfiguration params.
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', $options['env'], true);