4

I am creating blog with Jekyll and for the sake of organization I have decided to put the images under the folder: "assets/img/[post name]/". The folders look like this:

.
├── assets
│   ├── css
│   │   ├── BMFW.css
│   │   └── vs.css
│   └── img
│       └── 2021-05-23-Blog-presentation
│           └── test.jpg <--
├── _config.yml
├── Gemfile
├── Gemfile.lock
├── index.html
├── _layouts
│   ├── layout.html
│   └── post.html
├── _posts
│   └── 2021-05-23-Blog-presentation.md
├── README.md
└── script
    └── cibuild

Seems that the page.name variable for some reason does not exist (I have checked it with {{page | inspect}}) so I use this line to get the name of the post:

{{ page.path | replace: ".md","" | split: "/" | slice: -1 | }}

That means that if I want to display an image called test.jpg I would write:

![]({{ site.baseurl }}/assets/img/{{ page.path | replace: ".md","" | split: "/" | slice: -1 | }}/test.jpg)

The only thing that changes from one image to another is the name of the image. So my question is: is there a way to set a base path, in my case {{ site.baseurl }}/assets/img/{{ page.path | replace: ".md","" | split: "/" | slice: -1 | }}/, so I don't have to write the full path over and over again?

The ideal solution would be to just have to write ![]({{media}}/test.jpg) or similar.

EDIT 1:

Just in case it is useful for anybody, what I am doing now is to put this line at the beginning of each blog entry:

{% assign media = site.baseurl | append: "assets/media/" | append:  page.path | replace: ".md","" | replace: "_posts/",""  %}

So then I can insert images just writing:

![]({{ media }}/test.jpg)

It is not a solution because I still have to put that line at the beginning of every post but is better than before.

EDIT 2:

I have looked to make some custom pluggin in Jekyll but I haven't found a way to get access to the page properties.

Another option was to create a custom tag that inserted the liquid code: {{site.baseurl | append: "assets/media/" | append: page.path | replace: ".md","" | replace: "_posts/","" }}. The problem with this one is that once the custom tag has ben executed jekyll continues and does not execute the newly inserted liquid code.

edoelas
  • 317
  • 2
  • 13

2 Answers2

0

To avoid repetition in Jekyll, you use includes. You could make a _includes/image.html file like this:

{% assign media = site.baseurl | append: "assets/media/" | append:  include.post | replace: ".md","" | replace: "_posts/",""  %}
<img src="{{ media }}/{{ include.file }}">

and use it like this:

{% include image.html post=page.path file="test_1.jpg" %}
{% include image.html post=page.path file="test_2.jpg" %}

The only problem is that the included file can't see anything from the file that's not passed as a parameter, so we can't get rid of the post=page.page part. However, that's less repetition than with your current solution.

Related: Macro in Liquid template language.

Miguel
  • 2,130
  • 1
  • 11
  • 26
  • 1
    It is a solution to avoid repeating the same line at the begining of each post, but I find more tedious having to write `{% include image.html post=page.path file="test_1.jpg" %}` each time I want to insert an image than copy pasting a longer line at the begining and forgeting about it. – edoelas Jun 14 '21 at 18:26
  • Yes, you are completely right. Jekyll doesn't offer much options in this regard (as far as I know)... I'll leave the answer anyways, in case other person finds it useful. – Miguel Jun 14 '21 at 18:34
  • I have thought of very weird way of doing it, but I have to test it first to make sure that it is possible. I am using a custom renderer, so I could modify the image markdown tags to add the path during the translation from markdown to html. – edoelas Jun 14 '21 at 18:38
  • That sounds actually as a good idea. In my opinion, full customization always require some processing by the side of the programmer user. – Miguel Jun 14 '21 at 19:14
  • I just decided this is a bad Idea. I am changing how the item tag works, that should not be done. But I might create an aditional markdown element, something like `:media:` that is substituted by the actual path. – edoelas Jun 14 '21 at 19:40
0

Would using static files in Jekyll be sufficient for setting the base path for all your image assets?

Add to _config.yml:

defaults:
  - scope:
      path: "assets/img"

All the static files will have base path assets/img added to their file.path metadata.

Edit: Here is Liquid snippet on getting the path in the defaults

{% assign defaults = site.defaults %}
{{ defaults[0].scope.path | inspect }}
ti7
  • 16,375
  • 6
  • 40
  • 68
Kin
  • 1,435
  • 10
  • 16
  • I would prefer to have my images organized in folders based on the name of the post. As far as I know this solution requires to have all the media in the same folder. – edoelas Jun 21 '21 at 09:09