Cannot import variables from sass file in Jekyll - jekyll

I have a variables.scss file that holds all of my sass variables in my root. I want to import it in my other scss files so that I can use these variables:
#import "/variables.scss";
However when I run the project, I get the following error:
Conversion error: Jekyll::Converters::Scss encountered an error while converting 'assets/css/index.scss':
File to import not found or unreadable: /variables.scss. Load path: C:/Ruby25-x64/lib/ruby/gems/2.5.0/gems/minima-2.5.0/_sass on line 1
What am I doing wrong and how can I properly import my sass variables. here is my config_.yml file:
# Welcome to Jekyll!
#
# This config file is meant for settings that affect your whole blog, values
# which you are expected to set up once and rarely edit after that. If you find
# yourself editing this file very often, consider using Jekyll's data files
# feature for the data you need to update frequently.
#
# For technical reasons, this file is *NOT* reloaded automatically when you use
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
# Site settings
# These are used to personalize your new site. If you look in the HTML files,
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
# You can create any custom variable you would like, and they will be accessible
# in the templates via {{ site.myvariable }}.
title: Project
email: your-email#example.com
description: >- # this means to ignore newlines until "baseurl:"
Write an awesome description for your new site here. You can edit this
line in _config.yml. It will appear in your document head meta (for
Google search results) and in your feed.xml site description.
baseurl: "" # the subpath of your site, e.g. /blog
url: "" # the base hostname & protocol for your site, e.g. http://example.com
twitter_username: jekyllrb
github_username: jekyll
# Build settings
markdown: kramdown
theme: minima
plugins:
- jekyll-feed
- jekyll-paginate-v2
collections:
posts:
output: true
permalink: /releases/:path
permalink: pretty
sass:
sass_dir: _sass
style: compressed
future: true
published: true
# Exclude from processing.
# The following items will not be processed, by default. Create a custom list
# to override the default setting.
# exclude:
# - Gemfile
# - Gemfile.lock
# - node_modules
# - vendor/bundle/
# - vendor/cache/
# - vendor/gems/
# - vendor/ruby/
############################################################
# Site configuration for the Jekyll 3 Pagination Gem
# The values here represent the defaults if nothing is set
pagination:
# Site-wide kill switch, disabled here it doesn't run at all
enabled: true
# Set to 'true' to enable pagination debugging. This can be enabled in the site config or only for individual pagination pages
debug: false
# The default document collection to paginate if nothing is specified ('posts' is default)
collection: 'posts'
# How many objects per paginated page, used to be `paginate` (default: 0, means all)
per_page: 5
# The permalink structure for the paginated pages (this can be any level deep)
permalink: '/page/:num/' # Pages are index.html inside this folder (default)
#permalink: '/page/:num.html' # Pages are simple html files
#permalink: '/page/:num' # Pages are html files, linked jekyll extensionless permalink style.
# Optional the title format for the paginated pages (supports :title for original page title, :num for pagination page number, :max for total number of pages)
title: ':title - page :num'
# Limit how many pagenated pages to create (default: 0, means all)
limit: 0
# Optional, defines the field that the posts should be sorted on (omit to default to 'date')
sort_field: 'date'
# Optional, sorts the posts in reverse order (omit to default decending or sort_reverse: true)
sort_reverse: true
# Optional, the default category to use, omit or just leave this as 'posts' to get a backwards-compatible behavior (all posts)
category: 'posts'
# Optional, the default tag to use, omit to disable
tag: ''
# Optional, the default locale to use, omit to disable (depends on a field 'locale' to be specified in the posts,
# in reality this can be any value, suggested are the Microsoft locale-codes (e.g. en_US, en_GB) or simply the ISO-639 language code )
locale: ''
# Optional,omit or set both before and after to zero to disable.
# Controls how the pagination trail for the paginated pages look like.
trail:
before: 2
after: 2
# Optional, the default file extension for generated pages (e.g html, json, xml).
# Internally this is set to html by default
extension: html
# Optional, the default name of the index file for generated pages (e.g. 'index.html')
# Without file extension
indexpage: 'index'
############################################################

First of all, use only relative basenames to import:
#import "variables";
// or if you've nested partials
#import "subdirectory/partial_name";
Secondly, if you're using sassc gem, ensure that you're using at least sassc-2.1.0 in your bundle. (Run bundle show to check). Or if you're using the deprecated sass gem, then continue using that until you can upgrade.
Lastly, ensure that your scss partial doesn't have unclosed parentheses.
UPDATE
Jekyll expects to find partials to import from in the configured sass_dir (which is _sass by default).
So, you've to ensure that the path _sass/variables.scss exists either at your source directory or within the theme-gem you're using.

Related

How to add permalink and variables globally to Jekyll pages inside a specified directory

I'm setting up a website with multi language support.
In the root directory I have one or more directories based on the language locale, e.g.: /en /it
I'm trying to set one language as default and let Jekyll generate its pages in the root of the _site directory, by setting the defaults section in _config.yml as described below. Other directories will be generated as usual.
I don't want:
to use a plugin since it have to work also with GitHub pages
to set a lang: en variable in each page front-matter but setting it globally in _config.yml instead if possible
put a load of files/directories in the root directory, just the various en, it, fr etc (if not having something like described below, but using a master pages directory).
I tried various solutions, including:
using collections: it works as expected with the example below but I don't want to use them for various reasons, like not having sitemap plugin working with them
using this solution, but it doesn't work with multiple pages with same name and other types of documents
This works with collections with an _en directory in the root:
collections:
en:
output: true
permalink: /:path
defaults:
...
- scope:
path: ""
type: "en"
values:
layout: "default"
lang: "en"
permalink: /:path
Not this, IMHO as it should be for pages:
defaults:
...
- scope:
path: "en"
type: "pages"
values:
layout: "default"
lang: "en"
permalink: /:path
In brief I need:
custom variables set for each page in the specified directory globally instead in each page front matter
make Jekyll to generate all pages from the specified directory to build in the root of _site directory using a global permalink

How to paginate posts by author

What I'm trying to do
Jekyll can use front matter variables like tags and categories and access them with site.tags and site.categories to iterate over them using liquid.
Now my problem is that I can't do this with a custom front matter variable like author (as in site.authors) because Jekyll will not store it in a list format. This makes it very hard to paginate it.
The problem
Every solution I have looked at i.e.
how to handle multiple authors in Jekyll
adding authors to Jekyll
jekyll-author
requires me to hardcode a list of authors to _config.yml or some other .yml (i.e. in _data/authors.yml).
The problem here is that I don't use a fixed list of authors. The authors list needs to get updated when I throw in another post with a front-matter tag author: exampleAuthor or a list of authors (as in multiple authors per post, as currently only possible with categories and tags as well), while the server is running. It works with tags and categories splendidly, but not with custom tags like authors.
The easiest solution would to have a site.authors list to iterate over and just extending it with a ruby plugin.
I haven't found a plugin that provides me with a solution and thinking this was a common problem that I'm probably not the first to have.
What I tried
I then looked at writing my own ruby plugin (Which is hard on it's own because of the lack of documentation. Maybe I'm to dumb to google, but the resources I found where very limited and hardly enough to guide you through the process) but there has to be a reason why this is so hard to do that makes all the existing solutions require hard-coding the author list in a .yml (or .json, but most people go with .yml for some reason).
Doing this is out of the question for me, since I want to only throw in posts with author names in it later on and manipulating a .yml (I am under the impression that .yml-files don't get compiled once the server is started, like _config.yml, correct me if I'm wrong) would be counterproductive because it requires you to restart the server to have them compiled.
Even very advanced plugins like jekyll-paginate-v2 (which I use successfully to paginate posts by tags and categories) don't have a solution to this, as shown by this issue. As per this issue, it is getting recommended to misuse the category variable to paginate by author. In my opinion, that is desperate workaround and too hacky to be considered.
I have found suggestions that it could also be done with collections, but this would again
requiring to hard-coding the author list (again, I don't want that. I don't have a fixed list of authors. All of the author information has to come from the front-matter in the /_posts directory .md files)
As of now I don't see how it can be done with collections.
However I'm open to suggestions.
Edit: I found this dated issue on Jekylls github page which highlights that people are trying to do the same but to no avail.
Has this become viable in the last 4 years?
For someone still looking for a way to
Generate author pages automatically just by dropping author: name to post front matter,
Have pagination on the author pages (a good optimization).
I built a plugin jekyll-auto-authors that works in sync with jekyll-paginate-v2 to enable author auto pages along with pagination.
I wrote this guide and made this video to help with the setup.
The bare minimum setup instructions:
Install the plugin:
group :jekyll_plugins do
# other gems
gem "jekyll-paginate-v2" # reqiured for jekyll-auto-authors to work
gem "jekyll-auto-authors"
end
Enable it:
plugins:
# other plugins
- jekyll-paginate-v2
- jekyll-auto-authors
Make a data file with author data, for example using _data/authors.yml:
johndoe:
name: "John Doe"
bio: "John Doe is a software engineer."
email: "john#example.com"
socials:
github: "john-doe"
twitter: "john_doe"
janedoe:
name: "Jane Doe"
bio: "Jane Doe is a systems engineer."
email: "jane#example.com"
socials:
github: "jane-doe"
twitter: "jane_doe"
Make a layout for the author page, let's say _layout/author.html. Example layout can be taken from the article.
Enable pagination and auto pages for authors in _config.yml file:
pagination:
enabled: true
per_page: 9
permalink: '/page/:num/'
title: ':title - page :num'
sort_field: 'date'
sort_reverse: true
autopages:
enabled: true
# enable auto pages for tags/categories/collections as per need. Disabling for this demo.
tags:
enabled: false
categories:
enabled: false
collections:
enabled: false
authors:
enabled: true # adding false here stops the auto-generation
data: '_data/authors.yml' # Data file with the author details
layouts:
- 'author.html' # We'll define this layout later, will be used for each author
title: 'Posts by :author'
permalink: '/author/:author/'
slugify:
mode: 'default' # choose from [raw, default, pretty, ascii or latin]
cased: true # if true, the uppercase letters in slug will be converted to lowercase ones.
That's the initial setup!
Now drop in the author value in the front matter of posts:
---
# other configs
author: johndoe
---
This will generate a page as defined in the permalink block of the auto pages configuration. If there's pagination enabled, and per_page value is exceeded, the additional pages will be generated in /page/:num/ format.
To render the author values, the plugin exposes page.pagination.author_data value
{% assign author = page.pagination.author_data %}
<!-- Use {{ author.name }} or any such value, as defined inside the data file -->
To show next and previous buttons, you can use this logic that paginator exposes:
{% if paginator.total_pages > 1 %}
<ul>
{% if paginator.previous_page %}
<li>
Newer
</li>
{% endif %}
{% if paginator.next_page %}
<li>
Older
</li>
{% endif %}
</ul>
{% endif %}
The initial setup is overwhelming, but once done you can then just drop in author data inside _data/authors.yml file and add author: value inside post frontmatter and it is fairly easy then!
P.S. I developed this solution for Genics Blog as managing multiple authors got hard. To learn how I've implemented it at Genics, please check out the theme-files repository.
Update
I released v1.0.1 just now, which makes adding the data parameter to author autopage configuration optional.
If data isn't defined, you can still access the author username string with page.pagination.author. You can use it to show the username on the page.
If data is defined, page.pagination.author_data variable is available. This would be a hashmap that has data as defined in the data file.
This means that you just have to:
Add and enable the plugin.
Set up pagination and author pages config.
Make a layout file.
And you can just drop in author: username to post files to generate autopages for them with pagination!
Adding authors to Jekyll posts is easy with collections. Here's a proof of concept for you. Specifically, in this commit I add everything you need for it.
As for your question about pagination, will need to use a pagination plugin (paginate-v2 is good), as I believe the built in pagination only supports the posts collection.

How to generate a whole website in a variabilized sub-directory ? (Jekyll)

I've been playing around with Jekyll lately and recently discovered that S3 wouldn't allow me to have enough buckets to have one bucket per website.
So I'm struggling to figure out two things
1) How do I specify that I want a 'child' subdirectory to be created, and all the generated website's files to be in it ?
2) How do I use a variable as the 'child' subdirectory's name ? (since it will be different for each website)
The baseurl config option doesn't seem to do anything about that. Any idea will be welcome :-)
Thanks a lot, and have a great day !
I'm not sure about the variable option, however, for child sub-directories:
A) If you can put the content into "child" folders directly within the jekyll content, then use different configuration files to manage each site through build properties. See the examples under the example below.
B) If you just want to put the same content in different places, perhaps you could use different baseurl or destination properties in different config files? Use the same config file approach as below, but with different versions of those properties instead of/in combination with the exclude property (see https://jekyllrb.com/docs/configuration/#serve-command-options).
Example: Use different config files
Use the exclude config property to exclude folders (and all of that folder's contents) when running a build. You could also specify different output folder locations per site, base URLs, and so on. I'll focus on the exclude property, but you can find other useful properties in the documentation: https://jekyllrb.com/docs/configuration/#global-configuration
For example, you could have the following files/folders:
/siteA-folder/siteA-content/blah.html
/siteB-folder/siteB=content/meh.html
/siteC-folder/siteC=content/foo.html
config.yaml
config_buildA.yaml
config buildB.yaml
Use the build option --config FILE1[,FILE2...] (https://jekyllrb.com/docs/configuration/#build-command-options) to explicitly call your custom config file A or B, each of which has its own version of the exclude property.
Snippet from config_buildA.yaml:
exclude:
- /siteB-folder/ # While building A, you want to exclude the siteB folder and contents
- /siteC-folder/ # Similarly, exclude siteC contents
Snippet from config_buildB.yaml:
exclude:
- /siteA-folder/ # While building B, you want to exclude the siteA folder and contents
- /siteC-folder/ # Similarly, exclude siteC contents
Building A from the command line:
jekyll build --config config_buildA.yaml
Building B from the command line:
jekyll build --config config_buildB.yaml
By managing excludes in the config file, you can re-use the common templates and css, and keep everything together (using less disk space overall).
If there's shared content, you could also look into using a more advanced feature, includes (see https://jekyllrb.com/docs/includes/), to manage the shared content in the includes folder, referenced within the html or markdown files (but that's getting a little of the beaten track for your question, so I'll stop there...)
EDIT: I see you've edited the question specifying the baseurl property doesn't do what you're looking for.
I've used a combination of the url site property baseurl and destination similar to below. In my case, I have different destinations depending on whether it's an archive or latest content, but you could use this to build to different web folders if you wanted.
Ex: config for latest content
url: http://example.com
baseurl: "/latest/"
destination: /path/to/latest/output/
Ex: config for archived content
url: http://example.com
baseurl: "/archive/content/"
destination: /path/to/archive/output/
Then, using the multiple versions of the config file, I can just call whichever one applies.

Jekyll post not generated

I am trying to add a new post to my Jekyll site, but I cannot see it on the generated pages when I run jekyll serve.
What are some common reasons for a Jekyll post to not be generated?
The post is not placed in the _posts directory.
When you change the collections_dir in your config from . (default) to my_col_folder all your posts have to move as well below my_col_folder/_posts jekyll defaults
The post has incorrect title. Posts should be named YEAR-MONTH-DAY-title.MARKUP (Note the MARKUP extension, which is usually .md or .markdown)
The post's date is in the future. You can make the post visible by setting future: true in _config.yml (documentation)
The post has published: false in its front matter. Set it to true.
The title contains a : character. Replace it with &#58. Works in jekyll 3.8.3 (and probably in other 'recent' releases).
You can use jekyll build --verbose to view build process in detail.
Exmaple output:
Logging at level: debug
Configuration file: /home/fangxing/fffx.github.io/_config.yml
Logging at level: debug
Requiring: jekyll-archives
Requiring: jekyll-livereload
Requiring: kramdown
Source: /home/fangxing/fffx.github.io
Destination: /home/fangxing/fffx.github.io/_site
Incremental build: enabled
Generating...
EntryFilter: excluded /Gemfile
EntryFilter: excluded /Gemfile.lock
Reading: _posts/2018-01-14-new-post.md
Reading: _posts/2014-01-01-example-content.md
Reading: _posts/2014-01-02-introducing-lanyon.md
Reading: _posts/2017-11-21-welcome-to-jekyll.markdown
Reading: _posts/2018-01-14-boot-android-on-charge.md
Reading: _posts/2013-12-31-whats-jekyll.md
Skipping: _posts/2018-01-14-boot-android-on-charge.md has a future date
Generating: Jekyll::Archives::Archives finished in 0.000122873 seconds.
Generating: JekyllFeed::Generator finished in 0.000468846 seconds.
...
from the log I found jeklly skipped 2018-01-14-boot-android-on-charge.md because it has a future date.
One possible reason is that the date specified in the front matter does not contain a time zone offset, in which case it defaults to UTC, not the time zone of the local machine as you might expect. I wasted an hour on this until UTC "caught up" with my current local time zone, BST.
I haven't found a definitive answer to this but I think the date in the front matter must be given in UTC with a timezone offset (which defaults to zero if omitted).
So date: 2018-05-03 12:34:27 is in UTC irrespective of where in the world you are, and irrespective of the timezone setting in _config.yml.
So be careful to specify datetimes like this:
date: 2018-05-03 12:34:27 +0100
Or it can be browser cache as well if you are looking not in the _site folder but directly on the blog's main page with the list of posts.
I have written Rspec tests for my blog that express these rules:
require 'spec_helper'
require 'yaml'
# Documented at https://jekyllrb.com/news/2017/03/02/jekyll-3-4-1-released/
post_regex = %r!^(?:.+/)*(\d{2,4}-\d{1,2}-\d{1,2})-(.*)(\.[^.]+)$!
def date_in_front_matter(date)
return date if date.is_a?(Date)
return date.to_date if date.is_a?(Time)
return Date.parse(date) if date.is_a?(String)
end
describe 'posts' do
Dir.glob("_posts/*md").each do |file|
basename = File.basename(file)
context basename do
front_matter = YAML.load(File.read(file).split(/---/)[1])
it 'filename must match documented post regex' do
expect(basename).to match post_regex
end
it 'date in file name same day as date in front matter' do
date_in_file_name = Date.parse(post_regex.match(basename).captures[0])
expect(date_in_front_matter(front_matter['date'])).to eq date_in_file_name
end
it 'title in front matter should not contain a colon' do
expect(front_matter['title']).to_not match /:/
end
it 'front matter should not have published: false' do
expect(front_matter['published']).to_not be false
end
end
end
end
This may be of use to others as I was losing a lot of time due to typos in the date etc.
These tests along with the rest of the Rspec config can be seen in context here.
Just to add one more reason, when you move an article from _drafts to _post, you sometimes need to delete the _site for the article to be regenerated.
In my case it often happens that _site will not be entirely deleted before re-generation so the new article won't appear.
Anyway rm -rf _site and bundle exec jekyll serve works :)
If you are unable to track the file in --verbose and if the file is silently ignored then try removing collections_dir in the config.yml file. That solved the issue for me.
My post also did not appear an the error was, that in my name I used a dot, e.g. 2017-10-18-test.2.md.
This is not accepted, you have to use 2017-10-18-test2.md.
If you have checked your front matter, and all seems well, and even jekyll build --verbose doesn't reveal anything (in my case, it just acted as if the file didn't exist at all, not even listing it as excluded), check the encoding of your file. Apparently, it needs to be UTF-8 without signature. It it's UTF-8 BOM (or UTF-8 with Signature as some text editors call it), then it will be silently ignored. To make matters worse, some editors will display both types as just UTF-8, making the difference even harder to spot.

Jekyll use config.yml values in the HTML

Is it possible to setup configuration values within the config.yml file and have them be printed within the HTML page within Jekyll? I would like to set the default title and description of my website within the config.yml file and have them printed out in the header of all my layouts.
Every template has a site variable, which contains the settings from _config.yml. For example, if you have something like my_setting: "string" in _config.yml, you can access the value in a template using {{ site.my_setting }}.
Note: if you are using jekyll serve, you will need to restart the process for changes to take place. Indeed, _config.yml is not reloaded with the watch option.