Jekyll creating navigation for blog pages - html

I am using jekyll-pagination on a site I am working on. I have a loop for a navbar, that loops through the sites pages, and adds them to the navbar. The navbar is picking up the extra paginated pages from the blog, and adding the "Blog" to the navbar over and over again. Is there anyway to only have "Blog" show up once, and the additional blog pages be linked only in the blog?
Here is a grab of the navbar:
Here is the code for the navbar:
<ul class="nav navbar-nav navbar-right">
{% assign mypages = site.pages | sort: "order" %}
{% for page in mypages %}
<li>
{{ page.title }}
</li>
{% endfor %}
</ul>

After playing with it I found out what I needed to do. I made a folder under _site and called it _data, within that I made a file called nav.yml and added the following:
docs_list_title: someName
docs:
- title: Home
url: index.html
- title: About
url: about.html
- title: Blog
url: /blog/index.html
Then in my layout I changed the for loop to the following:
{% for item in site.data.nav.docs %}
<li>
{{ item.title }}
</li>
{% endfor %}

Related

Creating "current" links for nav in Liquid on Jekyll

thanks for your time in advance. I've built a site based on the Jekyll tutorial site so it uses the same nav set up. I've modified it to have "current" links so I can style current page in the nav. It was working great at first but once I added my own CSS it broke something in Liquid. Here's the gist:
<nav>
<ul>
{% for item in site.data.navigation %}
<li>
<a href="{{ item.link }}"
{% if page.url == item.link %}
class="current"
{% else %}
class = "not-current"
{% endif %}>{{ item.name }}</a>
</li>
{% endfor %}
</ul>
</nav>
That's my navigation.html include, and here's my nav data:
- name: Home
link: /
- name: About
link: /about.html
This code successfully adds a 'current' class to my index page link in the nav, 'Home'. But when I go to about, in developer tools, the class is shown as 'not-current' when it should be current.
The Liquid given is running and working, since my 'Home' tag gets the 'current' class, and that comes straight from the Liquid If/Else. When I click my 'About' link in the nav, both 'Home' and 'About' have 'not-current' as a class. Any tips? Thanks in advance.
EDIT: Site can be seen here

Creating multiple blog like lists using Jekyll hydeout theme

I'm using the hydeout theme in jekyll and I am trying to have 3 sections in the side bar;
Home - A list of all posts including pagination (working already)
College - A list of all college category posts with pagination
Fun - A list of all fun category posts with pagination
So far using the theme I have the sections in the side bar and the home page is showing all posts from both categories including pagination.
However my issue is that the category layout is only setup to show post titles and I cannot get it to act as a full list of posts let alone include pagination.
category.html:
{% unless page.content == '' %}
{{ content }}
{% endunless %}
<ul class="posts-list">
{% assign category = page.category | default: page.title %}
{% for post in site.categories[category] %}
<li>
<h3>
<a href="{{ site.baseurl }}{{ post.url }}">
{{ post.title }}
<small>{{ post.date | date_to_string }}</small>
</a>
</h3>
</li>
{% endfor %}
</ul>
Here is a link to the hosted site and the code on github.
I essentially want the college and fun subsections to display posts the exact same way the home page does but only posts that belong in their given category
Any help would be greatly appreciated.

Add a project page to site.posts on a Jekyll blog

I have a Jekyll blog where the main page is a bunch of links to posts, but where I also want to include a link to a project's gh-pages page and I want the list to stay sorted by date. Right now, I'm just manually inserting it at the top of the page.
<ul class="posts">
<li>
<span class="post-date">Jul 8, 2015</span>
<a class="post-link" href="/QuisCustodiet/">The Most Influential Works, According to TvTropes</a>
</li>
{% for post in site.posts %}
<li>
<span class="post-date">{{ post.date | date: "%b %-d, %Y" }}</span>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
This looks okay, but it will break in a week or two when I make another post. Is there a way to create another "post" and insert it into the list of site.posts in a way that it stays sorted? Is there some other much better way of doing this that I don't know about?
If I understand your problem right, you want to have some "special project posts" in your list of posts that are only links to another specific project site but have a date and therefore can be sorted together with the other posts.
Here is what I came up with:
You create an empty Post in _posts/ with front matter like this:
---
layout: post
title: "Project Example"
customlink: http://www.example.org
date: 2015-07-12 12:50:25
---
The customlink attribute is for the link to your project page. In your html, where you list all your posts, you make an if-statement to check for the attribute and handle it properly. Like this for example:
<ul>
{% for post in site.posts %}
<li>
{% if post.customlink %}
{{ post.title }}
{% else %}
{{ post.title }}
{% endif %}
</li>
{% endfor %}
</ul>
Your project post is treated as your other posts and sorted with them by date, but its link will direct the user to your project page.
Jekyll will still create the html for this post and serve it like all the other posts under a specific path. To prevent this you could add an empty permalink attribute in the posts front matter like permalink: "" and your post would lie under the root of your blog. Jekyll would still create a ".html" file for this post in the _site folder.
You need to create the posts for every external project manually but I do not know a better solution.

Hide a page in Jekyll website served by GitHub

How do I hide a page in Jekyll? I have a Contact Us page (as a Google Docs form), and there is a response page. When created, it shows up in the navigation as a child of the Contact Us page, but I don't want it to show up at all.
I currently have this set up in the front matter like this:
---
layout: page
title: Thanks
permalink: /contact/thanks/
---
If you do not put any title in the page, it does not show up in the nav bar. Something like
---
layout: page
permalink: /contact/thanks/
---
Rather than 'opting out' of including certain pages, you can 'opt in' to include only the pages you do want included in your navigation. This is useful if you have a large number of pages.
Include a menu variable in the front matter of every page you do want included in the navigation:
---
layout: blog
title: Blog
menu: main
permalink: /blog/
---
And then add an if statement where your navigation is generated:
<ul>
{% for page in site.pages %}
{% if page.menu == 'main' %}
<li>{{ page.title }}</li>
{% endif %}
{% endfor %}
</ul>
This is likely to be in _layouts/default.html or possibly _includes/header.html.
Thanks to David Jaquel's answer on this question for the inspiration: Excluding page from Jekyll navigation bar
Just add a show_in_nav: false in you page front matter and in your navigation bar, do a :
<ul>
{% for p in pages %}
{% unless show_in_nav == false %}
<li>{{ p.title }}</li>
{% endunless %}
{% endfor %}
</ul>
This will prevent your page from appearing in navigation bar.
According to docs, set published to false in your front matter:
---
layout: post
title: Blogging Like a Hacker
published: false
---
Front Matter

Excluding page from Jekyll navigation bar

I am setting up a basic Github-hosted Jekyll website (so minimal, I am not even bothering to change the default theme). I have a nested site with a small number of first-tier pages that I would like to appear in the navigation bar (i.e. the default mode of operation). I also have some second-tier pages that I would like to NOT junk up the navigation bar.
While a multi-level navigation system would be nice, I'm trying to avoid using plugins. Therefore, I believe the simplest solution is to just exclude tier two pages from the navigation system entirely.
Here's a hypothetical page structure (minus the other Jekyll files):
jekyllsite
jekyllsite/bar
jekyllsite/bar/alice
jekyllsite/bar/alice/index.md
jekyllsite/bar/bob
jekyllsite/bar/bob/index.md
jekyllsite/bar/index.md
jekyllsite/baz
jekyllsite/baz/index.md
jekyllsite/foo
jekyllsite/foo/eggs
jekyllsite/foo/eggs/index.md
jekyllsite/foo/index.md
jekyllsite/foo/spam
jekyllsite/foo/spam/index.md
jekyllsite/index.md
In descending order of awesome, this is how I'd like this to go down:
Best case, context sensitive navigation (don't think possible without plugins): When visiting jekyllsite/index.md, I would get a single layer navigation bar offering me links to foo, bar, and baz. When visiting jekyllsite/bar/index.md, I would see a two-tiered navigation bar containing foo, bar, and baz at the top level, and with alice and bob in the second tier.
The next best option would be for me to change something globally, such that only top-level directories (foo, bar, baz) got added to the nav bar. Subdirectories such as alice, bob, spam, and eggs would be automatically excluded from the nav bar.
Finally (and I think this might be the easiest) would be for a YAML frontmatter flag to exclude a page. Something like nonav: true in the frontmatter of the page to be excluded.
This seems like it would have to be a fairly common use case, though I haven't been able to find anything that looks like a short path to either of these three options. I'm hoping someone more familiar with Jekyll has a "path of least resistance" answer.
I personally do ;
Front matter for page that appears in main menu
---
layout: default
title: Home
menu: main
weight: 10
---
Main menu template (classes are from twitter bootstrap) :
<ul class="nav navbar-nav">
{% comment %}Jekyll can now sort on custom page key{% endcomment %}
{% assign pages = site.pages | sort: 'weight' %}
{% for p in pages %}
{% if p.menu == 'main' %}
<li{% if p.url == page.url %} class="active"{% endif %}>
{{ p.title }}
</li>
{% endif %}
{% endfor %}
</ul>
You can then replicate that at any level by setting a custom var in the yaml front matter :
menu : foo
and passing a value to a menu template
{% include navbar.html menuLevel="foo" %}
And intercept it like this :
{% if p.menu == menuLevel %}
Any page that doesn't expose a menu: toto will not appear in navigation.
If you are coming from the basic Jekyll theme, the simplest way to exclude pages from the header site navigation is to add an unless page.exclude exception.
(page.exclude is a new Yaml frontmatter attribute.)
By default, this is in _includes/header.html:
{% for page in site.pages %}
{% unless page.exclude %}
{% if page.title %}
<a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>
{% endif %}
{% endunless %}
{% endfor %}
and a corresponding tag to the Yaml frontmatter of any page:
---
... other attributes ...
exclude: true
---
Credit to Michael Chadwick.
It is possible to create a multi-level, context-sensitive navigation like you described without plugins, I have done it.
The only caveat is that you need to maintain a YAML data file with your menu hierarchy - with my approach, it's not possible to generate this automatically from your directory structure.
I'll show the short version here, but I have a way more detailed explanation on my blog:
Building a pseudo-dynamic tree menu with Jekyll
Example project on GitHub
1. Create a YAML data file (/_data/menu.yml) which contains your menu hierarchy:
- text: Home
url: /
- text: First menu
url: /first-menu/
subitems:
- text: First menu (sub)
url: /first-menu/first-menu-sub/
subitems:
- text: First menu (sub-sub)
url: /first-menu/first-menu-sub/first-menu-sub-sub/
- text: Second menu
url: /second-menu/
subitems:
- text: Second menu (sub)
url: /second-menu/second-menu-sub/
2. Create an include file (/_includes/nav.html) with the following content:
{% assign navurl = page.url | remove: 'index.html' %}
<ul>
{% for item in include.nav %}
<li>
<a href="{{ item.url }}">
{% if item.url == navurl %}
<b>{{ item.text }}</b>
{% else %}
{{ item.text }}
{% endif %}
</a>
</li>
{% if item.subitems and navurl contains item.url %}
{% include nav.html nav=item.subitems %}
{% endif %}
{% endfor %}
</ul>
This include file will take care of showing the correct navigation for each page:
showing the next level of subitems only for the current page
displaying the current page in bold
If you don't understand what exactly the include file is doing under the covers, read my blog post - I explained it there, in great detail (in the section "The recursive include file").
3. In your main layout file, embed the include file:
{% include nav.html nav=site.data.menu %}
This will display the navigation there.
Note that I'm passing the complete data file from step 1 to the include.
That's all!
As I said in the beginning:
The only disadvantage of this approach is that each time you create a new page, you also need to insert the page's title and URL into the data file.
But on the other hand, this makes it very easy to exclude some pages from the navigation: you just don't add them to the data file.