Include Twig Template with Vars as another twig template - php

I have a twig template
base.html.twig
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
I have another twig template: content.html.twig
<div class="row">
{{ content | raw }}
</div>
and an another one which is box.html.twig
<div class="col-md-{{ box.size|default(4) }} box-container">
<div class="box {% if showBorder|default(true) == true %}border{% endif %} {{ box.color|default('red') }}">
<div class="box-title">
<h4><i class="{{ box.icon|default('fa fa-bars') }}"></i>{{ box.text }}</h4>
<div class="tools">
{% if showCollapseButton|default(true) == true %}
<a href="javascript:;" class="collapse">
<i class="fa fa-chevron-up"></i>
</a>
{% endif %}
{% if showCloseButton|default(false) == true %}
<a href="javascript:;" class="remove">
<i class="fa fa-times"></i>
</a>
{% endif %}
</div>
</div>
<div class="box-body {% if lightBody|default(false) == true %}bg{% endif %}">
{% if showScroll|default(false) == true %}
<div class="scroller" data-height="{{ scrollHeight|default(165) }}px">
{{ box.content|raw }}
</div>
{% else %}
{{ box.content|raw }}
{% endif %}
</div>
</div>
</div>
and the working.html.twig goes as
{% extends 'base.html.twig' %}
{% block content %}
{% endblock %}
How do i get box.html.twig into content.html.twig and the final result in working.html.twig
I know i can get content.html.twig within working.html.twig as {% include 'content.html.twig' with {'content':'Sample Content Here'} %}
but how can i get box.html.twig into the content variable to pass to include content.html.tiwg
Twig View is rendered as below:
twigLoader = new Twig_Loader_Filesystem(MVC_DIR);
$twig = new Twig_Environment($twigLoader, array(
'cache' => 'path/to/cache',
'auto_reload' => true,
'debug' => true,
));
$this->twigCustomFunctions($twig);
echo $twig->render($viewPath, $this->viewVars);

I would recommend to render the box template first but set the rendered view to an array variable; then pass the variable to the content template
Something like this
$content = $twig->render('path/to/box.html.twig', array(...)); //pass the required variables for box.html instead of '...'
Now when you render the content.html you can pass the $content
echo $twig->render('path/to/content.html.twig', array(
'content' => $content
));

Related

Twig templates don't show updates. Symfony 4.3

After I edit my twig templates, they don't load on the page.
I have a header and footer twig file which are included in my base.html.twig.
When i edit these files, the changes aren't pushed trough when i reload the page.
I've tried clearing the cache and i disabled cache in config\packages\twig.yaml
I even tried to completely delete the cache folder, nothing seems to work.
I use the built in Symfony server.
homepageController.php:
?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use App\Entity\Vacature;
/**
* #Route("/")
*/
class HomepageController extends AbstractController
{
/**
* #Route("/", name="homepage")
* #Template()
*/
public function index()
{
$rep = $this->getDoctrine()->getRepository(Vacature::class);
$data1 = $rep->getAllVacatures();
$data2 = $rep->getLastVacatures(5);
return array("carousel" => $data1, "laatste5" => $data2);
}
}
Homepage/index.html.twig
{% extends 'base.html.twig' %}
{% block title %}Hello HomepageController!{% endblock %}
{% block body %}
{% for vacature in carousel %}
<div class="vacature">
<h4>{{ vacature.titel }}</h4>
<p>{{ vacature.tekst }}
Bekijk
</div>
{% endfor %}
{% for vacature in laatste5 %}
<div class="vacature">
<h4>{{ vacature.titel }}</h4>
<p>{{ vacature.tekst }}
Bekijk
</div>
{% endfor %}
<pre>
{{ dump(carousel) }}
</pre>
{% endblock %}
base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}VacIT{% endblock %}</title>
<link href="{{ asset('/assets/css/foundation.css') }}" rel="stylesheet"/>
<link href="{{ asset('/assets/css/main.css') }}" rel="stylesheet"/>
{% block stylesheets %}{% endblock %}
</head>
<body>
<div id='header'>
{% include "header.html.twig" %}
</div>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
<div id='footer'>
{% include "footer.html.twig" %}
</div>
</body>
</html>
header.html.twig
<div class='header'>
<div class="row">
<div class="small-12 columns">
<div class='header-logo'>
<a href="{{ path('homepage') }}">
<img id='logo' src="{{ asset('/assets/images/logo/logo.png') }}" alt="logo" width="200px">
</a>
</div>
<div class="skew-header-shadow">
<div class="skew-header"> </div>
</div>
</div>
</div>
</div>
footer.html.twig
<div class="footer-box">
<div class="skew-footer-shadow">
<div class="skew-footer"> </div>
</div>
<div class="footer">
<a href="{{ path('homepage') }}">
<img id='logo' src="{{ asset('/assets/images/logo/logo.png') }}" alt="logo" width="300px">
</a>
</div>
</div>
the tree is
Project
|-bin
|-config
|-public
|-assets
|-CSS
|-Fonts
|-images
|-logo
|-src
|-Command
|-Controller
|-Entity
|-Repository
|-Resources
|-templates
|-homepage
|-index.html.twig
base.html.twig
header.html.twig
footer.html.twig
Edit: I thought maybe this could be the reason somehow, the entire folder was inside my OneDrive. The thought crossed my mind, OneDrive is to blame. I don't know why, it's just a hunch...
Well... I just restarted the whole project. There were several other problems with it.
Although it would be interesting to see if anyone knows why the header an footer didn't change, it is not really relevant anymore.

WordPress/Timber post loop looping four times

I have the following code in my theme's index.php file. It is set to grab four of the most recent posts from a selection of category IDs. The IDs are a mix of parent and children categories.
$args = array(
'cat' => '7,5,3,4,6',
'numberposts' => 4,
'order' => 'DESC',
);
$context['stories'] = Timber::get_posts($args);
The following code is used in the tease.twig file.
{% block content %}
{{ post.content }}
{% endblock %}
The following code is used in the tease-stories.twig file.
{% extends "tease.twig" %}
{% block content %}
{% for story in stories %}
<article class="story" id="story-{{post.ID}}">
{% if loop.first %}
{% if story.thumbnail.src %}
<img src="{{story.thumbnail.src}}" class="" alt="" />
{% endif %}
{% endif %}
<h3 class="story__heading">
<a href="{{ story.link }}">
{{ story.title }}
</a>
</h3>
<div class="story__meta">
<time class="">{{ story.date }}</time>
</div>
{% if loop.first %}
<div class="story__content">
{{ story.preview.read_more(false) }}
</div>
{% endif %}
</article>
{% endfor %}
{% endblock %}
The following code is used in the index.twig file.
{% extends "base.twig" %}
{% block content %}
<section class="stories">
<h2>Latest Travel Stories</h2>
{% for story in stories %}
{% include ['tease-stories.twig'] %}
{% endfor %}
</section>
<section class="observations">
<h2>Observations</h2>
{% for observation in observations %}
{% include ['tease-observations.twig'] %}
{% endfor %}
<a href="{{ site.url }}/gerry/observations" title="More observations" class="more more-observations">
More Observations
</a>
</section>
{% endblock %}
Screenshot of looped content:
I am not sure why the loop is looping over the content four times. Any help is greatly appreciated. Cheers.
I have solved the problem with assistance from #DarkBee. The problem was using a for loop twice, once in the index.twig file and once in the tease.twig file, which resulted in the stories being outputted multiple times. My updated index.twig code is below.
{% extends "base.twig" %}
{% block content %}
<section class="stories">
<h2>Latest Travel Stories</h2>
{% include ['tease-stories.twig'] %}
</section>
<section class="observations">
<h2>Observations</h2>
{% include ['tease-observations.twig'] %}
<a href="{{ site.url }}/gerry/observations" title="More observations" class="more more-observations">
More Observations
</a>
</section>
{% endblock %}

Twig how to check which template is geting rendered

I have
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include '/layouts/navbar.html.twig' %}
</div>
{% block body %}{% endblock %}
</div>
</div>
Now in this /layouts/navbar.html.twig theres an anchor tag, who's href attribute heavily depends on which template is rendered below, for example if its the Posts template, the href should be /posts/new, if its the announcements template, the href should be /announcements/newand so on, is that even possible?
You could make use of the global variable _self to solve this e.g.
main.twig
{% include "foo.twig" %}
{% include "bar.twig" %}
foo.twig and bar.twig
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include "nav.twig" with { 'template': _self, } %}
</div>
{% block body %}{% endblock %}
</div>
</div>
nav.twig
{% set path = '' %}
{% if template == 'foo.twig' %}
{% set path = 'path/to/foo' %}
{% elseif template == 'bar.twig' %}
{% set path = 'path/to/bar' %}
{% endif %}
{% for i in 0..3 %}
{{ i }}
{% endfor %}
demo
If the path is the only thing that depends on the current template, I'd modify DarkBee's example to just simply pass the path from the parent template. That way you don't need the if/else structure:
posts.twig:
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include "nav.twig" with { 'path': '/posts/new' } %}
</div>
{% block body %}{% endblock %}
</div>
</div>
announcements.twig:
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include "nav.twig" with { 'path': '/announcements/new' } %}
</div>
{% block body %}{% endblock %}
</div>
</div>
nav.twig:
{% for i in 0..3 %}
{{ i }}
{% endfor %}

Is it possible to use Symfony's base.html without extending it?

I'm using Symfony2 to create a single page application,
as you can see, the base.html.twig (posted below) is relatively small,
all I want to do is create a route '/' that redirects directly to the base.html without the need of using unnecessary bundle inheritance.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %} Share with me {% endblock %}</title>
{% block stylesheets %}
{% include 'assets/basetemplates.html.twig' %}
{% endblock %}
</head>
<body class="metro mybody">
{% block channel %}
<div id="profile_push_container"></div>
<a href="#channel-close">
<div class="profile-modal-overlay"></div>
</a>
{% endblock %}
{% block content_form %}
<div id="content_form_overlay" class="animated fadeIn"></div>
<div id="content_form" class="animated fadeInDownBig">
<div class="content_form">
<button class="content_cancel_btn" onclick="ContentForm.controller.closeForm();"><i class="icon-cancel-2"></i></button>
<div class="form-items" id="form-items">
<div class="form-item">
<h2 class="content_title">Auto handel</h2>
</div>
</div>
</div>
</div>
{% endblock %}
{% block navbar %}
{% include 'GabrielLayoutBundle:Widgets:navigation.html.twig' %}
{% endblock %}
{% block body %}
<div id="content-loop-container">
<div id="content-push-in"></div>
{% block sidebar %}
<aside class="sidebar bounceInLeft animated light" id="custom-sidebar-css">
<ul id="the_sidebar"></ul>
</aside>
{% endblock %}
</div>
<div id="more-button"></div>
{% endblock %}
{% block footer %} {% endblock %}
{% block javascripts %}
{% include 'assets/basescripts.html.twig' %}
{% endblock %}
</body>
</html>
This doesn't seem to work, it finds the template but prevents me from using the twig functions
$collection->add('home_route', new Route('/', array(
'_controller' => 'FrameworkBundle:Template:template',
'template' => '<path>/views/base.html.twig',
)));

Symfony Twig override specific form row

I have the a form twig template, where I want to parse a specific fields help text with the raw filter (it contains html). The field is called postcode in a form called Clinic
According to here http://symfony.com/doc/current/cookbook/form/form_customization.html#how-to-customize-an-individual-field
Form template:
{% extends 'AgriHealthAhpBundle::admin.html.twig' %}
{% form_theme form 'AgriHealthAhpBundle:Form:fields.html.twig' %}
{% block _clinic_postcode_row %}
<div class="row">
test<div class="small-12 medium-3 columns label">{{ form_label(form) }}</div>
<div class="small-12 medium-6 columns widget">
{{ form_widget(form) }}
<div class="error">
{{ form_errors(form) }}
</div>
</div>
<div class="small-12 medium-3 columns help">
{% if help is defined %}
{{ help|raw }}
{% endif %}
</div>
</div>
{% endblock %}
{% block admin -%}
<h1>New Clinic</h1>
{{ form(form) }}
<div class="row form_actions">
<div class="small-12 medium-offset-3 medium-2 columns submit">
<button type="submit" id="agrihealth_ahpbundle_clinic_submit_visible" name="agrihealth_ahpbundle_clinic[submit]">Create</button>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('#agrihealth_ahpbundle_clinic_submit_visible').click(function(){
jQuery('form[name="agrihealth_ahpbundle_clinic"]').submit();
});
});
</script>
<div class="small-12 medium-2 columns cancel">
<a href="{{ path('clinic') }}">
Cancel
</a>
</div>
<div class="small-12 medium-2 end columns cancel">
<a href="{{ path('clinic') }}">
Back to List
</a>
</div>
</div>
{% endblock %}
AhpBundle/Resources/views/Form/fields.html.twig
{% block form_row %}
{% spaceless %}
<div class="row">
<div class="small-12 medium-3 columns label">{{ form_label(form) }}</div>
<div class="small-12 medium-6 columns widget">
{{ form_widget(form) }}
<div class="error">
{{ form_errors(form) }}
</div>
</div>
<div class="small-12 medium-3 columns help">
{% if help is defined %}
{{ help }}
{% endif %}
</div>
</div>
{% endspaceless %}
{% endblock form_row %}
Anyone can see what I have overlooked, I tried
{% block _clinic_postcode_row %}
and
{% block _Clinic_postcode_row %}
Solution
As per accepted answer, the form row block needs to fully idetified with shorthand bundle name. The easiest way is to view the source code of the form and identify the text used in each input field and the form name="":
Replace
{% form_theme form 'AgriHealthAhpBundle:Form:fields.html.twig' %}
with
{% form_theme form with ['AgriHealthAhpBundle:Form:fields.html.twig', _self] %}
Since you are decorating the row inside action template, while applying separate form template you need to specify multiple templates
You also need to specify a fully qualified path name to your row block such as
{% block _agrihealth_ahpbundle_clinic_postcode_row %}

Categories