I'm moving my website to Jekyll since Wordpress is way too bloated and far from easy to use for a simple blog+portfolio. I am then facing a problem which I could not solve looking at the documentation (and even the examples, since they are very very simple).
I want to have a site with a landing page at / (ok), a blog on the directory /blog/ and the posts at /blog/post-title/ (ok, I think) and a portfolio with my jobs at /portfolio/ with jobs at /portfolio/job-title/, but I cannot create this last directory.
I tried creating a _jobs dir inside the portfolio dir, and then looping through it with
{% for job in site.jobs %}
...html...
{% endfor %}
Since the blog example uses this same syntax, but with posts instead of jobs. How should I do to access this portfolio/_jobs directory and loop through the files?
The tree of the Jekyll folder is as follows:
.
├── blog
│ ├── index.html
│ └── _posts
│ ├── 2013-02-19-hello-world.markdown
│ └── 2014-03-01-welcome-to-jekyll.markdown
├── _config.yml
├── css
│ ├── main.css
│ └── syntax.css
├── _includes
│ ├── footer.html
│ ├── header.html
│ └── sidebar.html
├── _layouts
│ ├── default.html
│ ├── job.html
│ └── post.html
├── portfolio
│ ├── index.html
│ └── _jobs
│ └── jekyll-portfolio.markdown
Jekyll does not support this as simply as in your example yet, it is coming in 2.0 however.
You could add a key/value pair to the YAML header of the child pages to signify that it should appear on the main portfolio index page. I have a similar setup that I use to define what pages should appear in the main navigation for my site.
The URL customisation for the portfolio pages can only be achieved by using the permalink setting in the YAML header of each child page.
portfolio/jobs/jekyll-portfolio.markdown etc
---
group: jobs
---
portfolio/index.html
<ul>
{% for node in site.pages %}
{% if 'jobs' == node.group %}
<li>{{node.title}}</li>
{% endif %}
{% endfor %}
</ul>
You may be able to avoid requiring the group attribute if you changed the if condition to do substring matching of the URL, but this solution is easier to understand.
Related
I'm setting up pages on my personal website(hugo academics by wowchemy) and here is the structure of one of the folders I have:
.
├── ABF.md
├── EXE.md
├── Figures
│ ├── sampling.gif
│ └── sampling_compressed.gif
├── HREMD.md
├── MetaD.md
├── REUS.md
├── TREMD.md
├── US.md
├── _index.md
├── alchemical_MetaD.md
├── appendix.md
├── intro.md
└── test.gif
In _index.md, I have the following lines to read in a GIF file:
<center>
<img src="Figures/sampling_compressed.gif">
</center>
In intro.md, which is in the same folder as _index.md, I also have the same lines to read in the same GIF file. However, in localhost, the GIF file is shown in the page made by _index.md, but not the one built by intro.md. How can I solve the problem and why is this happening? Thanks in advance!
Your assumptions about the output structure are wrong. Hugo builds _index.md in the root of you folder, while the intro.md file (when processed with pretty URL's) is built in a subfolder: intro/index.html.
That being said... I tested your setup and an image in a Section directory (which is a directory with an _index.md file) is not processed by default. I would solve this by moving the image to the static directory so you can reference it from any file in the same way (with an absolute path), especially because this image does not belong to just one page.
If it WERE to be used by just one page, you could have turned the intro.md into intro/index.md and make that directory a Page bundle in which you could put your image and reference it by using the resources variable.
I'm learning to use gulp and I decided to use pug for writing all my html.
The thing is that have this folder structure:
src/pug
├── base
│ ├── mixins.pug
│ └── variables.pug
├── components
│ ├── footer.pug
│ ├── header.pug
│ ├── head.pug
│ └── template.pug
├── index.pug
└── views
└── about.pug
And I want gulp to ignore all files that are not index.html and all my files inside the views folder.
I'm doing that using this configuration:
function compilePug() {
return src(['./src/pug/index.pug','./src/pug/views/*.pug'], {base: './src/pug/'})
.pipe(pug().on("error", console.log))
.pipe(
pug({
// Your options in here.
})
)
.pipe(dest('./dist/'));
};
The thing is, that's creating and output like this dist/views/about.html.
But I rather generate something like this dist/about/index.html.That way I can navigate between multiple pages without having a route with the .html extension at the end.
Is that possible?
I've written an npm module that does this: gulp-url-builder.
First, move your index.pug into your views directory. Everything you want to render as a page should go in there. Don't forget to adjust any extends path to your template.
src/pug
├── base
│ ├── mixins.pug
│ └── variables.pug
├── components
│ ├── footer.pug
│ ├── header.pug
│ ├── head.pug
│ └── template.pug
└── views
├── about.pug
└── index.pug
After you've installed in required the url builder module in your gulpfile, you can modify your compilePug() function to look something like this:
const { src, dest, series, parallel, watch } = require('gulp')
const pug = require('gulp-pug')
const urlBuilder = require('gulp-url-builder')
function compilePug() {
return src([
'./src/pug/views/*.pug'
]).pipe( pug() )
.pipe( urlBuilder() )
.pipe( dest('dist') )
}
This will output html files based on this pattern (note that underscores can be used for nested pages):
src/pug/views/index.pug --> dist/index.html
src/pug/views/about.pug --> dist/about/index.html
src/pug/views/foo-bar.pug --> dist/foo-bar/index.html
src/pug/views/blog.pug --> dist/blog/index.html
src/pug/views/blog_my-post.pug --> dist/blog/my-post/index.html
I have a folder like this:
tutorials/
├── machine_learning
│ └── scikit_learn
│ ├── index.html
│ └── _post
│ └── 2014-09-22-my-title.md
└── web_design
├── index.html
└── _post
└── 2010-02-11-my-title.md
I want jekyll to list all the posts in /tutorials/machine_learning/scikit_learn/_post. How to do this?
I tried site.categories.tutorials.machine_learning.scikit_learn. It is not working.
Thanks.
The magic of categories in Jekyll.
Any post will have folder hierarchy names added in categories array.
We have two posts :
folder1 > _posts > YYYY-MM-DD-one.md
folder1 > folder2 > _posts > YYYY-MM-DD-two.md
Post one will be in folder1 category.
Post two will be in folder1 and folder 2 categories.
Knowing our folder hierarchy, we just can pick at the right level
<ul>
{% for post in site.categories["folder1"] %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
with site.categories["folder1"] we get posts One and Two
with site.categories["folder2"] we get post Two
This was the easy use case.
Now, let's imagine that we have a hierarchy like :
.
├── steel
│ ├── brands
│ │ └── _posts
│ │ └── 2014-01-27-steel-brands.md
│ └── objects
│ └── _posts
│ └── 2014-01-27-steel-objects.md
└── wood
├── brands
│ └── _posts
│ └── 2014-01-27-wood-brands.md
└── objects
└── _posts
└── 2014-01-27-wood-objects.md
If we want wood objects, we cannot simply loop in site.categories["objects"] because we'll also get posts from steel objects.
In order to get only wood objects we can do :
<ul>
{% for post in site.categories["objects"] %}
{% if post.categories contains "wood" %}
<li>{{ post.title }}</li>
{% endif %}
{% endfor %}
</ul>
Note : Always work with post.categories. Never with the post.category, it's buggy.
While I am looking the doc. I saw the following document structure,
.
├── _config.yml
├── _drafts
| ├── begin-with-the-crazy-ideas.textile
| └── on-simplicity-in-technology.markdown
├── _includes
| ├── footer.html
| └── header.html
├── _layouts
| ├── default.html
| └── post.html
├── _posts
| ├── 2007-10-29-why-every-programmer-should-play-nethack.textile
| └── 2009-04-26-barcamp-boston-4-roundup.textile
├── _data
| └── members.yml
├── _site
├── .jekyll-metadata
└── index.html
When I need to include an image inside my post. Where should I put the image to use the feature of site.static_files mentioned here (Static Files Section in the Documentation)? So that I can use variable like file.path and file.modified_time directly.
Previously when I was using Jekyll 2.x, I was doing something like below by creating my own asset directory.
<link rel="stylesheet" href="{{ "/assets/css/index.css" | prepend: site.url }}">
Assuming you have your gallery images in a structure like
-img
-gallery
-image1.png
-image2.png
etc.
you can access them in a collection or page like this:
{% for image in site.static_files %}
{% if image.path contains 'img/gallery' %}
<p>{{image.path}} - {{image.modified_time}}</p>
<img src="{{site.baseurl}}{{image.path}}">
{% endif %}
{% endfor %}
This goes through all static files and check for a certain path (img/gallery in this example).
Than you can access the static file metadata for that file. (I named it 'image' in this example but you can name it whatever you want after the for keyword).
I think it doesn't make too much sense to put something like this in a blog post but rather in a page or a collection.
A static file can be placed anywhere within the site directory that is not a collection of some sort. So not within a directory that begins with "_". What makes it static is the fact that it does not have YAML frontmatter.
Id recommend making a directory named "assets" or "images" and have them in there.
edit:
what are you trying to use the feature for?
This is what my project directory briefly looks like (not complete picture). I am having trouble linking many components together (.css, .html).
├── bootstrap-3.3.5-dist
└── mysite
├── db.sqlite3
├── myApp
│ ├── admin.py
│ ├── forms.py
│ ├── __init__.py
│ ├── templates
│ │ └── myApp
│ │ ├── base.html
│ │ ├── base_menu.html
│ │ ├── main.css
│ ├── tests.py
│ ├── urls.py
│ └── views.py
In the tree above, the base.html is my main site. I want to include the main.css in my <head> of base.html, but the path isn't correct.
<link rel="stylesheet" href="main.css">
I have tried myApp/main.css, templates/myApp/main.css, so on... Not only can't I link my .css, I also want to use template inheritance for base_menu.html, same issue - the relative path isn't correct.
This is my main hindrance so far, please help. Thanks.
Static Resources
We do not usually use Django to route to so-called "static" resources. The reasoning behind this is that it is a waste to have your server spin up a Python application which calls Django, just so you can locate and stream back a "static" or unchanging file. Django is for rendering dynamic responses (such as HTML with template tags in it where you are going to inject some content).
Anyway, with this in mind, a typical Django project is often organized something like this (I deleted the sub-directory inside myApp/templates to simplify things):
├── bootstrap-3.3.5-dist
└── mysite
├── db.sqlite3
├── myApp
│ ├── admin.py
│ ├── forms.py
│ ├── __init__.py
│ ├── static
│ │ └── myApp
│ │ ├── main.css
│ │ ├── some.js
│ ├── templates
│ │ ├── base.html
│ │ ├── base_menu.html
│ ├── urls.py
│ └── views.py
Then, in your setings.py you set up two important variables:
# This is the url that static routes will reverse to
STATIC_URL = '/static/'
# This is the place where static files actually live
STATIC_ROOT = '/location/for/storing/static/files'
After that, you can run the following command:
$ python manage.py collectstatic
And Django will collect all the static files (inside the static directories inside the apps), and dump them all in directories at the location specified above.
Finally, this will allow you to reverse static urls in your templates like so:
{% load staticfiles %}
<link rel="stylesheet" href="{% static "myApp/main.css" %}">
This can be a bit confusing when you are serving content locally, because (contra what I said above) you will need a url route defined (if you are using django's runserver command), so that Django knows how to serve up the routes that will lead to these staticfiles.
See how to serve staticfiles in development and another stackoverflow answer
Template Inheritance
As for template inheritance, perhaps the missing insight is this one: stuff between template tags is rendered by Django and then that whole response is sent back.
Here's a quick demo:
Template File: myApp/templates/about.html
{% extends 'index.html' %}
{% block maincontainer %}
<div class="container">
<p>
Some content.
</p>
</div>
{% endblock maincontainer %}
Template File: myApp/templates/index.html
<html>
<head>
{% load staticfiles %}
<link rel="stylesheet" href="{% static "myApp/main.css" %}">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
<link
</head>
<body>
{% include "base_menu.html" %}
{% block maincontainer %}
{% endblock maincontainer %}
</body>
</html>
Here's what your Django view will do with these templates:
You tell it to render about.html. It will parse and evaluate everything between the template tag indicators {% and %}.
It sees you want this template to extend another template, index.html, so it magically locates that template and does step 1 on it.
index.html includes the line include base_menu.html, so Django magically locates that template, does Step 1 and inserts all of its content where the include statement is.
Django finds the template tag static blabla, so it does a urlreverse for the static file referenced there (meaning, it creates a complete url referring to the static file).
Finally, after it's done with index.html and any other included templates, back in about.html, it sees you want to override a content block defined in index.html and so it replaces that chunk defined in index.html with the overridden chunk defined in about.html.
After that, it's done, and it sends the completed template, which is now simply a large string, back to whatever requested it. This may include something like the following tag:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
Your browser is responsible for figuring out what to do with this line. This is why your first attempt at including css failed: the browser was trying to locate that file on disk and didn't know where it was.