I'm developing landing page with October CMS and using Static Pages plugin.
Here is my header.htm file with navigation:
<div class="header" id="header">
<div class="container">
<div class="header__inner">
<div class="header__logo">
<img src="{{ 'assets/img/logo.svg'|theme }}" alt="logo" class="logo">
</div>
<nav class="nav" id="nav">
{% partial 'menu-items' items=staticMenu.menuItems class='nav__list' %}
</nav>
</div>
</div>
</div>
Question is how to modify basic menu-items.htm partial if I'am using one page layout and I want exact section be active on menu item click (not separate page as it is now).
At the moment I have menu with such items and want one of these section be active on click:
/,
/#about,
/#projects,
/#contacts.
My menu-items.htm partial is below:
<ul class="{{ class }}">
{% for item in items %}
<li
class="nav__item {{ item.isActive or item.isChildActive ? 'active' : '' }}
{{ item.items ? 'dropdown' : '' }}"
>
<a class="nav__link"
{% if item.items %}class="dropdown-toggle" data-toggle="dropdown"{% endif %}
href="{{ item.url }}"
>
{{ item.title }}
{% if item.items %}<span class="caret"></span>{% endif %}
</a>
{% if item.items %}
{% partial 'menu-items' items=item.items class='dropdown-menu' %}
{% endif %}
</li>
{% endfor %}
</ul>
At the moment code in menu-items.htm partial if statement add "active" class on click because of this line:
<li class="nav__item {{ item.isActive or item.isChildActive ? 'active' : '' }} {{ item.items ? 'dropdown' : '' }}"
...it is because item "isActive" property is "true" when exact menu item is clicked. But my question is, how to do the same (add "active" class) with section link in meniu navigation, because my project have only one page "home" and several sections in it. so I want menu navigation link be active on fixed navigation when someone click for eaxmple "About" link and scroll to /#about section.
I wrote just several lines of Jquery (thanks to Pettis Brandon advise).
$('.nav__item').click(function(){
$('.nav__item').removeClass('active');
$(this).addClass('active')
});
It removes 'active' class from '.nav__item' class and after that add it again on corresponding link, based on {{ item.url }}. Hope it helps for the other as well (who is using Static Pages plugin).
Related
I've been working on an online learning website for a school project. I've had trouble passing variales when clicking on a lesson, belonging to a section, inside a course. The idea is that on a course page (formation.html.twig), there's a summary of the course, and you can click on the lessons which are in a sidebar menu. It should then display a page with the same menu, and the content of the lesson showing in place of the course summary (lesson.html.twig).
I've updated the controller so the url goes:
formations/consulter-formationid-sectionid-lessonid
In the view, I wrote {{ path('app_formations_lesson', {'formation':formation.id, 'section': section.id, 'id':lesson.id}) }}
It's working alright for the url and the right values show when I click, but the page refreshes and won't load the right twig view (lesson.html.twig), it loads the same view I'm currently on (formation.html.twig).
FormationsController:
#[Route('/formations/consulter-{id}', name: 'app_formations_see')]
public function see($id): Response
{
$formation = $this->doctrine->getRepository(Formation::class)->findOneById($id);
$section = $this->doctrine->getRepository(Section::class)->findAll();
$lesson = $this->doctrine->getRepository(Lesson::class)->findAll();
return $this->render('formations/formation.html.twig', [
'formation' => $formation,
'sections' => $section,
'lessons' => $lesson
]);
}
#[Route('/formations/consulter-{formation}-{section}-{id}', name: 'app_formations_lesson')]
public function seeLesson($id): Response
{
$lesson = $this->doctrine->getRepository(Lesson::class)->findOneById($id);
return $this->render('formations/lesson.html.twig', [
'lesson' => $lesson
]);
}
formation.html.twig
{% extends 'base.html.twig' %}
{% block title %}{{ formation.title }}{% endblock %}
{% block content %}
<div class="formationcontainer text-center">
{% block sidebar %}
{% include "./formations/sidebar.html.twig" %}
{% endblock %}
<h1>{{ formation.title }} par {{ formation.user.firstname }} {{ formation.user.lastname }}</h1>
{{ formation.description }}
<hr>
<h2>Sommaire</h2>
<div class="tableau">
<table class="table">
{% for section in formation.sections %}
<thead class="table-success">
<tr>
<th scope="col">{{ section.name }}</th>
</tr>
</thead>
<tbody>
{% for lesson in section.lessons %}
<tr>
<td>{{ lesson.title }}</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
</div>
</div>
{% endblock %}
lesson.html.twig
{% extends 'base.html.twig' %}
{% block title %}titre de la leçon{% endblock %}
{% block content %}
<div class="formationcontainer text-center">
{% block sidebar %}
{% include "./formations/sidebar.html.twig" %}
{% endblock %}
<h1>Nom de la leçon</h1>
<hr>
<h2>Vidéo</h2>
<h2>Contenu</h2>
</div>
{% endblock %}
sidebar block
<!-- Sidear for lesson pages -->
<nav class="flex-shrink-0flex-shrink-0 p-3 bg-white sidenav">
<button class="btn btn-success" id="sidenav-btn" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarCollapse" aria-expanded="false" aria-controls="collapseOne">
Sommaire
</button>
<div class="list-unstyled ps-0 ul-custom navbar-collapse collapse show" id="sidebarCollapse" aria-expanded="true">
<li class="mb-1">
{% for section in formation.sections %}
<ul class="list-unstyled align-items-center rounded fw-normal">
<li>{{ section.name }}</li>
</ul>
<div>
{% for lesson in lessons %}
<ul class="list-unstyled fw-normal pb-1 small">
<li>{{ lesson.title }}</li>
</ul>
{% endfor %}
</div>
{% endfor %}
</li>
<li class="border-top my-3"></li>
<li class="mb-1">
<ul class="list-unstyled fw-normal pb-1 small">
<li>retour à la liste des formations</li>
</ul>
</li>
</div>
</nav>
Where does this issue come from? How can I display the right view?
Thanks a lot!
edit: I swapped the code in the controller to match the seeLesson function first.
#[Route('/formations/consulter-{formation}-{section}-{id}', name: 'app_formations_lesson')]
public function seeLesson($id): Response
{
$formation = $this->doctrine->getRepository(Formation::class)->findOneById($id);
$section = $this->doctrine->getRepository(Section::class)->findAll();
$lesson = $this->doctrine->getRepository(Lesson::class)->findOneById($id);
return $this->render('formations/lesson.html.twig', [
'lesson' => $lesson,
'formation' => $formation,
'sections' => $section
]);
}
#[Route('/formations/consulter-{id}', name: 'app_formations_see')]
public function see($id): Response
{
$formation = $this->doctrine->getRepository(Formation::class)->findOneById($id);
$section = $this->doctrine->getRepository(Section::class)->findAll();
$lesson = $this->doctrine->getRepository(Lesson::class)->findAll();
return $this->render('formations/formation.html.twig', [
'formation' => $formation,
'sections' => $section,
'lessons' => $lesson
]);
}
It's rendering the wrong page because your URLs are too similar.
When trying to determine what method to execute, Symfony matches the requested URL against the route definitions above the controller methods from top to bottom.
If you're requesting for example /formations/consulter-1-2-3,
Symfony first tries to match this against /formations/consulter-{id}.
This matches if you substitute 1-2-3 for {id}, so it executes the see method.
To fix you have two options:
Either switch the order of the 2 methods in your controller so that the method seeLesson is defined above the see method. Symfony will then first try to match against the route for the seeLesson method.
Or keep the method order as is, but add a constraint to the {id} parameter in the route for the see method, to specify that the matched {id} can only consist of digits:
#[Route('/formations/consulter-{id}', name: 'app_formations_see', requirements: ['id' => '\d+'])]
I am new to OctoberCMS and I am stuck now, I am facing issue to use my custom blog posts component (which overrides Rainlab blog posts) in the same page multiple times.
Say I have created an alias of default blogPosts to postLists and I defined my custom HTML structure and it is working well, no issues.
Now what I want is to use the postLists post structure in my page for three different categories and here I am stuck because when I pass variable to component like this - { % component 'postLists' categoryFilter='news' %} it does not work for the category filter and if I select a category from drag drop component UI it becomes global categoryFilter setting for the page.
This is my requirement.
My postList component code:-
{% set posts = __SELF__.posts %}
{% for post in posts %}
<div class="col-sm-6">
<div class="row">
<div class="col-sm-4 col-4 content_body_img">
<a href="{{ post.url }}">
{% if post.featured_images.count > 0 %}
<img class="media-object" src="{{ post.featured_images.first.getThumb(108, 108) }}" />
{% else %}
<img class="media-object" src="http://placehold.it/108x108" />
{% endif %}
</a>
</div>
<div class="col-sm-8 col-8">
<p>{{ post.title }}</p>
<!--location_date-->
<div class="location_date">
<ul>
<li><i class="fa fa-calendar"></i><span> {{ post.published_at|date('j F, Y') }}<span></li>
<li><i class="fa fa-map-marker"></i>Dubai</li>
</ul>
</div>
<!--location_date end -->
</div>
</div>
</div>
<!--content_body_img end -->
{% else %}
<div class="col-sm-6 col-6 col-lg-3">{{ noPostsMessage }}</div>
{% endfor %}
Please help me, any help will be very much appreciated.
Thanks Sanny
This is static Approach - I will post dynamic Approach as well give me some time
Best and possibly easy solution will be ( in case you just intend to show posts ) is to add 3 Post List component with Different Category filter option for each tab.
It should do your work
make sure this is optimal solution if you just need to show lists nothing else.
I'm currently using symfony 3.2. and now i have a link like this :
http://link.com?lang=en and in config/parameters I have allowed_locales -en, -ru
How could i create a language switcher in twig template like this :
EN<img src="{{ asset('assets/images/arrow-down.svg') }}" alt="arrow" class="arrow-down" />
<div class="locales-content" style="left:0;">
Russian
English
</div>
Here is what I did in my application, feel free to adapt it to your needs. It creates a dropdown with two links that redirect to the same page, but change the _locale parameter. In case there is no route in the request, it creates two links that redirect to the homepage.
<li class="dropdown">
{% if app.request.locale == 'ru' %}Russian{% else %}English{% endif %} <span class="caret"></span>
<ul class="dropdown-menu">
{# Check if there is a route and some parameters in the request #}
{% if app.request.get('_route') is not empty and app.request.get('_route_params') is not null %}
{# English #}
English
{# Russian #}
Russian
{# If there is no route in the request, redirect to the homepage #}
{% else %}
{# English #}
English
{# Russian #}
Russian
{% endif %}
</ul>
</li>
I'm coding up a theme using Timber for Wordpress, which uses the twig templating engine.
I currently have different data needed for header sections on three pages.
Home Page > BG Slider & Title
Blog Page > BG & Pinned Post
Other Pages > Regular BG Image
The navigation is also supposed to be the same over each of these page headers.
I'm unsure of the best way to use twig to solve this problem.
In my base.twig I currently have:
{% block header %}
<div class="wrapper">
<h1 class="hdr-logo" role="banner">
<a class="hdr-logo-link" href="/" rel="home">{{site.name}}</a>
</h1>
<nav id="nav-main" class="nav-main" role="navigation">
<ul class="nav">
{% for item in menu.get_items %}
<li class="nav-item {{item.classes | join(' ')}}">
<a class="nav-link" href="{{item.get_link}}">{{item.title}}</a>
{% if item.get_children %}
<ul class="nav nav-drop">
{% for child in item.get_children %}
<li class="nav-drop-item">
<a class="nav-link" href="{{child.get_link}}">{{child.title}}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
</nav><!-- #nav -->
</div>
{% endblock %}
I could copy and paste this block onto each page, ie add it to
home.twig, blog.twig and other.twig
But i am repeating myself constantly, and it feels wrong. I need to feed through this on each page, without repeating my navigation each time i do it.
Does anyone have a suggestion as to how to fix?
What you want are Twig macros and/or Includes
Includes
can be used to include another .twig file in your template.
You can add variables to an Include also, but by default code inside the include have acccess to global context. eg. all template variables.
{# template.html will have access to the variables from the current context and the additional ones provided #}
{% include 'template.html' with {'foo': 'bar'} %}
{% set vars = {'foo': 'bar'} %}
{% include 'template.html' with vars %}
Macros
Are isolated from the global context, and can only work with variables/parameters that you supply to it.
{# defineit #}
{% macro input(name, value, type, size) %}
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
{% endmacro %}
{# then calling it #}
<p>{{ _self.input('username') }}</p>
With both Includes and Macros you can easily do infinitely nested trees, when you include itself in the loop.
Example of nested tree with include:
{# content of tree.twig file for include#}
{% for item in menu.get_items %}
<li class="nav-item {{item.classes | join(' ')}}">
<a class="nav-link" href="{{item.get_link}}">{{item.title}}</a>
{% if item.get_children %}
<ul class="nav nav-drop">
{# recursion #}
{% include 'tree.twig' with { menu : item.get_children } %}
</ul>
{% endif %}
</li>
{% endfor %}
im frecuent user of this forum and always find answers from other users, but this time i need to ask my own question.
At this moment im editing a wp template based on twig that i bought, right now im facing a fancybox gallery which just call the first image, and i need to add the gallery rel to the other images included in the post. i already found the missing code which call the rest of images from the post ID, but i dont know how to express it by the twig structure and incorporate it to the original code of the page
this is the code which display the gallery:
{% if wp.get_post_meta(post.ID, '_property_slides', TRUE) %}
<div class="carousel property">
<div class="preview">
<a href="{{ wp.get_post_meta(post.ID, '_property_slides', TRUE).0.imgurl }}" class="fancybox">
<img src=" {{ wp.get_post_meta(post.ID, '_property_slides', TRUE).0.imgurl }}" alt="">
</a>
// the php code expressed on twig goes here //
</div>
<!-- /.preview -->
<div class="content">
<ul>
{% for slide in wp.get_post_meta(post.ID, '_property_slides', TRUE) %}
{% if loop.first %}
<li class="active" >
{% else %}
<li>
{% endif %}
<img src="{{ slide.imgurl }}" alt="">
</li>
{% endfor %}
</ul>
<a id="carousel-prev" href="#">{{ wp.__('Previous', 'aviators') }}</a>
<a id="carousel-next" href="#">{{ wp.__('Next', 'aviators') }}</a>
</div>
<!-- /.content -->
</div><!-- /.carousel -->
{% endif %}
This is the php code i need to implement on twig
add_filter(‘wp_get_attachment_link’,'add_gallery_id_rel’);
function add_gallery_id_rel($link){
global $post;
return str_replace(‘<a href’, ‘<a rel=”galeria’. $post->ID .’” href’, $link);
}
I really appreciate if you can help me with this (sorry about my weird english)
That code is a filter applied to the regular Wordpress functions, you are using a Twig Wrapper so that code won't work for you.
Try modifying the twig loop.
{% for slide in wp.get_post_meta(post.ID, '_property_slides', TRUE) %}
#... rest of the code
<a rel="galeria{{ post.ID }}" href="{{ slide.imgurl }}">
<img src="{{ slide.imgurl }}" alt="">
</a>
#... rest of the code
{% endfor %}
Skip the first slide using slice:
{% for slide in wp.get_post_meta(post.ID, '_property_slides', TRUE)|slice(1) %}
#... rest of the code same as above