How to create a drop down menu in yml using jekyll - html

I have code that displays buttons on navbar. On one of the buttons I would like to add a drop down menu. I've already added the code for the drop down in my navigation.yml file, but I am having issues adding it in my jekyll html file. Below is part of the code that shows the navigation bar with button links. I just need help adding the drop down menu code.
-----html file-----
<ul class="visible-links">
{%- for link in site.data.navigation.main -%}
<li class="masthead__menu-item">
<a href="{{ link.url | relative_url }}"{% if link.description %} title="{{ link.description }} "{% endif %}>{{ link.title }}</a>
</li>
{%- endfor -%}
</ul>
---navigation.yml file------
- title: "Contact Us"
sublinks:
- title: "Text goes here"
url: "#"
- title: "Text goes here"
url: "#"
- title: "Text goes here"
url: "#"
I'm not that familiar with Jekyll, so any help is needed.
Thanks,

See the menu.yml file
primary:
- title: Main Menu
subfolderitems:
- name: "Home"
url: "../"
weight: 2
- name: "Pages"
url: "#"
weight: 3
subsubfolderitems:
- name: "About"
url: "/about/"
weight: 2
- name: "Pricing"
url: "/pricing/"
weight: 2
- name: "Faq's"
url: "/faq/"
weight: 2
- name: "Contact"
url: "/contact/"
weight: 2
- name: "Testimonial"
url: "/testimonial/"
weight: 2
- name: "404"
url: "/404/"
weight: 2
- name: "Blog"
url: "#"
weight: 3
subsubfolderitems:
- name: "Blog Listing"
url: "/blog/"
weight: 2
- name: "Blog Single"
url: "/adum-software-industry-how-achive-the-goal/"
weight: 2
- name: "Contact"
url: "/contact/"
weight: 2
See the dropdown query file. You need to write some css style for the menu
<nav class="header-menu" id="header-menu">
{% if site.data.menus.primary[0] %}
{% for item in site.data.menus.primary %}
{% if item.subfolderitems[0] %}
<ul class="menu">
{% for entry in item.subfolderitems %}
<li class="{% if entry.subsubfolderitems[0] %}has-sub{% endif %} menu-item">
<a class="menu-link nav-link {% if entry.subsubfolderitems[0] %}menu-toggle{% endif %}" href="{{ entry.url }}">{{ entry.name }}</a>
{% if entry.subsubfolderitems[0] %}
<ul class="menu-sub menu-drop">
{% for subentry in entry.subsubfolderitems %}
<li class="menu-item">
<a class="menu-link nav-link" href="{{ subentry.url }}">{{ subentry.name }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
{% endif %}
</nav>

Related

Jekyll adding unwanted space before and after links

I'm learning Jekyll. I finished the step by step tutorial: https://jekyllrb.com/docs/step-by-step/01-setup/
Variables seem to generate spaces before and after. Eg. item.name is now outputting the following:
Home
Blog
About
Staff
Which visually puts a space after each link. Ugly and potential for styling mishaps.
Do I have to make it, not do that? Am I OCD? Or am I doing it wrong?
Reference:
_includes/nav.html
<nav>
{% for item in site.data.nav %}
<a href="{{ item.link }}" {% if page.url==item.link %}class="current" {% endif %}>
{{ item.name }}
</a>
{% endfor %}
</nav>
that .current class
.current {
color: green;
}
_data/nav.yml
- name: Home
link: /
- name: About
link: /about.html
- name: Blog
link: /blog.html
- name: Staff
link: /staff.html
It doesn't happen to me, but this can be fixed by adding | strip after item.name like so:
_includes/nav.html
<nav>
{% for item in site.data.nav %}
<a href="{{ item.link }}" {% if page.url==item.link %}class="current" {% endif %}>
{{ item.name | strip }}
</a>
{% endfor %}
</nav>
EDIT:
Seems like in OP's case, it's caused by indentation's spacings. To fix this, you must replace any occurrence of {{ with {{-, }} with -}}, {% with {%-, and %} with -%}. Here's the reference.

Jekyll-paginate-v2: my posts are not shown on the page

In my Jekyll 4 site I have a /blog/index.html page. In the correspondent layout I just put the code from the jekyll-paginate-v2 github repo (01-typicalblog). I am using jekyll-paginate-v2 3.0.0.
Here's the code of the /blog/index.html page:
<ul class="post-list">
{% for post in paginator.posts %}
<li>
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
<h2>
<a class="post-link" href="{{ post.url | relative_url }}"
>{{ post.title | escape }}</a
>
</h2>
</li>
{% endfor %}
</ul>
{% if paginator.total_pages > 1 %}
<ul class="pager">
{% if paginator.previous_page %}
<li class="previous">
<a
href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}"
>← Newer Posts</a
>
</li>
{% endif %} {% if paginator.next_page %}
<li class="next">
<a
href="{{ paginator.next_page_path | prepend: site.baseurl | replace: '//', '/' }}"
>Older Posts →</a
>
</li>
{% endif %}
</ul>
{% endif %}
And here is in my config.yaml file:
permalink: /:year-:month-:day-:title/
pagination:
enabled: true
per_page: 3
permalink: "/page/:num/"
title_suffix: " - page :num"
limit: 0
sort_field: "date"
sort_reverse: true
The front matter in the /blog/index.html page has:
pagination:
enabled: true
I have been trying to change /page/:num/ with /blog/:num/ and /blog/page/:num/ to no avail. (I am still a beginner in the field).
I put the plugin both in the Gemfile and the config.yaml file and followed all the steps form the "01-typicalblog" example page (https://github.com/sverrirs/jekyll-paginate-v2/tree/master/examples/01-typicalblog).
I also deleted several times the Gemfile.lock to avoid any caching problem.
When I serve the site I see this in the terminal:
Pagination: Disabled in site.config.
But as you can see, I did enable it in both the page font matter and the config file.
I have been looking for days for possible solutions but I can't find much material on paginate-v2 and hope that someone could help me.
Thanks in advance!
in your case you must insert pagination: enabled: true in index.md also
jekyll-paginate-v2 does not work properly with jekyll 4. I run into similar issues.
https://github.com/sverrirs/jekyll-paginate-v2/issues/165
jekyll-paginate-v2 version 3 seems to have fixed the issues
https://rubygems.org/gems/jekyll-paginate-v2/versions/3.0.0

Cannot get paganation using jekyll-paginate-v2 to work

I have been looking at multiple answers to similar questions here on stack overflow and other sources, but simply cannot solve my problem.
I have a page consisting of index.md which has the following frontmatter:
# Feel free to add content and custom Front Matter to this file.
# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
title: title
layout: default
pagination:
enabled: true
---
And this is what I do to list my post:
<!--
Here is the main paginator logic called.
All calls to site.posts should be replaced by paginator.posts
-->
{% for post in paginator.posts %}
<li>
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
<h2>
<a class="post-link" href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
</h2>
</li>
{% endfor %}
</ul>
<!--
Showing buttons to move to the next and to the previous list of posts (pager buttons).
-->
{% if paginator.total_pages > 1 %}
<ul class="pager">
{% if paginator.previous_page %}
<li class="previous">
← Newer Posts
</li>
{% endif %}
{% if paginator.next_page %}
<li class="next">
Older Posts →
</li>
{% endif %}
</ul>
{% endif %}
<div class="pagination">
{% if paginator.previous_page %}
<a href="{{ paginator.previous_page_path }}" class="previous">
Previous
</a>
{% else %}
<span class="previous">Previous</span>
{% endif %}
<span class="page_number ">
Page: {{ paginator.page }} of {{ paginator.total_pages }}
</span>
{% if paginator.next_page %}
Next
{% else %}
<span class="next ">Next</span>
{% endif %}
</div>
I have added the gem to plugin list and to the gem file and run bundle install, and my configuration looks like this:
pagination:
enabled: true
per_page: 3
offset: 2
permalink: '/page/:num/'
title: ':title - page :num of :max'
limit: 0
sort_field: 'date'
sort_reverse: true
However when I run bundle exec jekyll s my test post is not listed.
But if I use:
{% for post in site.posts%}
{{post.title}}
{% endfor %}
My test post is listed as I intent. Anyone who can help me towards, what I am doing wrong, I simply cannot spot it.
Do you have a specific reason for including offset: 2 in the _config.yml? This will exclude the first 2 posts from appearing in the pagination so if you don't have at least 3 posts in your project nothing will be displayed.
Try removing the offset line from your config file, rerun bundle exec jekyll serve, and see if the functionality works.
For offset usage check the jekyll-paginate-v2 README section "Offsetting posts".

Accessing _data in Jekyll (loop in loop)

Given this YAML:
- maincategory:
title: "Projects"
subcategory:
title: "General"
item:
title: "Alpha"
item:
title: "Beta"
- maincategory:
title: "Support"
subcategory:
title: "General"
item:
title: "Something"
item:
title: "Else"
How would one iterate over this data if the Jekyll _data file is called entries.yml?
So far I've gotten here but I'm not sure whether I should keep referencing the site.data oject in sub-loops. Also not sure whether this is even possible.
{% for entry in site.data.entries %}
<h2>{{ entry.maincategory.title }}</h3>
{% for subcategory in site.data.entries.maincategories %}
<h3>{{ entry.maincategory.subcategory.title }}</h3>
<ul>
{% for item in site.data.entries.maincategory.subcategories %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
To be clear, this is where I want to end up (output wise):
<!-- Loop over every main category -->
<h2>Main category title</h2>
<!-- Loop over every sub category within main category -->
<h3>Subcategory title</h3>
<ul>
<!-- Loop over every item in this subcategory -->
<li>Item title
</li>
YAML:
- title: "Projects"
subcategories:
- title: "project-sub1"
items:
- title: "project-sub1-item1"
href: "#"
- title: "project-sub1-item2"
href: "#"
- title: "project-sub2"
items:
- title: "project-sub2-item1"
href: "#"
- title: "project-sub2-item2"
href: "#"
- title: "Support"
subcategories:
- title: "support-sub1"
items:
- title: "support-sub1-item1"
href: "#"
- title: "support-sub1-item2"
href: "#"
Nested loops:
{% for entry in site.data.entries %}
<h2>{{ entry.title }}</h2>
{% for subcategory in entry.subcategories %}
<h3>{{ subcategory.title }}</h3>
<ul>
{% for item in subcategory.items %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
Output:
<h2>Projects</h3>
<h3>project-sub1</h3>
<ul>
<li>project-sub1-item1</li>
<li>project-sub1-item2</li>
</ul>
<h3>project-sub2</h3>
<ul>
<li>project-sub2-item1</li>
<li>project-sub2-item2</li>
</ul>
<h2>Support</h3>
<h3>support-sub1</h3>
<ul>
<li>support-sub1-item1</li>
<li>support-sub1-item2</li>
</ul>

Jekyll select current page url and change its class

I've been using Jekyll for a static site (so that its easy to maintain), and have been stuck at the following feature :
This is my link bar :
<ul id="links">
<li class="first"><a class="active" href="/">Home</a></li>
<li>Associate With Us</li>
<li>Media</li>
<li>Clients</li>
<li class="last">Contact Us</li>
</ul>
The active class handles the coloring. What I want is this class be applied by jekyll depending on some variable set using liquid/YAML.
Is there some easy way to go about this?
Since the bar is common to all the pages, it is now in the default layout. I could go around by using Javascript to detect the url, and do the highlighting but was wondering if there was any way of doing this in Jekyll.
I do this in two pages I have set up in Jekyll.
The first thing I do is creating an entry inside _config.yml with the information of all the pages:
# this goes inside _config.yml. Change as required
navigation:
- text: What we do
url: /en/what-we-do/
- text: Who we are
url: /en/who-we-are/
- text: Projects
url: /en/projects/
layout: project
- text: Blog
url: /en/blog/
layout: post
Then, on my main layout, I use that information to generate the navigation links. On each link, I compare the url of the link with the url of the current page. If they are equal, the page is active. Otherwise, they are not.
There's a couple special cases: all blog posts must highlight the "blog" link, and the front pages (English and Spanish) must not present the nav bar. For both cases, I rely on the fact that blog posts and front pages have specific layouts (notice that the "Blog" and "Project" links on the yaml have an extra parameter called "layout")
The navigation code is generated like this:
{% unless page.layout == 'front' %}
<ul class="navigation">
{% for link in site.navigation %}
{% assign current = nil %}
{% if page.url == link.url or page.layout == link.layout %}
{% assign current = 'current' %}
{% endif %}
<li class="{% if forloop.first %}first{% endif %} {{ current }} {% if forloop.last %}last{% endif %}">
<a class="{{ current }}" href="{{ link.url }}">{{ link.text }}</a>
</li>
{% endfor %}
</ul>
{% endunless %}
I still have to remember adding an entry to _config.yaml every time I add a new page, and then restart Jekyll, but it happens very infrequently now.
I think the navigation yaml could go inside an _include called "navigation" or something similar, but I haven't tried using yaml inside those so I don't know whether it will work. In my case, since I've got a multi-lingual site, it's easier to have everything inside config (missing translations are easier to spot)
I hope this helps.
As a further extension on the work of the other, here is a way to make it work without soggy index.html showing on all your beautiful URLs:
---
navigation:
- text: Home
url: /
- text: Blah
url: /blah/
---
{% assign url = page.url|remove:'index.html' %}
{% for link in page.navigation %}
<li {% if url == link.url %}class="active"{% endif %}>
{{link.text}}
</li>
{% endfor %}
The gold is in the assign statement which gets the page URL (which naturally includes the index.html and then strips it off to match the page.navigation pretty URLs.
This may be a new feature since the question first appeared, but I've discovered this can all be done in one file:
define the navigation as a variable in the yaml header
loop over the variable using liquid
So in my _layouts/base.html I have:
---
navigation:
- text: Home
url: /index.html
- text: Travel
title: Letters home from abroad
url: /travel.html
---
<ul>
{% for link in page.navigation %}
<li {% if page.url == link.url %}class="current"{% endif %}>
{{link.text}}</li>
{% endfor %}
</ul>
Which generates this on the Home page:
<ul>
<li class="current">Home</li>
<li>Travel</li>
</ul>
And this on the Travel page:
<ul>
<li>Home</li>
<li class="current">Travel</li>
</ul>
I needed something simple, this is what I did.
In my front matter I added a variable called active
e.g.
---
layout: generic
title: About
active: about
---
I have a navigation include with the following section
<ul class="nav navbar-nav">
{% if page.active == "home" %}
<li class="active">Home</li>
{% else %}
<li>Home</li>
{% endif %}
{% if page.active == "blog" %}
<li class="active">Blog</li>
{% else %}
<li>Blog</li>
{% endif %}
{% if page.active == "about" %}
<li class="active">About</li>
{% else %}
<li>About</li>
{% endif %}
</ul>
This works for me as the amount of links in the navigation are very narrow.
Same navigation on all pages
After reading all that answers, I came up with a new and easier to maintain solution:
Add {% include nav.html %} to your _layouts/layout.html file
Add a nav.html file to your _includes folder
Add the following content to your nav.html file. It will determine if your link is on the current page and add a class of active as well as remove index.html from your link. It will also work with a subfolder like /repo-name, which is needed for GitHub gh-pages Pages branch.
<nav>
<ul class="nav">
{% assign url = page.url|remove:'index.html' %}
{% for link in site.navigation %}
{% assign state = '' %}
{% if page.url == link.url %}
{% assign state = 'active ' %}
{% endif %}
<li class="{{ state }}nav-item">
{{ link.text }}
</li>
{% endfor %}
</ul>
</nav>
Then add the nav link array to your _config.yml file as following. Mind the right indentation, as YAML is pretty picky on that (Jekyll as well).
navigation:
- text: Home
title: Back to home page
url: /index.html
- text: Intro
title: An introduction to the project
url: /intro.html
- text: etc.
title: ...
url: /foo.html
Navigation only on home - "back" for others
Assuming that the link to your "Home"-page (index.html) is the first array part inside the _config.htmls navigation array, you can use the following snippet to show the navigation to the different pages on the main/home page and a link back to the home page on all other pages:
<nav>
<ul class="grid">
{% assign url = page.url | remove:'/index.html' %}
{% assign home = site.navigation.first %}
{% if url == empty %}
{% for link in site.navigation %}
{% assign state = '' %}
{% if page.url == link.url %}
{% assign state = 'active ' %}
{% endif %}
{% if home.url != link.url %}
<li class="{{ state }}nav-item">
{{ link.text }}
</li>
{% endif %}
{% endfor %}
{% else %}
<li class="nav-item active">
{{ home.text }}
</li>
{% endif %}
</ul>
</nav>
This works for me (sorry for non-english code):
<nav>
<a href="/kursevi" {% if page.url == '/kursevi/' %} class="active"{% endif %}>Kursevi</a>
<a href="/radovi" {% if page.url == '/radovi/' %} class="active"{% endif %}>Radovi</a>
<a href="/blog" {% if page.url == '/blog/' %} class="active"{% endif %}>Blog</a>
<a href="/kontakt" {% if page.url == '/kontakt/' %} class="active"{% endif %}>Kontakt</a>
</nav>
Navigation highlighting logic is the last thing I would do in server side. I'd rather stick with nice, clean and unobtrusive approach using JS/jQuery (if this option works for you).
The elements which need to be highlighted go inside a common layout like this:
<nav>
<a id="section1" href="#">Section 1</a>
<a id="section2" href="#">Section 2</a>
<a id="section3" href="#">Section 3</a>
</nav>
In your page (or even in nested layouts) you place an element with data-ref="#section1" (in fact, any jQuery selector will work).
Now, include following JS snippet (shown as jQuery, but any framework will do) in <head>:
$(function() {
$("[data-ref]").each(function() {
$($(this).attr("data-ref")).addClass("current");
});
});
This approach is nice, because it makes no assumptions on underlying architecture, frameworks, languages and template engines.
Update: As some folks pointed out you might want to omit the $(function() { ... }) part which binds the script to DOM ready event — and just push the script down to the bottom of your <body>.
Adding to the solution of incarnate, the simplest possible line of code with jQuery is this:
$( "a[href='{{ page.url | remove: "index.html" }}']" ).addClass("current");
Works perfectly for me.
I took a simple CSS approach. First, add an identifier in the front matter...
---
layout: page
title: Join us
permalink: /join-us/
nav-class: join <-----
---
Add this as a class in <body> and your nav...
<body class="{{ page.nav-class }}">
and
<li class="{{ page.nav-class }}">...</a></li>
Then link these for all pages in CSS, e.g:
.about .about a,
.join .join a,
.contact .contact a {
color: #fff;
}
The main downside being you need to hard code the style rules.
With Jekyll 3.4.3, this works :
<ul>
{% for my_page in site.pages %}
{% if my_page.title %}
<li {% if my_page.url == page.url %} class="active" {% endif %}>
<a href="{{ my_page.url | relative_url }}">{{ my_page.title | escape }}
</a>
</li>
{% endif %} {% endfor %}
</ul>