I want to make a simple blog that shows the details of a post when a user clicks a title in a list of new posts on an index page. However, I realized that my detail of post shows overflow in my block mycontent, this is what I did:
base.html has a line like this:
<div class="col-md-8">
{% block mycontent %}
{% endblock %}
</div>
my read_post.html
{% block mycontent %}
<h3>{{ post.title }}</h3>
<code>{{ post.publish }}</code><br>
{{ post.content|linebreaks }}
{% endblock %}
This is my result when I have long text, I want it to have a newline and to not overflow from block mycontent. I am using boostrap for theme site
Have you tried word-wrap: break-word property?
- Word-wrap allow long words to be able to break and wrap onto the next line
- break-word allows unbreakable words to be broken
Related
I encounter a problem with the way Drupal renders Global Custom text.
I need to use Custom text field in my view to wrap fields. The body field has some "style" element inside the HTML but they are removed.
{% if field_titre_rubrique is defined and field_titre_rubrique|length %}
<div class="ancre" id="{{ field_ordre_rubrique }}">
<h1 class="ancreMenu">{{field_titre_rubrique}}</h1>
<div>
{% if body is defined %}
{{body}}
{% endif %}
{% if field_pdf is defined %}
{{field_pdf}}
{% endif %}
</div>
</div>
<div>{{ edit_node }}</div>
{% endif %}
Do I have a solution to keep "style" elements ?
You can use {{ body|raw }} but be sure that you can do this safely.
More about this topic: https://www.drupal.org/node/2296163
I am completely new to PHP, Wordpress and Timber. I have a custom post type called Projects, it uses the posts archive template and I am going crazy to create a specific Projects archive template so I can have a different layout for it.
This is what my index.twig looks like
{% extends "layouts/base.twig" %}
{% block content %}
<div class="uk-child-width-1-3#m" uk-grid uk-scrollspy="cls: uk-animation-fade; target: > div > .uk-card; delay: 500; repeat: false">
{% for post in posts %}
{% include "tease-post.twig" %}
{% endfor %}
</div>
{% endblock %}
and this is the tease-post.twig
{% block content %}
<div>
<div class="uk-card uk-card-default">
<div class="uk-card-media-top">
<img src="{{post.thumbnail.src('full')}}" alt="">
</div>
<div class="uk-card-body">
<h3 class="uk-card-title">{{post.title}}</h3>
<p>{{post.get_preview(25,false,false,true)}}</p>
</div>
<div class="uk-card-footer">
Read more
</div>
</div>
</div>
{% endblock %}
Any idea how it works? Can't find any related documentation..
There are a few diff't methods depending on what you're looking to achieve. It would seem the simplest is...
{% extends "layouts/base.twig" %}
{% block content %}
<div class="uk-child-width-1-3#m" uk-grid uk-scrollspy="cls: uk-animation-fade; target: > div > .uk-card; delay: 500; repeat: false">
{% for post in posts %}
{% include "tease-'~ post.type ~'.twig" %}
{% endfor %}
</div>
{% endblock %}
You could then create a file called tease-project.twig (assuming that `project is the name of your custom post type's slug) that might look something like this...
{# tease-project.twig #}
<h2>My cool project is... {{ post.title }}</h2>
If you're looking to do something special with a CPT's specific archive page...
Check your archive.php file, if you're using the starter theme it should load a file called archive-projects.twig (assuming that projects is the name of the custom post type).
The logic is fully customizable so you can load any .twig files you want depending on the circumstance
Is it possible to override a template block from a twig extension? How do I do it?
Edit:
I have a block in my master layout template, it is called {% block emailMenu %}, the question is, is it possible to override this block, not from another template but from inside a twig custom function?
I guess I'm confused as the best way to handle my situation, my email menu will change from page to page depending on several factors, and I thought of making a twig function to be called from the layout or from another template, the reason I am thinking along these lines is to keep my other templates free from a lot of logic, logic that I'd rather have with pure PHP. Any thoughts would be appreciated.
You can just render additional controller (not a twig extension) which renders own template (possibly dependent on the page), which overrides base template block.
I think, overriding block from twig extensions - it is not the twig purposed for.
You must create a base template:
{# src/BW/MainBundle/Resources/views/Main/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}Test Application{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li>Home</li>
<li>Blog</li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block body %}{% endblock %}
</div>
</body>
</html>
And then extends parent template with extends keyword:
{# src/Acme/BlogBundle/Resources/views/Blog/index.html.twig #}
{% extends 'BWMainBundle:Main:base.html.twig' %}
{% block title %}My cool blog posts{% endblock %}
{% block body %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
Also read this docs about templating in Symfony using Twig.
Imagine I have something like this in my twig template
{% block posLeft %}
-----
{%endblock%}
Is there any way to check for existance of the posLeft block without calling to:
block("posLeft")
And check the return value of the posBlock to varify the existance. I am a newbie in Symfony2 + Twig.
You can solve it like this, if you want to display a certain block only if it has content. Hope, this is what you're looking for.
Example index.html.twig
{% set _block = block('dynamic') %}
{% if _block is not empty %}
{{ _block|raw }}
{% endif %}
Example part.html.twig
{% extends "index.html.twig" %}
{% block dynamic %}
Block content goes here.
{% endblock %}
You can do it like this:
{% if block('posLeft') %}
...
{% endif %}
But it is not efficient if you need output of rendered block.
So if you will need block output you should assign it to variable in the first place
and then do assertions
The other answers here do not work for twig 2.1 (I've not tested on ~2.0), so here's a small update:
{% if block('dynamic') is defined %}
{{ block('dynamic')|raw }}
{% endif %}
Note that the line to render the block is not:
{% block dynamic %}
{# this wont work #}
{% endblock %}
This wont work because the block will be rendered during compile, and so the test will return true that it exists (as its tested at runtime). So you need to render the block with {{ block('dynamic')|raw }} instead as this doesn't actually define the block in the template.
First check, which Twig version you are using inside your Symfony project, because the answers here are only for Twig 1.
If you are using Twig 2 you are lucky. According to the Twig documentation, you can use the defined test to check if the block exists in the current template context.
{% if block("dynamic") is defined %}
...
{% endif %}
I have written a little TwigExtension to check if the block gets called inside the if statement and it seems like Twig only really checks if the block exists and does not call it.
The link to the docs: https://twig.symfony.com/doc/2.x/functions/block.html
If you are using Twig 1, the old answer at https://stackoverflow.com/a/13806784/6458657 is still correct.
Twig 2.x
{{ (block("posLeft")) ?? '' }}
If you want to display a block if it's defined or not in one line. Might be a little kludgy but satisfies my needs without a bunch of if..then logic.
Just want to provide another example which worked for me.
<body
{% if block('ngapp') is not empty %}ng-app="{% block ngapp %}{% endblock %}"{% endif %}
>
This allows me in child templates declare {% block ngapp 'myApp' %} and have it displayed within parent.
This was needed because on some pages I was bootstrapping Angular manually via (angular.bootstrap('moduleName', rootElement)) and Angular does not like empty ng-app='' directive and breaks in weird ways.
The accepted answer didn't work for me in Twig 3.3.10, throwing an error that the block wasn't defined.
To solve this and define a block whose contents are conditionally wrapped in a container, only if any block content is set, this worked:
Parent template with block definition and wrapper element
{# parent.twig #}
<h1>Hello. I am the parent.</h1>
{% if block('sidebar') is not empty %}
<div class="sidebar-container">
{% block sidebar %}{% endblock %}
</div>
{% endif %}
Child template setting block content
{% extends 'parent.twig' %}
{% block sidebar %}
Sidebar content from child template
{% endblock %}
Output – block content inside wrapper:
<h1>Hello. I am the parent.</h1>
<div class="sidebar-container">
Sidebar content from child template
</div>
Child template not setting block content
{% extends 'parent.twig' %}
{# sidebar block not set in this one... #}
Output – no empty wrapper element:
<h1>Hello. I am the parent.</h1>
I have a Sf2 application with a twig template extending a layout. Inside the template i want to fill a block by using twig's render tag. Unfortunately the render tag causes two sub requests instead of the expected single one. But if i place the render tag outside of the block, everything works just fine*.
*of course except that the result is rendered simply at the top of the page instead inside a block, but it's only one additional sub request.
What may cause that two sub requests are made if - and only if - the render tag is placed within a block?
DIRTY DETAILS
In the layout there's a block for an additional navigational menu (topmenu):
layout.twig.html
<div class="row" id="secondary-nav">
<div class="span12">
{% block topmenu %}{% endblock %}
</div>
</div>
Duplicate sub request example
And this is my view, it uses a {% render ... %} tag to fill the topmenu block by issuing a sub request to the "Navigation" controller:
index.html.twig
{% extends "FooBundle::layout.html.twig" %}
{% block topmenu %}
{% render "FooBundle:Navigation:index" with { 'active': 'feedback' } %}
{% endblock %}
So far, so good, but doing it this way the sub request is issued twice for some unknown reason. It's not displayed twice, but i see the SQL query count increased and the symfony2 profiler shows two identical sub requests too.
Single sub request example
If i place the {% render ... %} tag outside of any block like this, it is causing only one single sub request:
index.html.twig
{% extends "FooBundle::layout.html.twig" %}
{% render "FooBundle:Navigation:index" with { 'active': 'feedback' } %}
{% block topmenu %}
{% endblock %}
NARF! Finally, after spending X hours on this issue, i found out that i had a check in my layout.html.twig, to see if the topmenu block has any contents:
{% if block('topmenu') %} ... {% endif %}
...
{% block topmenu %}{% endblock %}
This led to the second, unwanted sub request.
Fix
To still have the ability to check for the content but not requesting twice, i'm loading the block into a variable first and then outputting the variable instead of using {% block topmenu ...%}:
{% set topmenu = block('topmenu') %}
{% if topmenu %} ... {% endif %}
{{ topmenu | raw }}
Luckily i do not need to extend the block really, it's just a placeholder.