How to handle twig view and bootstrap 3 rows/columns? - symfony

I have an Article entity and I made a findAll() in the controller.
I rendered each article in a div with the col-md-6 class.
But foreach 2 articles I must wrap these divs in a row div.
How can I do this with twig ?
Thanks.
EDIT :
I tried your code (NHG) like this:
{% for article in articles %}
{% if loop.index % 2 == 0 %}
<div class="row"></div>
{% endif %}
<div class="col-md-6">
<article class="well well-sm">
<img src="{{ article.image }}" alt="{{ article.title }}" class="img-thumbnail">
<h2 class="h3 text-center">{{ article.title }}</h2>
<div class="alert alert-success well-sm">
{{ article.content|striptags|slice(0, 235) }}...
</div>
<a class="btn btn-default btn-sm pull-right" href="#">{{ article.comments|length }} Comments</a>
<div class="btn-group btn-group-sm">
{% for tag in article.tags %}
<a class="btn btn-default">{{ tag.name }}</a>
{% endfor %}
</div>
</article>
</div>
{% endfor %}
But it doesn't work.
I want to have something like this :
<div class="row">
<div class="col-md-6"></div>
<div class="col-md-6"></div>
</div>
<div class="row">
<div class="col-md-6"></div>
<div class="col-md-6"></div>
</div>
<div class="row">
<div class="col-md-6"></div>
<div class="col-md-6"></div>
</div>

UPDATED:
As #Maerlyn suggested:
{% for row in articles|batch(2) %}
<div class="row">
{% for article in row %}
<div class="col-md-6">
// your content
</div>
{% endfor %}
</div>
{% endfor %}
OLD way:
Use loop.index (doc: The loop variable), modulo (doc: Math operators) and if (doc: if statement )
{% for article in articles %}
{% if loop.index % 2 == 1 %}
<div class="row">
{% endif %}
<div class="col-md-6">
// your content
</div>
{% if (loop.index % 2 == 0 or loop.last) %}
</div>
{% endif %}
{% endfor %}

{% for row in articles|batch(2) %}
<div class="row">
{% for article in row %}
<div class="col-md-6">
// your content
{% if loop.index is divisibleby(3) %}
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}

I suggest :
<div class="row">
{% for article in articles %}
{% if (loop.index0 % 2 == 0) and not loop.first %}
</div>
<div class="row">
{% endif %}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
// your content
</div>
{% endfor %}
</div>

Related

Arranging photos in a vertical position in CommerceHQ platform

I'm having some problem with my theme for my e-commerce store. Currently, the product images are aligned in a carousel form. (One large main image, 3-5 thumbnails images below in carousel form)
I'd like to change this to show all photos in same sizes but vertically (top to bottom)
This is my code, how do I change it? I've read stuff online and tried making changes but nothing is happening. Please help.
{{ set(this, 'title', product.seo_title) }}
{% set mainStyles = load.get( loadQuery.cms_items("main-styles", {limit: 50}) ) %}
{% set buttonText = mainStyles[0].settings["Add to cart button text"]|default('Add to Cart') %}
{% set buttonColor = mainStyles[0].settings["Add to cart button color"]|default('inherit') %}
{% set maxRelatedProducts = mainStyles[0].settings["Number of rows for related items"]|default(1) * 3 %}
{% set quanSelector = mainStyles[0].settings["Quantity selector on product page"] %}
{% set imageCrop = mainStyles[0].settings["Product thumbnail aspect ratio"]|default('Smart crop') %}
{% if imageCrop == 'Wide' %}
{% set imageCrop = 'wide' %}
{% elseif imageCrop == 'Tall' %}
{% set imageCrop = 'tall' %}
{% endif %}
<div class="page product" data-productid="{{ product.id }}">
<div class="container">
<div class="col-sm-7">
<div class="fotorama"
data-width="100%"
data-arrows="false"
data-loop="true"
data-autoplay="false"
data-thumbwidth="113"
data-thumbheight="113"
data-thumbborderwidth="4"
data-thumbmargin="5">
{% if product.mainImage %}
<a href="{{ product.mainImage.getImageSize("jumbo") }}">
<img src="{{ product.mainImage.getImageSize("jumbo") }}">
</a>
{% endif %}
</div>
<div class="product-no-image{% if product.mainImage %} hidden{% endif %}">
<img src="/img/icons/image.svg">
</div>
<div class="hidden-xs">
<hr>
{% set relatedProducts = campaign.recommendations({ "product_id": product.id, "limit": maxRelatedProducts }) %}
{% if relatedProducts|length %}
<div class="row related items-grid">
<div class="col-sm-12">
<div class="block-title">
<h3>Related products</h3>
</div>
<div class="items">
{% for product in relatedProducts %}
<div class="col-sm-4 col-xs-6 item {{ imageCrop }}">
<a href="{{ site_path(product.url) }}">
{% if product.mainImage %}
<div class="image"
style="background-image: url('{{ product.mainImage.getImageSize("medium") }}');"></div>
{% else %}
<div class="image empty"></div>
{% endif %}
<p class="title">{{ product.title }}</p>
<p class="price">
{{ product.defaultPrice | currency }}
</p>
</a>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
</div>
</div>
<div class="col-sm-5">
<div class="product-head">
<h2>{{ product.title }}</h2>
<p class="price">
<span id="price">{{ product.price | currency }}</span>
<span class="compare">
<span id="compare-price">{{ product.compare_price | currency(NULL, {"force_prefix_symbol": true}) }}</span>
</span>
</p>
{% if product.variants %}
<div class="variants">
{% for variant in product.allVariants %}
<div class="item">
<span class="label-heading">{{ variant.variant }}</span>
{% if variant.selectorType == "dropdown" %}
<div class="select2">
<select data-variant="{{ loop.index0 }}"
class="product-{{ variant.variant|preg_replace('/[^a-zA-Z0-9]/')|lower }}-select product-select"
title="">
</select>
</div>
{% else %}
<div class="product-colors product-{{ variant.variant|preg_replace('/[^a-zA-Z0-9]/')|lower }}-round">
{% for option in variant.variantOptions %}
<button type="button"
data-variant="{{ loop.parent.loop.index0 }}"
data-option="{{ option.option|preg_replace('/[^a-zA-Z0-9]/')|lower }}"
class="btn-rounded product-color"
style="{% if option.thumbnail.image %}background-image: url('{{ option.thumbnail.imageUrl }}');{% else %}background-color: {{ option.thumbnail.color }}{% endif %}"></button>
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
{% if quanSelector %}
<div id="quantity-selector" class="quantity">
<span class="label-heading">Quantity</span>
<input type="number">
<button class="down"></button>
<button class="up"></button>
</div>
{% endif %}
{{ system.getApp('ProductCustomizer', {'product_id': product.id} ) }}
<button class="btn" id="buy-it-now"
style="background-color: {{ buttonColor }}">{{ buttonText }}</button>
{{ system.getApp('SecurityBadge', {} ) }}
{{ system.getApp('QuantityLeft', {'product_id': product.id} ) }}
{{ system.getApp('Timer', {'product_id': product.id}) }}
</div>
{% if product.textareaModels %}
<div class="panel-group descriptions" id="accordion" role="tablist" aria-multiselectable="true">
{% for textarea in product.textareaModels %}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="section-heading{{ loop.index }}">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion"
href="#section{{ loop.index }}"
aria-expanded="{% if loop.index == 1 %}true{% else %}false{% endif %}"
aria-controls="section{{ loop.index }}">
{{ textarea.name|raw }}
<span class="icon__state"></span>
</a>
</h4>
</div>
<div id="section{{ loop.index }}"
class="panel-collapse collapse{% if loop.index == 1 %} in{% endif %}" role="tabpanel"
aria-labelledby="section-heading{{ loop.index }}">
<div class="panel-body">
<div class="typography">{{ textarea.text | raw }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
</div>
<div class="visible-xs">
{% set relatedProducts = campaign.recommendations({ "product_id": product.id, "limit": maxRelatedProducts }) %}
{% if relatedProducts|length %}
<div class="row related items-grid">
<div class="col-sm-12">
<div class="block-title">
<h3>Related products</h3>
</div>
<div class="items">
{% for product in relatedProducts %}
<div class="col-sm-4 col-xs-6 item {{ imageCrop }}">
<a href="{{ site_path(product.url) }}">
{% if product.mainImage %}
<div class="image"
style="background-image: url('{{ product.mainImage.getImageSize("medium") }}');"></div>
{% else %}
<div class="image empty"></div>
{% endif %}
<p class="title">{{ product.title }}</p>
<p class="price">
{{ product.defaultPrice | currency }}
</p>
</a>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
</div>
<div class="row">
<div class="col-sm-12">
{{ system.getApp('Reviews', {'product_id': product.id} ) }}
</div>
</div>
</div>
</div>

Using 3 templates at the same time with Twig

I am having troubles assembling 3 Twig templates, with {% extends %} and {% use %}.
I know how to assemble 2 templates, thanks to {% extends %} but I don't get how to add a third. I got two different types of errors :
Circular reference detected for Twig template "home.html.twig", path:
home.html.twig -> twtts.html.twig -> home.html.twig
OR
Template "twtts.html.twig" cannot be used as a trait.
I don't understand what's wrong in this :
{# home.html.twig #}
{% extends 'layout.html.twig' %}
{% use 'twtts.html.twig' %}
{% block assets %}
<script src="/assets/js/actions.js"></script>
{% endblock %}
{% block page_title %}Twttr | Home{% endblock %}
{% block content %}
<div class="container d-flex">
<div class="col-md-3"></div>
<div class="col-md-6">
<table class="table col-md-6 mt-5" id="twtts">
{% block twtts %}
{% endblock %}
</table>
</div>
<div class="col-md-3"></div>
</div>
{% endblock %}
{% extends 'layout.html.twig' %}
_
{# twtts.html.twig #}
{% block twtts %}
{% for twtt in twtts %}
<tr class="">
<td class="col-md-6">
<div class="media pr-4 pl-4 pt-4 pb-3">
<a href="/profile/{{twtt.author_name}}">
{% if twtt.pp_url is not empty %}
<img src="{{ twtt.pp_url }}" alt="{{ twtt.author_name }} profile picture" class="align-self-start twtt-thumbnail mr-3 ml-3">
{% else %}
<img src="/assets/pp/default_pp.png" alt="PP-Pro" class="align-self-start twtt-thumbnail mr-3 ml-3">
{% endif %}
</a>
<div class="media-body position-relative">
{% if twtt.rt_author_name is not null %}
<small class="text-muted position-absolute rtwtt-msg">{{ twtt.rt_author_name }} rtwtted :</small>
{% endif %}
<h5 class="mt-0 d-flex justify-content-between">
{{ twtt.author_name }}
<span>{% if twtt.rt_author_name is not null %}{{ twtt.post_time|date("d/m/Y H:i") }}{% else %}{{ twtt.date|date("d/m/Y H:i") }}{% endif %}</span>
</h5>
<p>{{twtt.content|nl2br}}</p>
<div class="media-footer d-flex justify-content-center">
<div class="actions d-flex justify-content-around">
<div class="rtwtt {% if twtt.rtwtted == true %}text-success{% endif %}" data-twtt={{ twtt.id }}><span class="rt-nbr">{{ twtt.rtwtts }}</span><i class="fas fa-retweet"></i></div>
<div class="fav {% if twtt.faved == true %}text-warning{% endif %}" data-twtt={{ twtt.id }}><span class="fav-nbr">{{ twtt.favs }}</span><i class="fas fa-star"></i></div>
</div>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
{% endblock %}
_
{# layout.html.twig #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block page_title %}{% endblock %}</title>
{# ... #}
{% block assets %}{% endblock %}
</head>
<body>
<main>
<div class="container">
{% block content %}{% endblock %}
</div>
</main>
</body>
</html>
It used to work when the file twtts.html.twig was in home.html.twig but as I am going to reuse it for a lot of other pages, I was trying to shorten it, and make a file for this template.
If you want to simply render the content from twtts.html.twig, you should use include
{# home.html.twig #}
{% extends 'layout.html.twig' %}
....
{% block content %}
<div class="container d-flex">
<div class="col-md-3"></div>
<div class="col-md-6">
<table class="table col-md-6 mt-5" id="twtts">
{% include 'twtts.html.twig' %} <==== Include where you want to render
</table>
</div>
<div class="col-md-3"></div>
</div>
{% endblock %}
See the following thread for difference between include, use and extend.
Difference between Include, Extends, Use, Macro, Embed in Twig
Thanks!

grav modular page - separate content and sidebar

I want to create a page in grav, where I have a content area and a sidebar area.
I want to use on modular.md root template in which I refer to a template that loops and displays both content and sidebar modules.
My problem is: how to distinguish between content and sidebar?
my template looks like this:
{% block body %}
{% block content %}
<section id="info">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-8">
<div id="content" class="site-content bg">
<h2 class="heading">{{ page.title }}</h2>
{{ page.content }}
{% for module in page.collection() %}
{{ module.content }}
{% endfor %}
</div>
</div>
<div id="sidebar" class="col-sm-4 sidebar-inner">
{% for module in page.collection() %}
{{ module.content }}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% endblock %}
What I try to achieve is to use filters on both page.collections, so that in one case only "content" (taxonomy.tag was my guess here) and in the other case only sidebar is used.
I could live with naming conventions (sidebar modules have a fixed prefix), but I can't figure it out.
okay, I came along with a hack: I include 'sidebar' in the folder name of the module and filter on module.folder name. I am convinced there is a better solution, though!
<section id="info">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-8">
{% if page.content %}
<div id="content" class="site-content bg">
<h2 class="heading">{{ page.title }}</h2>
{{ page.content }}
</div>
{% endif %}
{% for module in page.collection() %}
{% if 'sidebar' not in module.folder %}
{{ module.content }}
{% endif %}
{% endfor %}
</div>
<div id="sidebar" class="col-sm-4 sidebar-inner">
{% for module in page.collection() %}
{% if 'sidebar' in module.folder %}
{{ module.content }}
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
What you can do (I think) is set a value in the fromtmatter of the module
sidebar: true
Then you can filter on that value in your collection like
{% for module in page.collection() %}
{% if page.header.sidebar %}
{{ module.content }}
{% endif %}
{% endfor %}

How do I use the django template tag in the css tag?

I tried to use the forloop.last template tag
<div class="panel-body">
{% for card in cardlist.card_set.all %}
{% if forloop.last %}
<div class="well" style="margin-bottom: 0px;">{{ card.title }}</div>
{% else %}
<div class="well" style="margin-bottom: 20px;">{{ card.title }}</div>
{% endif %}
{% endfor %}
</div>
How do I refactor the above source like the source below?
In the refactored source, "margin-bottom: {{margin-bottom}} px;" Error in "{{margin-bottom}}".
<div class="panel-body">
{% for card in cardlist.card_set.all %}
{% if forloop.last %}
margin-bottom = 0
{% else %}
margin-bottom = 20
{% endif %}
<div class="well" style="margin-bottom: {{ }}px;">{{ card.title }}</div>
{% endfor %}
</div>
you can try it:
<div class="panel-body">
{% for card in cardlist.card_set.all %}
<div class="well" style="margin-bottom:{% if forloop.last %}0px{% else %}20px{% endif %};">{{ card.title }}</div>
{% endfor %}
</div>

Text label is not aligning with form boxes from layout

I've been following Symfony2 documentation on how to override a Twig form template which is working however there is one problem. The names of the fields are not lining up next to the form boxes.
I should be getting this:
But instead my Name and Email labels are not aligning. I get this:
Can someone show me what I'm doing wrong? (I've copied over the code from the template and wrapped the form code with it.)
Overridden template code
{% block form_widget_simple %}
<div class="row collapse">
<div class="large-2 columns">
<label class="inline"></label>
</div>
<div class="large-10 columns">
{% spaceless %}
{% set type = type|default('text') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endspaceless %}
</div>
</div>
{% endblock form_widget_simple %}
{% block email_widget %}
<div class="row collapse">
<div class="large-2 columns">
<label class="inline"></label>
</div>
<div class="large-10 columns">
{% spaceless %}
{% set type = type|default('text') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endspaceless %}
</div>
</div>
{% endblock email_widget %}
{% block textarea_widget %}
{% spaceless %}
<textarea rows="12" {{ block('widget_attributes') }}>{{ value }}</textarea>
{% endspaceless %}
{% endblock textarea_widget %}
Original Zurb Foundation template code http://foundation.zurb.com/templates/contact.html
<form>
<div class="row collapse">
<div class="large-2 columns">
<label class="inline">Your Name</label>
</div>
<div class="large-10 columns">
<input type="text" id="yourName" placeholder="Jane Smith">
</div>
</div>
<div class="row collapse">
<div class="large-2 columns">
<label class="inline"> Your Email</label>
</div>
<div class="large-10 columns">
<input type="text" id="yourEmail" placeholder="jane#smithco.com">
</div>
</div>
<label>What's up?</label>
<textarea rows="4"></textarea>
<button type="submit" class="radius button">Submit</button>
</form>
Thanks to Michael Sivolobov for his guidance. Hope this helps others with the same question. Overwrote form_row and wrapped {{ form_label(form) }} in the <div class>.
% block form_row %}
{% spaceless %}
<div>
<div class="large-2 columns">
<label class="inline">{{ form_label(form) }}</label>
</div>
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endspaceless %}
{% endblock form_row %}

Resources