slimphp / twig-view Goto Github PK
View Code? Open in Web Editor NEWSlim Framework view helper built on top of the Twig templating component
Home Page: http://slimframework.com
License: MIT License
Slim Framework view helper built on top of the Twig templating component
Home Page: http://slimframework.com
License: MIT License
Hi.
The docs are a little lacking when it comes to using twig 2.x
Can they be updated to reflect how to force usage of twig 2.x?
First the $this->view only works for Pimple with their __get() implementation.
Second most container use the same instance as default or can be configured to.
Third messing with container is considered a code smell.
Fourth it's better to save the view in Request attribute rather than mess around with container.
In Slim 2, I can easily add data before rendering with $this->view->appendData([]); However, In Slim 3, the only possible for me to do so is with $this->view->offsetSet($key, $value);
I think it would be great to pass an array instead of key value pair
Hi there. In Slim 2 i can set key in __construct like $this->view->set("foo","bar") via Slims/View. But in Slim 3 with Twig-view i can not set twig value in it. How can i set val outside of render function?
I modified it to work with my installation :
public function isCurrentPath($name)
{
if ($this->uri->getBasePath()) {
if ($this->uri->getPath() == '/') {
return $this->router->pathFor($name) === $this->uri->getBasePath() . '/';
} else {
return $this->router->pathFor($name) === $this->uri->getBasePath() . '/' . $this->uri->getPath();
}
} else {
return $this->router->pathFor($name) === $this->uri->getPath();
}
}
So, I realize that this has been discussed before in #20 and also in slimphp/Slim#1326, but it seem this has not really been resolved.
Let me explain the problem again
activate
with a parameter token
/app
So here are my options:
{{ path_for('activation', {token: 'foo'}) }}
-> /app/activation/foo
{{ base_url() }}
-> http://example.com/app
As you can see, I can not simply combine the two to create an absolute URL, since the initial directory would be duplicated. Ideally I would have a url_for()
method that works exactly like path_for
but returns a fully qualified URL.
How to specify subdirectories....
my directory structure.
A ->
--> AA
--> BB
Type: Twig_Error_Loader
Message: There are no registered paths for namespace "admin" in "menus/index.twig" at line 54.
File: /home/vijaykoogu/voicepace/vendor/twig/twig/lib/Twig/Loader/Filesystem.php
Line: 182
Please show us how to use session.
Not sure if this is covered in the missing helpers, should this support flash messages?
Hello, I can use composer to get Twig-View, but not to get Slim in version 3. But Twig-View would only work with version 3. Is it possible to add Slim in version3 to the packagist for composer?
By the way, thanks for this amazing framework.
How would one bootstrap additional functions to extend Twig?
Hi guys
Twig's new version is 2.x, But Twig-View only supports 1.x.
I cant find the docs for base_url.
I know it's there but a few people stop by the support channels looking for it.
I read the code and did not find a register() method for the Slim app object, do I need an specific version of the Slim fw to use this? I'm using 2.6.2, the one that composer downloaded.
in slim 2
we have render function
as
` $app->render('email.twig')'
but in slim we have to add $response in twig render :( is there any way to render templates without using $response or hold twig render in a variable?
The is_current_path
method introduced in #64 is really useful. π
However, the method fails if the class is invoked with a string URI (see line #60) as demonstrated in the docs:
// Instantiate and add Slim specific extension
$basePath = rtrim(str_ireplace('index.php', '', $c['request']->getUri()->getBasePath()), '/');
$view->addExtension(new Slim\Views\TwigExtension($c['router'], $basePath));
It works fine when invoked using $c['request']->getUri()
:
$view->addExtension(new \Slim\Views\TwigExtension($c['router'], $c['request']->getUri()));
Curious βΒ what's the advantage of using the docs approach over $c['request']->getUri()
?
Hi,
I have controller and for example on Login post action, if there are errors or on success login, I'd want to user be redirected login page with errors or dashboard page. How can I do that?
If I write $this->view->render(...); it opens up in the same url (/login/post)...
Thanks
From the code:
public function fetch($template, $data = [])
{
$data = array_merge($this->defaultVariables, $data);
return $this->environment->loadTemplate($template)->render($data);
}
public function render(ResponseInterface $response, $template, $data = [])
{
$response->getBody()->write($this->fetch($template, $data));
return $response;
}
in "fetch" I can use pre-added variables but not in render.
I'm using the twig view helper and it does not show anything... There is no error, nothing, just a blank white page. The server says "200"... I don't know what I'm doing wrong.
For example if I use the php-view package or simply do $response->getBody()->write("foo")
it works. But with the twig-view it doesn't work.
app/
cache/
templates/
home.twig
src/
App.php
Twig.php
Home.php
...
public/index.php
vendor/
...
I have my own App class, which holds an object of Slim\App. Here I create an object of my own Twig
class, which executes this code:
$container = $app->getContainer();
$container["view"] = function ($container) {
$view = new Slim\Views\Twig("../app/templates", [
"cache" => "../app/cache"
]);
$view->addExtension(new Slim\Views\TwigExtension(
$container["router"],
$container["request"]->getUri()
));
return $view;
};
And instantiate an object of the Home
class, with this code:
$app->get("/", function ($request, $response, $args) {
return $this->view->render($response, "home.twig", []);
});
My template home.twig
contains just <h1>Hello world!</h1>
.
Can someone help me? Or do you need more information?
There is no methods like addFilter, addFunction and etc.
$function = new \Twig\TwigFunction('function_name', function () {
// ...
});
$view->addFunction($function);
[24-Jun-2019 10:11:11 Kwajalein] PHP Fatal error: Uncaught Error: Call to undefined method Slim\Views\Twig::addFunction() In ....
https://twig.symfony.com/doc/2.x/advanced.html
Should I use
$view->getEnvironment()->addFunction($function);
?
What is the best way of coupling this with flash messages?
Currently, I want to do this:
$app->get('/flash', function ($request, $response, $args) use ($app) {
$this->flash->addMessage('flash', 'This is a message');
return $response->withStatus(302)->withHeader('Location', '/');
});
$app->get('/', function ($request, $response, $args) use ($app) {
$flashes= $this->flash->getMessages();
return $this->view->render($response, 'home.php', [
'messages' => $flashes
]);
})->setName('home');
And then:
{% for flash in messages %}
{{ flash }}
{% endfor %}
However, I am getting an error:
Notice: Array to string conversion in ... /vendor/twig/twig/lib/Twig/Environment.php(332) : eval()'d code on line 29
Not sure if I am making a complete amateur mistake here in how I am sending the array over. Or is this simply not possible?
Sometimes I need to include small template within other twig template. In symfony there is render() function in twig for this. I wrote twig extension which adds this functionality with Slim 3. It is quite short and I think we can add it to twig-view. I believe that many users with slim+twig could benefit from this.
usage can be as simple as:
{{ render('Admin\\Action\\UserAction:info', { 'msq' : 'test'}) }}
where Admin\Action\UserAction is registered callable in container.
What is you opinion on this? Is this usecase scanario common enough to include this function to twig-view? I have it working and I can create pull request if so.
Currently this has only url_for
function. The old Slim-Views has 4 different helpers. A simple solution would be to add Slim\App
as a global. It would look like this:
{% if slim.request.isGet %}
<a href="{{ slim.request.uri.basepath ~ slim.router.urlFor('home') }}">link</a>
{% endif %}
It's not as pretty as few selected helpers but the API is would same as in PHP code. Unfortunately it would also make it possible to include application logic into templates which may have unwanted side effects.
Hi,
With slim previous version (2.x), it was quite easy to access flash messages from twig... This feature was quite useful. Any idea on when something similar will be available ?
Regards,
Sylvain
I keep getting this error when i try to use the twig template engine with Slim.
this is my composer.json
{
"require": {
"slim/slim": "^3.8",
"directus/sdk": "0.2.*",
"slim/twig-view": "dev-master"
},
"minimum-stability": "dev",
"repositories": [
{
"type": "git",
"url": "https://github.com/wellingguzman/zend-db"
}
]
}
below is a screen shot of the codes
Any plans to create a common interface for views?
I've written a library that will accept any view object that implements a render
method such as the one found in Slim\View\Twig.php and Slim\Views\PhpRenderer.php.
For now I plan to create a small library with a ViewInterface
and have two implementations for Twig
and PhpRenderer
use Psr\Http\Message\ResponseInterface;
interface ViewInterface
{
/**
* Output rendered template
*
* @param ResponseInterface $response The outbound PSR-7 response.
* @param string $template Template pathname relative to templates directory.
* @param array $data Associative array of template variables.
*
* @return ResponseInterface
*/
public function render(ResponseInterface $response, $template, $data = [])
}
final class TwigView extends \Slim\Views\Twig implements ViewInterface
{
}
final class PhpView extends \Slim\Views\PhpRenderer implements ViewInterface
{
}
Hi
In the documentation of Twig, they write that it should be best practice to decouple the extension definitions from their runtime implementations. See https://twig.symfony.com/doc/2.x/advanced.html#definition-vs-runtime
Should we follow that recommendation?
I already tried to implement that. See https://github.com/adriansuter/Twig-View/tree/patch-runtimeExtension
It actually works, but of course, phpunit is giving me 21 errors π¨.
From documentation:
// Define named route
$app->get('/hello/{name}', function ($request, $response, $args) {
$this['view']->render('profile.html', [
'name' => $args['name']
]);
})->setName('profile');
but i give error because i not pass the response object with first param to render method, so i edited with this:
// Define named route
$app->get('/hello/{name}', function ($request, $response, $args) {
return $this['view']->render($response, 'profile.html', [
'name' => $args['name']
]);
})->setName('profile');
Added the return because the router waiting the response object and in reference to this issue #8 I edited with this:
public function render(ResponseInterface $response, $template, array $data = [])
{
$response->getBody()->write($this->fetch($template, $data));
return $response;
}
Anyone have the same error? Ofc I use the latest dev version of slim.
With this modifications all working correctly.
We should be using proper accessors on the container in our example.
$basePath = rtrim(str_ireplace('index.php', '', $container->get('request')->getUri()->getBasePath()), '/');
$view->addExtension(new \Slim\Views\TwigExtension($container->get('router'), $basePath));
Curious if I'm missing something with the undocumented "defaultVariables" feature, or if it's just an accident of history...
Is there any use-case where "defaultVariables" offers any benefit over using twig's built-in Globals method?
For example:
$this->view->getEnvironmnent()->addGlobal('myVar', 123);
...versus:
$this->view['myVar'] = 123
Seems that a proxy method could be added to Twig-View (like the addExtension
method) and this would serve the same purpose without having to clutter up the Slim\Views\Twig class with that ArrayAccess implementation. Or perhaps there's something that can be done (or is used elsewhere in the system) with the "defaultVariables" thing that can't be done with twig's built-in globals functionality?
Thanks!
Just ran into an odd issue where a response was being preserved by reference, though I'm still not certain how.
Think I narrowed this down to the slim/twig-view rendering method:
/**
* Output rendered template
*
* @param ResponseInterface $response
* @param string $template Template pathname relative to templates directory
* @param array $data Associative array of template variables
* @return ResponseInterface
*/
public function render(ResponseInterface $response, $template, $data = [])
{
$response->getBody()->write($this->fetch($template, $data));
return $response;
}
Question: shouldn't this be preserving the immutability of the response? ie. $response = $response->...
Or is it something related to the Twig Environment?
Or is it the write method from Slim that's breaking things (by returning the response, rather than a clone / new one)?
Thanks for any insight you can provide. XD
The instructions for this repo dont seem to work for me
I installed the Slim Framework from the home and documentation which works fine first time.
Yet when i install Twig View i get many application inconsistancies such as file class names not available.
and Searching your repo is seems Slim\App doesnt even exist?
For some reason Twig->render() doesn't return a response. What does work for me is this:
public function render(ResponseInterface $response, $template, $data = [])
{
$response->getBody()->write($this->fetch($template, $data));
return $response;
}
The path_for
returned string starts with a slash, this is inconvenient for applications inside a subdirectory.
Example:
Route definition
$app->get('/{slug}', 'App\Action\ItemAction:dispatch');
Template
<a href="{{ path_for('item', {'slug': item.slug}) }}">
{{ item.name }}
</a>
produces /itemslug
, which is evaluated inside a browser to http://localhost:8000/itemslug
on my dev server. As my application is within project/alpha
subdirectory, I'd prefer some helper function which creates as string which evaluates to http://localhost:8000/project/alpha/itemslug
.
In the head of the document I'm using base element <base href="{{ base_url() }}/" />
so all links may be relative.
I can use both: base_url() ~ path_for()
but IMHO it's an overhead to list scheme, domain, port etc in each hyperlink - a relative or absolute path would be sufficient.
So I wonder how the application URLs should be created in the Twig-View?
Reintroduce the url_for
function which would create URLs not paths, or trim starting slash in path_for
? If so, should it happen it in the Twig-View or in the Slim::Router package?
How to use multiple paths per namespace?
PHP Parse error: syntax error, unexpected '.' in /base/data/home/apps/b~previewtechs-cloud/slim-app-skeleton:20170224t205746.399418087592248769/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1552
"twig/twig": "^1.18|^2.0",
I guess it is causing some trouble. Recently I just ran my application on my local machine with PHP 7.1. It works well but when I just deployed that app to Google App Engine (PHP 5.5.9 environment) then it raised error.
PHP Parse error: syntax error, unexpected '.' in /base/data/home/apps/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1552
So I am pretty sure it's because of PHP versioning. So if anybody want to avoid the issue, they need to manually add main "twig/twig"
package in their installation. Otherwise, somebody can face compatibility issue after app deployment.
I think, we can add a small note in Readme.md
file.
My file structure looks like this:
---public(Documentroot folder, where all my css,js, images loads from)
---models
---modules {all my modules customer, db_management e.t.c)
---scripts
|---ivr_builder
|------ui-bootstrap-tpls-0.2.js
--twig_templates {All my ta}
|---layout.twig
In my index.php file, I have this:
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../vendor/autoload.php';
spl_autoload_register(function ($classname) {
require "../models/" . $classname . ".php";
});
$config['displayErrorDetails'] = false;
$app = new \Slim\App(["settings" => $config]);
$container = $app->getContainer();
// Register component on container
$container['view'] = function ($container) {
$view = new \Slim\Views\Twig(
'/var/www/html/ivr/twig_templates', ['cache' => false]);
$env = $view->getEnvironment();
$lexer = new Twig_Lexer($env, array(
'tag_comment' => array('{#', '#}'),
'tag_block' => array('{%', '%}'),
'tag_variable' => array('[[', ']]'),
'interpolation' => array('#{', '}'),
));
$env->setLexer($lexer);
$loader = new \ Twig_Loader_Filesystem('ivr/scripts/ivr_builder/ui-bootstrap-tpls-0.13.4.js');
$env->getLoader();
return $view;
};
Then in my browser, I get this error:
Name Status angular-aside.js 200 jquery.js 200 ui-bootstrap-tpls-0.1.3.4.js 500
My layout.swig header looks like this:
<meta http-equiv="Content-Type" content="text/html" charset="iso-8859-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% if page_title is defined and page_title is not null ? page_title: 'Log in' %}
{% endif %}
<link rel='stylesheet' href='/css/bootstrap.css'/>
<link rel='stylesheet' href='/js/libraries/angular-aside/angular-aside.css'/>
<link rel="stylesheet" href="/js/libraries/angular-notify-master/styles/css/angular-notify-texture.css" id="notifyTheme">
<link rel='stylesheet' href='/css/ivr_builder.css'/>
<link rel="stylesheet" type="text/css" href="/css/custom.css">
<script type="application/javascript" src="/js/libraries/angular.js"></script>
<script type="application/javascript" src="/js/libraries/angular-animate.min.js"></script>
<script type="application/javascript" src="/scripts/ivr_builder/ui-bootstrap-tpls-0.13.4.js"></script>
<script type="application/javascript" src="/js/libraries/angular-aside/angular-aside.js"></script>
<script type="application/javascript" src="/js/libraries/angular-notify-master/scripts/dist/angular-notify.js"></script>
<script type="application/javascript" src="/js/jquery-ui-1.11.4/external/jquery/jquery.js"></script>
Please any suggestion on how why its not loading please on the browser
This issue is similar to slimphp/Slim#2762.
With the solution proposed in slimphp/Slim#2762 (comment), a user could for example just write
$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->addErrorMiddleware(true, true, false)
->getDefaultErrorHandler()->forceContentType('application/json');
and only AppFactory
needs to be imported. That is pretty nice for these two internal slim middlewares.
I wonder if we could simplify the other middlewares as well. I mean, for example, to add the twig middleware, a user has to write the following code.
$container = new Container();
AppFactory::setContainer($container);
$app = AppFactory::create();
// Let's add the routing middleware. Nice.
$app->addRoutingMiddleware();
// Let's add the twig middleware. Complicated.
$app->add(new TwigMiddleware(
new Twig(__DIR__ . '/../templates', [
'cache' => __DIR__ . '/../cache/twig',
'auto_reload' => true,
]),
$app->getContainer(),
$app->getRouteCollector()->getRouteParser(),
'',
Twig::class
));
// Let's add the error middleware. Nice.
$app->addErrorMiddleware(true, true, false);
We could for example let the user add twig to the container and then he/she can simply call
$app->add(TwigMiddleware::create($app, $basePath, $twigContainerKey));
The static create()
method would then get the container from the app, twig from the container, and the route parser from the app (via route collector). Of course, the method would throw exceptions whenever anything is missing (no container, twig not found, etc.).
I am getting error
Unknown "path_for" function in "/Templates/Partials/index.twig" at line 11.
here is index .twig
{% extends "Base.twig" %}
{% block content %}
<header class="main_menu_sec navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-12">
<div class="lft_hd">
<div class="logo">
<a href="{{ path_for('home') }}">Gowarbaam</a>
</div>
</div>
</div>
here is view in container
`$container['View'] = function ($container)
{
return new \Slim\Views\Twig( DIR . '/../App/Views',[
'cache' => false //dirname(FILE) . '/../Caching'
]);
$View->addExtension(new Slim\Views\TwigExtension(
$container['router'],
$container['request']->getUri()
));
return $View;
};`
After updating my composer.json I get this error.
Unable to register extension "Slim\Views\TwigExtension" as it is already registered.
Users should be discouraged from using echo
in their application, and we shouldn't use echo
in the render
method ourselves.
For me, the purpose of a PSR-7 based app should be the building of a valid response object during the application phase, and then sending that response at the end. I believe that if you are working with PSR-7 you shouldn't ever be writing to the output directly.
My proposal is to change the render
method to the following:
public function render(Response $response $template, $data = [])
{
return $response->write($this->fetch($template, $data));
}
This interface does not exist in Twig.
Where is it defined? The Twig project only has Environment and that one has no interface.
I've read some of the closed issues and it seems that no one, is actually having an issue using path_for. I have double and triple check for typos.
{{ path_for('home', {'name': 'home'}) }}
Everything else is working great. Any ideas what is going on?
The TwigMiddlewareTest
should be refactored to remove duplicate code.
Twig-View/tests/TwigMiddlewareTest.php
Lines 24 to 121 in 2fe4757
I have the same setup like the usage section in the readme and every time i use the block function from twig the content is wrapped into a
tag..example:
layout.twig
{% block content %}{% endblock %}
test.twig
{% extends 'includes/layout.twig' %} {% block content %} test {% endblock %}
output
<pre>test</pre>
how i can disable the
<pre>
tag ?UPDATE: forgot the block part, anything inside the body is wrapped with a
<pre>
tag.
UPDATE 2: Its a issue from some chrome addon.Usage example in Readme.md not working.
When I tried implementing this, using the usage example, it didn't work.
The first thing it "crashed" on, was that there is no "addExtension" method for the class \Slim\Views\Twig.
After checking it out, it looks like there should be a getEnvironment call before that. So it will be:$view->getEnvironment()->addExtension(new Slim\Views\TwigExtension(
Which brings us to the next issue, there is no Slim\Views\TwigExtension class.
Any ideas?
Twig 2.x requires PHP 7 (readme update)
Already known here: #70, but just a quick note -- might be worth highlighting this requirement specifically in the readme (maybe under install, too), since it could be overlooked.
Running various versions of PHP locally as needed, so composer update changed to Twig 2.x. Production server was running PHP 5.6 (so it broke briefly).
Usage example
For me, the usage example doesn't work.
return $this["view"]->render($response, 'profile.html', [ 'name' => $args["name"] ]);
With this I got the error: "Cannot use object of type Slim\App as array".
return $this->view->render($response, 'profile.html', [ 'name' => $args["name"] ]);
This works fine for me.
What is the problem now? :D
Recommend Projects
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
TensorFlow
An Open Source Machine Learning Framework for Everyone
Django
The Web framework for perfectionists with deadlines.
Laravel
A PHP framework for web artisans
D3
Bring data to life with SVG, Canvas and HTML. πππ
Recommend Topics
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
web
Some thing interesting about web. New door for the world.
server
A server is a program made to process requests and deliver data to clients.
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Visualization
Some thing interesting about visualization, use data art
Game
Some thing interesting about game, make everyone happy.
Recommend Org
We are working to build community through open source technology. NB: members must have two-factor auth.
Microsoft
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba
Alibaba Open Source for everyone
D3
Data-Driven Documents codes.
Tencent
China tencent open source team.