Twig check if file exists - php

Hello so I am using slim framework and twig, and here is my current code in php:
$filename = '/path/to/foo.txt';
if (file_exists($filename)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
Now I want to put the if statement in my template file. How can I use the file_exists function in my twig template so I can check whether a file exists?

You can create your own function or test and just pass the arguments to the PHP function.
$test = new Twig_SimpleTest('ondisk', function ($file) {
return file_exists($file);
});
And then in your template:
{% if filename is ondisk %}
blah
{% endif %}
Unfortunately is exists sounds weird in English. Perhaps a function would make more sense.

Creating a custom function is just fine if you really need to make the validation on template side. But Twig is not meant to be used that way.
You can just make the valitadion php side and pass a flag to your template:
PHP
$filename = '/path/to/foo.txt';
$file_exists = file_exists($filename);
// ...
$app->render(
'yourTemplate',
array( 'file_exists' => $file_exists )
);
TWIG
{% if file_exists %}
do stuff
{% endif %}
Disclaimer: I don't know the exact way to render a twig template using Slim (Symfony2 guy here), but it's same logic.

For those who use Symfony with Liip Image vich_uploader, and want to check, if a DB stored files exists or not (for example on image list / gallery), this is my solution:
{% set filePath = vich_uploader_asset(image, 'imageFile') %}
{% if filePath is not null %}
....
{% endif %}

Related

ezplatform render links with url and object name from multi-relational content item in content type

does anyone know now to create a custom view type for ez platform? The default 3 have been exhausted and we need a new one for 'link'
Alternatively, does anyone know how to use the render( controller( with a custom template as this would also resolve out block right now.
Basically, we have a multi-relational field in a content object used and we need to print links to all the related contentIds, path works great but we cannot find a way to extract the name of the content object for the link without doing some fairly funky tpl logic of passing in params.
EG: As a hack for now we can pass in "embed_type" as a custom param with the render(controller("ez_content:viewAction" to pull in an alternate view for the content object for a specific content type and view type.
{% if embed_type is defined %}
{% include "embed/#{embed_type}.html.twig" %}
{% else %}
<h1>{{ ez_field_value( content, 'name') }}</h1>
{% endif %}
However, this is very ugly and all we really want to do is use 1 template for all content types, so all we need to do is loop through the relational field and print links (as the only thing available in the content field: "destination ids"). I am sure there used to be this option in the docs but i cannot find it anymore eg:
{% set links = ez_field_value( footer, "first_links_row" ).destinationContentIds%}
{% for id in links %}
{{ render(controller("ez_content:viewAction", {"contentId": id, "template": "link.html.twig"})) }}
{% endfor %}
Where the link.html.twig would simple print the link:
<a href="{{ path( "ez_urlalias", {"contentId": id} ) }}">
{{ ez_field_value( content, "name" ) }}
</a>
If using a custom tpl is not possible with the render (controller ( helper then a new custom view type would also fix this issue, but i cannot find documentation for either.
You can create a twig function that would do that. We have something like this:
Definition:
new Twig_SimpleFunction(
'content_name',
array($this, 'getContentName')
),
Implementation:
public function getContentName($content, $forcedLanguage = null)
{
if (!$content instanceof Content && !$content instanceof ContentInfo) {
$contentInfo = $this->repository->getContentService()->loadContentInfo($content);
} elseif ($content instanceof Content) {
$contentInfo = $content->contentInfo;
} else {
$contentInfo = $content;
}
return $this->translationHelper->getTranslatedContentNameByContentInfo($contentInfo, $forcedLanguage);
}
which enables you to provide either content id, content info or content itself, and it returns translated content name

Conditional HTML block with Twig

I'm using Silex and Twig for an app and I'd like to use Twig to hide or display content based on a method call. I'd like a custom tag like:
{{ 'foo'|check }}
<p>This will only be displayed if check passes</p>
{{ endcheck }}
...then a method elsewhere such as:
check($key) {
if($key === 'foo') {
...
} else {
....
}
}
...which would decide if the HTML content is displayed.
As far as I know, you would have your method programmed as:
check($key) {
if($key === 'foo') {
return true;
} else {
return false;
}
}
And then your custom filter would be used like this:
{% if 'foo'|check %}
<p>This will only be displayed if check passes</p>
{% endif %}
You would only use {{ }} for straight output (similar to <?= ?> in PHP.)
You're missing the point of TWIG. One of the primary reasons TWIG exists is to keep PHP out of the templates. So if you have something very complicated then process the array before you pass it to TWIG otherwise if it's simple like you've described then just have the twig emulate that functionality.
{% if row.val == 'foo' %}
this will be displayed
{% else %}
maybe you do not want anything displayed?
{% endif %}

Adding PHP logic withing .twig file

I am not very familiar with TWIG templates and I need to add a bit of logic to a template file based on the URL. I know how to do it in PHP, but am sort of lost here.
I can get the full URL using {{ app.request.uri }} but what I am really trying to do is something like this:
$uri = $_SERVER['REQUEST_URI'];
if ($uri == "/page1" ||strpos($uri, "/page1/") !== false) {
echo " id="item1";
}
Is something like this possible? Thanks
you could try it with the in Operator, but routing logic should be outside of the template file
you should do this logic in your Controller and set a variable "true".
controller.php
$uri = $_SERVER['REQUEST_URI'];
$item = null;
if ($uri == "/page1" ||strpos($uri, "/page1/") !== false) {
$item = "id=item1";
}
$this->render('MyBundle:mytwig.html.twig',array("item"=>$item));
mytwig.html.twig
{% if item %}
{{ item }} is only written if item is set
{% endif %}
This kind of logic does not belong in templates. Leave that code outside of your template and assign the result to a variable (instead of directly echoing it). Pass that variable to the Twig template. Output the variable.
Templates are exclusively for presentation, not for containing complicated logic code.

twig: create custom tag that calls a functions

SETUP:
Twig 1.13.1
PHP 5.4.3
PROBLEM:
I am needing help setting up a custom tag that calls a function that i have already built...
Current Code:
Template Code
{% set stories = get_latest_stories(2, sports) %}
{% for story in stories %}
{{ story.headline }} <br>
{% endfor %}
Controller
$function = new Twig_SimpleFunction('getViewStories', function (section, limit) {
return news_stories::getStories(section,limit);
});
$twig->addFunction($function);
$twig->render("storyList.html");
GOAL:
No with that said I would like to use a custom tag like
{% get_latest_stories 2 sports %}
to call the same function as above. The new way looks nicer and is easier to follow
Why not fetch your stories in the controller instead of the template? This does not seem like a job for the view layer...
So, something like this:
$twig->render("storyList.html", array(
'stories' => news_stories::getStories($section, $limit)
));
Then, you'll have a stories variable available in your template.
here is simple example how to write twig extension
Following code is taken from my unfinished project
function file_import($value){
//some code here
return $value;
}
$app['twig']->addFunction('file_import', new Twig_Function_Function('file_import'));
usage
{{ file_import('value') }}

FLAT FILE SITE: PHP5 Master Template Without Database

Dear folks,
Imagine a flat php site without database with hundreds of files having the same variables defined in all of them eg $read $look and $buys.
page1.php
<?
$blue= ".....";
$bell= ".....";
$beam= ".....";
?>
page2.php
<?
$blue= ".....";
$bell= ".....";
$beam= ".....";
?>
etcettera.php
Now, as soon as I invent a new variable, say $bike or $beaf then I have to go through all those template files in order to add to them $beaf = "" or else there undefined there. I miss a master template so to say... Any ideas/hints/code/suggestions are welcome. Thanks in advance.
Is there any smarter way of template management without use of database, making it easer to maintain these templates?
A templating engine like Twig might help you. Twig supports template inheritance, which allows you to define a master template that all child templates inherit from:
master.html.twig:
<html>
<head><title>{% block title %}Default Title{% endblock %}</title></head>
<body>
<h1>{% block pageHeading}{% endblock %}</h1>
{% block body}{% endblock %}
</body>
</html>
child.html.twig:
{% extends master.html.twig %}
{% block title}Child Page{% endblock %}
{% block pageHeading}Weclome!{% endblock %}
{% block body}
<p>My name is {{ name }}. Today's date is {{ today|date('n/j/Y') }}.</p>
{% endblock %}
PHP code:
$loader = new Twig_Loader_Filesystem('/path/to/templates');
$twig = new Twig_Environment($loader, array(
'cache' => '/path/to/compilation_cache',
));
$template = $twig->loadTemplate('child.html.twig');
echo $templater->render(array("name"=>"Mike", "today"=>new DateTime()));
I would suggest to create a file that has an __autoload function in it, include it at the top of your page1.php (and so on), then create some class like this:
class MyVars {
const book = "Book";
const apple = "Apple";
}
and you can use them like MyVars::book and MyVars::apple in your PHP files.
Your system with flat variables floating around is one of the thing to avoid.
Use a framework that helps you not doing such bad errors or just use Smarty
Zend

Categories