Giter Club home page Giter Club logo

jekyll-postfiles's Introduction

jekyll-postfiles

Gem Version Gem Downloads Build Status

Easing the management of images (and other files) attached to Markdown posts

The pain of Jekyll's recommended posts assets management

Jekyll's natural way to deal with static files attached to posts, like images or PDFs, is to put them all in a global assets/ (or downloads/) folder at the site root. Read "Including images and resources" in Jekyll's documentation.

You can of course put files in subfolders of assets/, but it will be really cumbersome to manage posts' Markdown files in _posts/ or a subfolder, and images elsewhere, and then use the good hierarchy in all Markdown image tags.

Imagine you have these files:

_posts/
  2016-06/
    2016-06-09-so-long-cloudflare-and-thanks-for-all-the-fissh.md
…
assets/
  2016-06-09-cloudflare/
    cloudflare-architecture.png
    performance-report-sample.pdf

To use the image and PDF files in the post's Markdown, you will have to write this:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.

![Cloudflare architecture](/assets/2016-06-09-cloudflare/cloudflare-architecture.png)

Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.

Here is [an example of performance report](/assets/2016-06-09-cloudflare/performance-report-sample.pdf).

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.

Painful to write.

Imagine you want to change the post's publication date, or one of the file names?

Painful to update.

What if you want to put new WIP Markdown files in _drafts/, and the attached assets somewhere in a way they won't be copied to the destination _site/ folder next time you build the site? You can't put the files in the assets/ folder, so when you will publish the draft, you will have to change the assets location in the Markdown file.

Painful, and prone to errors.

And what about previewing the content while editing? If you use an editor like MacDown with live preview, how will it find the actual path to the images? What means /assets/… for the editor?

Painful to preview.

There must be another way

What if instead, you could have the files stored like that:

_posts/
  2016-06-09-cloudflare/
    2016-06-09-so-long-cloudflare-and-thanks-for-all-the-fissh.md
    cloudflare-architecture.png
    performance-report-sample.pdf

And if you could write your Markdown like this:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.

![Cloudflare architecture](cloudflare-architecture.png)

Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.

Here is [an example of performance report](performance-report-sample.pdf).

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.

Much easier!

  • Easy to store, everything is in one single folder.
  • Easy to write, no path to add to file links
  • Easy to update
  • Easy to move from _drafts/ to _posts/, without anything to change in the Markdown content
  • Easy to edit in any editor with live preview

Not every assets need this

Some Jekyll users will try to convince you it's a bad idea, because it means the asset is tightly linked to the post.

In my own experience, 95% of assets, at least, are used in one single post. And this is pretty common to find such requests from users of other static generators, like Hugo (fixed in May 2015), Nikola (already there, but not obvious or user friendly), Octopress, etc.

But it's true this might not be ideal for all assets (the remaining 5%), so you can of course continue using full assets paths with /assets/… to have a few assets shared by several posts.

How does it work?

This plugin takes any file that is in posts folders, and copy them to the folder in which the post HTML page will be created.

Let's say you have these files:

_posts/
  2016-06-09-cloudflare/
    2016-06-09-so-long-cloudflare-and-thanks-for-all-the-fissh.md
    cloudflare-architecture.png
    performance-report-sample.pdf

And your Jekyll settings for permalinks are these:

# Permalinks
permalink: /:year/:month/:day/:title/

Jekyll with this plugin will generate the site content like this:

2016/
  06/
    09/
      so-long-cloudflare-and-thanks-for-all-the-fissh/
        index.html
        cloudflare-logo.png
        performance-report-sample.pdf

If you change your Jekyll settings for permalinks like these:

# Permalinks
permalink: /:year/:month/:day/:title.html

Jekyll with this plugin will generate the site content like this:

2016/
  06/
    09/
      so-long-cloudflare-and-thanks-for-all-the-fissh.html
      cloudflare-logo.png
      performance-report-sample.pdf

Handy, isn't it?

Installation

Add gem 'jekyll-postfiles' to the jekyll_plugin group in your Gemfile:

source 'https://rubygems.org'

gem 'jekyll'

group :jekyll_plugins do
  gem 'jekyll-postfiles'
end

Then run bundle to install the gem.

Usage

You don't have anything to do.

Just put the images (and PDFs, etc.) in the same folder as your Markdown files, or even subfolders, and use the standard Markdown image syntax, with a relative path.

Compatibility

⚠️ This plugin is not supported by Github Pages, host your site on services like https://netlify.com which support third party plugins.

Contributing

Thanks for your interest in contributing! There are many ways to contribute to this project. Get started here.

License

The gem is available as open source under the terms of the MIT License.

Thanks

Inspired by this old Gist by @kevinoid.

jekyll-postfiles's People

Contributors

birch-san avatar dependabot-preview[bot] avatar dirtyf avatar nhoizey avatar p13i avatar tlnagy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jekyll-postfiles's Issues

support for img: tag in post header

---
layout: post
img: picture.png
tags: [sometag] # add tag
---

Is it possible to use pictures saved in certain post folder in this header section of a post?
Currently it generates:

<article class="post">
  
    <a class="post-thumbnail" style="background-image: url(/assets/img/picture.png)" href="/2020-10-13-test/"></a>
  
  <div class="post-content">
    <h2 class="post-title"><a href="/2020-10-13-test/">Test</a></h2>
    <p>Some body
</p>
    <span class="post-date">2020, Oct 13&nbsp;&nbsp;&nbsp;—&nbsp;</span>
    <span class="post-words">1 minute read</span>
  </div>
</article>

it tries to find the picture in main folder: /assets/img/picture.png

Support collections__dir

Jekyll 3.7.0 introduced a config setting to store all content in a collections_dir

Current behavior

Jekyll-postfiles assumes post and drafts are in source dir

posts_src_dir = site_srcroot + "_posts"
drafts_src_dir = site_srcroot + "_drafts"

Expected behavior

Given a `collections_dir: content` is set in Jekyll's `_config.yml`
When I use the `jekyll-postfiles` plugin
Then the plugin is able to find my posts in `content/_posts`
And my drafts in `content/_drafts`

Support normal pages as well

It would be great if this plugin wouldn't only support blog posts but also normal pages by putting images next to the permalink-defined location of static pages.

How to include plugin on a github.io site?

I would like to use the plugin on my github.io site.

I have followed the instructions for installation and the local build of the site on my laptop works correctly. However, after I push the code update to my github repo I don't know it github.io is correctly installing the plugin.

Can you help me?

jekyll-postfiles generated asset link will be broken after restart jekyll server

I host my Jekyll locally with "bundle exec jekyll server", as a local LAN team blog.
jekyll-postfiles works fine, I made modifications, add new files... when jekyll server is running
but if I stopped the "jekyll server", then restart it again
every url link to those asset files are messed.

it seems when jekyll server restarts, it won't invoke jekyll-postfiles to correct those asset link again.

List files in the same post directory?

Lets say my post has a bunch of images and I would like to show all the pictures. Is there a variable that is tracking all the files in the current post directory so I can forloop through it?

extract date field from folder name, instead of subfile

I'm not a big fan of specifying the date twice, eg:

- 2019-06-19-welcome/
  - 2019-06-19-welcome-to-jekyll.md

I know the parent folder doesn't need to have the date, but if it doesn't then it doesn't match the contents of the sorrounding posts. I'd prefer a directory format like this.

- 2019-06-19-welcome-to-jekyll/
  - index.md

Hard link to image does not work on index page

Hi,

I tested your plugin and I found out what looks like an incorrect behavior:

Given that I have a link to an image in the same folder than the post
When I launch `jekyll build`
Then link to image in `index.html` is generated as `src="/my-image.png"`
And link to image in article is generated as `src="/2017/10/03/my-image.png"`
# index.html displaying a loop of full content of posts with pagination (1 per page)
...
{{ post.content }}
...
# _posts/2017/10/03/my-article.md

![Alternative text](my-image.png)

Add test suite

There are four things needed for a plugin to be added to the Github Pages:

  • The plugin is useful for a vast majority of users
  • The plugin is available as a gem
  • The plugin is covered with an extensive test suite
  • The plugin is actively maintained

This plugin is a useful gem that is actively maintained. It only needs to be covered with a test suit. You have any plans for adding some tests?

stack level too deep (SystemStackError)

C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:73:in `parent_dirs': stack level too deep (SystemStackError)
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/lib/jekyll/cleaner.rb:77:in `parent_dirs'
         ... 9350 levels...
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/mercenary-0.3.6/lib/mercenary.rb:19:in `program'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/jekyll-3.2.1/exe/jekyll:13:in `<top (required)>'
        from C:/tools/ruby23/bin/jekyll:23:in `load'
        from C:/tools/ruby23/bin/jekyll:23:in `<main>'

There is similar issue:
tsmango/jekyll_alias_generator#12

Error : Is a directory @ unlink_internal

When I want to use this plugin with jekyll 3.2.1, I get the following error:
jekyll 3.2.1 | Error: Is a directory @ unlink_internal - /home/hnaseri/MyData/staticwebsite/jekyll/zabanshenas/site2/_site/assets
any Idea?

Doesn't work with jekyll 3.8.3

I don't know if it's a version problem...

When building I get:
Error: could not read file /Users/tgartner/git/playground_jekyll/_posts/2018-07-26-kids_daddeling/2018-07-26-kids_daddeling.jpg: invalid byte sequence in UTF-8
So obviously Jekyll is trying to interpret the jpg ?!

And it's not copied over into the post directory.
Jekyll -v: jekyll 3.8.3

Does not work with jekyll 3.9.0

Server address: http://127.0.0.1:4000
Server running... press ctrl-c to stop.
[2021-06-03 19:12:29] ERROR `/blog/test/test.png' not found.

Folder Structure:

_posts
       myfolder
            test.png
            2012-03-01-test.md

_site
    blog
        test
            index.html 

Note: the png has not been copied over from _posts to _site

Wrong "Sorry, there can be only one Markdown file in each directory"

[PostFiles] Sorry, there can be only one Markdown file in each directory containing other assets to be copied by jekyll-postfiles

This error appears in case if directory has more than one binary. E.g:

└── my_post
    ├── 1.jpg
    ├── 2.png
    └── my_post.md

This happens because all three entries considered as posts

# site.posts.docs =>
# [#<Jekyll::Document _drafts/my_post/my_post.md collection=posts>, 
#  #<Jekyll::Document _drafts/my_post/1.jpg collection=posts>, 
#  #<Jekyll::Document _drafts/my_post/2.png collection=posts>]
def generate(site)
  site.posts.docs.each do |post|
    copy_post_files(post)
  end
end

and this code results with other_md_count > 0, because (mdfilepath = 'my_post.md') != (post_path = '1.jpg')

# Count other Markdown files in the same directory
other_md_count = 0
other_md = Dir.glob(File.join(post_dir, '*.{md,markdown}'), File::FNM_CASEFOLD) do |mdfilepath|
  if mdfilepath != post_path # my_post.md != 1.jpg
    other_md_count += 1
  end
end

This is bug or Jekyll has changed their API about site.posts.docs? Or I do something wrong?

ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
jekyll 3.3.1
jekyll-postfiles (2.1.1)

(Sorry for my english)

add option to automatically create subdirectories for postfiles

The permalink for my posts is /posts/:year/:month/:day/:title:output_ext. Now if I have a posts directory like:

- _posts/
  - 2019-06-19-foo.md
  - 2019-06-19-bar/
    - bar.js
    - assets/
      - main.png

I get a built posts directory like this:

- _posts/
  - 2019/
    - 06/
      - 19/
        - foo.html
        - bar.html
        - bar.js
        - assets/
          - main.png

I can change the permalink to /posts/:year/:month/:day/:title/ and then I get

- _posts/
  - 2019/
    - 06/
      - 19/
        - foo/
          - index.html
        - bar/
          - index.html
          - bar.js
          - assets/
            - main.png

but I don't like the idea of a directory with only a single file (I.E. foo) so I propose we add an option in jekyll-postfiles where a directory is automatically created for a post if it has any postfiles (or exists in a subdirectory) such that:

- _posts/
  - 2019/
    - 06/
      - 19/
        - foo.html
        - bar/
          - index.html
          - bar.js
          - assets/
            - main.png

postfiles aren't matched against converters?

eg:

- _posts
  - 2019-06-19-welcome-to-jekyll/
    - 2019-06-19-welcome-to-jekyll.md
    - assets/
      - main.scss

output files:

- _posts
  - 2019-06-19-welcome-to-jekyll/
    - index.html
    - assets/
      - main.scss

the sass file isn't converted to css before being included in the build directory.

generating failed with a lowercased pdf extension (.pdf)

cannot work with a lowercased extension pdf file(.pdf), such as:
_posts/2019-06-02-ttt2/xxx.pdf
Jekyll Feed: Generating feed for posts
Liquid Exception: undefined method to_liquid' for #<Pathname:xxx.pdf> in sitemap.xml Error: undefined method to_liquid' for #Pathname:xxx.pdf
Error: Run jekyll build --trace for more information.

but it works fine if I changed the extension into uppercase PDF(.PDF):

 Regenerating: 1 file(s) changed at 2019-06-10 15:41:30
                _posts/2019-06-02-ttt2/xxx.PDF
   Jekyll Feed: Generating feed for posts
                ...done in 4.171719 seconds.

Does not work with Jekyll 4.0.0

Can't install together with Jekyll 4.0.0.
bundle install tells me:

Bundler could not find compatible versions for gem "jekyll":
  In snapshot (Gemfile.lock):
    jekyll (= 4.0.0)

  In Gemfile:
    jekyll-postfiles (~> 3.0.0) was resolved to 3.0.0, which depends on
      jekyll (~> 3.6)

Invalide byte sequence in UTF-8

Hi, I have an error even before building, just executing jekyll doctor.

Error: could not read file /Users/boris/Projects/perso/blog/jekyll-private/_posts/fr/papa/2016/2016-07-09-et-le-feu-ca-brule/1.jpg: invalid byte sequence in UTF-8

The same error is produced when I try to serve in verbose mode, I got this:

       ...
       EntryFilter: excluded /scripts
       EntryFilter: excluded /tasks
       EntryFilter: excluded /vendor
           Reading: _posts/en/default/2005-01-01-typo-test/2005-01-01-typo-test.md
           Reading: _posts/en/default/2014/2014-03-13-conquering-ab-testing/2014-03-13-conquering-ab-testing.md
           ... 
           ...
           Reading: _posts/fr/papa/2016/2016-07-01-esperanto/2016-07-01-esperanto.md
           Reading: _posts/fr/papa/2016/2016-07-09-et-le-feu-ca-brule/1.jpg
             Error: could not read file /Users/boris/Projects/perso/blog/jekyll-private/_posts/fr/papa/2016/2016-07-09-et-le-feu-ca-brule/1.jpg: invalid byte sequence in UTF-8
           Reading: _posts/fr/papa/2016/2016-07-09-et-le-feu-ca-brule/2016-07-09-et-le-feu-ca-brule.md
           Reading: _posts/fr/papa/2016/2016-07-10-tonton-et-tatie/2016-07-10-tonton-et-tatie.md
           ...
           ...
          Reading: _confs/sensibilisation-web.md
           Reading: _confs/web-disruption-continue.md
         Rendering: 2016/index.html
  Pre-Render Hooks: 2016/index.html
  Rendering Liquid: 2016/index.html
  Rendering Markup: 2016/index.html
  Rendering Layout: 2016/index.html
         Rendering: _posts/fr/default/2016/2016-06-15-conseils-pour-les-etudiants/2016-06-15-conseils-pour-les-etudiants.md
  Pre-Render Hooks: _posts/fr/default/2016/2016-06-15-conseils-pour-les-etudiants/2016-06-15-conseils-pour-les-etudiants.md
  Rendering Liquid: _posts/fr/default/2016/2016-06-15-conseils-pour-les-etudiants/2016-06-15-conseils-pour-les-etudiants.md
  Rendering Markup: _posts/fr/default/2016/2016-06-15-conseils-pour-les-etudiants/2016-06-15-conseils-pour-les-etudiants.md
         Requiring: kramdown
         Rendering: _posts/fr/papa/2016/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans.md
  Pre-Render Hooks: _posts/fr/papa/2016/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans.md
  Rendering Liquid: _posts/fr/papa/2016/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans.md
  Rendering Markup: _posts/fr/papa/2016/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans/2016-06-26-la-blockchain-expliquee-a-un-enfant-de-cinq-ans.md
  Liquid Exception: undefined method `gsub' for nil:NilClass in _layouts/archives-year.html
jekyll 3.2.0 | Error:  undefined method `gsub' for nil:NilClass

Can "companion" Markdown files be processed instead of treated as static?

I have a situation where I want to have some additional markdown pages that go with the post. I know I can do this "manually", but there are many conveniences to being able to use all of the other machinery that's built for posts. Right now, an ,md file alongside the main posting in a folder is treated by jekyll-postfiles as another static asset, and just copied to the _site. I'd like for it to (optionally) be processed to HTML.

At the moment, I don't understand what's under the hood of the Jekyll plugins and the overall workflow to render a site to know whether this is even possible. I'm hoping someone with more knowledge can say whether or not this would be possible by modifying jekyll-postfiles or whether it would need to be done completely differently?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.