Get URL in twig - twig

Need to get the URL in a template.
I have tried using get.request.url and it always returns blank. I've tried get.request.attributes.get('_route') and it always returns blank. Since I'm new to twig I'm sure I'm missing something fairly basic and easy.

As you are working with twig standalone, u'd need to pass the information yourself. You could create a small wrapper class to solve this for you though.
Request.php
class Request {
public function __construct() {}
public function get($key) {
return isset($_GET[$key]) ? $_GET[$key] : null;
}
public function post($key) {
return isset($_POST[$key]) ? $_POST[$key] : null;
}
public function url() {
$http = 'http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 's': '');
return $http.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
}
And register the class as a global into twig:
<?php
require_once __DIR__.'/vendor/autoload.php';
$loader = new Twig_Loader_Filesystem(__DIR__.'/../views');
$twig = new Twig_Environment($loader);
$twig->addGlobal('request', new Request());
Now you can use your wrapper inside twig
{{ request.url }}{# output current url #}
{{ request.get('variable') }}{# contents of $_GET['variable'] when set or null #}
{{ request.post('variable') }}{# contents of $_POST['variable'] when set or null #}

Related

TWIG form template: call variable in attr

In a twig form template in Symfony 4 app I need to have an attribute with a variable.
Exemple:
{{ form_widget(myform.field, {'attr': {'class': 'bidding-slider','data-slider-value': '800'}}) }}
I need to put a variable in 'data-slider-value' instead of a manual value.
I tried :
{{ form_widget(myform.field, {'attr': {'class': 'bidding-slider','data-slider-value': '{{ variable }}'}}) }}
but it do not work...
{{ variable }} alone return well the value I need to put in 'data-slider-value'.
Second tried:
I have Extended form class 'TextType' method buildView.
To do that I added this file : src/Form/Extension/TextTypeExtension.php
// src/Form/Extension/TextTypeExtension.php
namespace App\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FileType;
class TextTypeExtension extends AbstractTypeExtension
{
/**
* Return the class of the type being extended.
*/
public static function getExtendedTypes(): iterable
{
// return FormType::class to modify (nearly) every field in the system
return [TextType::class];
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$tjm = $form->get('dailyrate')->getData();
$view->vars['attr']['data-slider-value'] = $tjm;
}
}
But now I am not sure of the way to use that in my form template...
Thank you very much for helping me.
Alex
Extend your form's class method buildView:
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['attr']['data-slider-value'] = ...//
}

Twig function with needs_context

I need to get current_page in needs_context of my function.
It's working correctly, but needs_context stays empty.
My class Helper extends \Twig_Extension
class Helpers extends \Twig_Extension {
public function getName() {
return 'Helpers';
}
public function getFunctions() {
return [
new \Twig_SimpleFunction('activeClass', [
$this,
'activeClass'
], [
'needs_context' => true
])
];
}
public function activeClass($context, $page) {
if (isset($context['current_page']) && $context['current_page'] === $page){
return ' active ';
}
}
In my .twig file
Foo
I hope with this function to return active class for the current href in the navbar. I use Slim v3 with his extension Twig-view.
Thanks for your help.
I resolved the problem.
Because I use a extension of Twig for Slim and no Twig, it's different.
Normaly, we use needs_context to extract the value of the current_page.
But with Twig-view for Slim PHP, we can use {% if is_current_path('your_page') %}class="active"{% endif %}
Sincere thanks to #martias and #DarkBee for their help.

can't use withFrame in page class content

I am using geb-spock. I am trying to validate content of the page class, in the page itsself so that I just call the variable or functions. Using functions. I did something like this
class BasePage extends Page {
static content = {
verifyheader { withFrame ("myFrame") { assert $("h1").text() == "Header1" }
}
}
}
...
then:
to BasePage
and:
verifyheader
I am getting an error that the test failed and withFrame is null.
This does not occuer when I put the withFrame in the test case
then:
to BasePage
and:
withFrame('myFrame') {...}
This worked perfectly, but I am looking to use it in the page class. Is it possible? How can I go about it? or in other words, what is wrong with my code
Yes, the withFrame call in your content definition returns null because the last statement inside of the block passed to it is an assertion which always returns null. You should not assert inside of your content definition but in your test instead:
class BasePage extends Page {
static content = {
headerText { withFrame("myFrame") { $("h1").text() } }
}
}
and:
when:
to BasePage
then:
headerText == "Header1"

reuse select menu with different ids' and names' in twig

I would like to reuse a select menu, but change every time the id and the name for it in Twig. How could it be done?
I thought of a wrapper block about the select menu and then extend it each time of reuse. But how to set the values for id and name using {{ parent() }}?
I do this by storing and creating the keys in my custom Twig_Extension class, here is a small setup for it. By keeping it global I can ensure unique id's in every view/macro/include ...
example.twig
{% for i in 1..5 %}
<ul id="{{ get_unique_key('my_menu') }}">
<li>Foo</li>
</ul>
{% endfor %}
ProjectTwigExtension
class ProjectTwigExtension extends Twig_Extension {
private $keys = array();
public function getFunctions() {
return array(
new Twig_SimpleFunction('get_unique_key', array($this, 'getUniqueKey')),
);
}
/**
* Create an unique HTML identifier
*
* #param $name String to make unique
*
* #returns String
*/
public function getUniqueKey($name) {
if (!in_array($name, $this->keys)) {
$this->keys[] = $name;
return $name;
}
$i = 0;
while(in_array($name.++$i,$this->keys)) {}
$this->keys[] = $name.$i;
return $name.$i;
}
public function getName() {
return 'ProjectTwigExtension';
}
}
Register extension
$twig = new Twig_Environment($loader);
$twig->addExtension(new ProjectTwigExtension());

Undefined variable error in ExpressionEngine plugin

I'm working on a plugin that does device detection based on an external library.
This is what I have so far:
class Deetector {
// public $return_data;
/**
* Constructor
*/
public function __construct()
{
$this->EE =& get_instance();
$this->EE->load->add_package_path(PATH_THIRD.'/deetector');
$this->EE->load->library('detector');
$this->return_data = "";
}
public function deetector()
{
return $ua->ua;
}
public function user_agent()
{
return $ua->ua;
}
// ----------------------------------------------------------------
/**
* Plugin Usage
*/
public static function usage()
{
ob_start();
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
}
}
If I call {exp:deetector} I get no output in the template. If I call {exp:deetector:user_agent} I get Undefined variable: ua.
Ultimately I don't plan on setting up different functions for each of the variables that the Detector library returns but am just trying to get it to output something at the moment.
I had originally started doing this as an extension which added the Detector library's variables to the global variables array and that was working fine; it's only since trying to do it as a plugin that I've run into problems.
You haven't set $this->ua to anything. I assume it's a variable of the detector library you loaded, so you probably want to do something like this:
class Deetector {
public function __construct()
{
$this->EE =& get_instance();
// remove this line, it's probably not doing anything
// $this->EE->load->add_package_path(PATH_THIRD.'/deetector');
$this->EE->load->library('detector');
// note you use $this->return_data instead of "return blah" in the constructor
$this->return_data = $this->EE->detector->ua;
}
// remove this, you can't have both __construct() and deetector(), they mean the same thing
// public function deetector()
// {
// return $ua->ua;
// }
public function user_agent()
{
return $this->EE->detector->ua;
}
}
UPDATE:
I took a look at the Detector docs, and it doesn't follow normal library conventions (it defines the $ua variable when you include the file). For that reason you should ignore the standard EE load functions, and include the file directly:
class Deetector {
public function __construct()
{
$this->EE =& get_instance();
// manually include the detector library
include(PATH_THIRD.'/deetector/libraries/detector.php');
// save the local $ua variable so we can use it in other functions further down
$this->ua = $ua;
// output the user agent in our template
$this->return_data = $this->ua->ua;
}
}

Resources