12
votes

I'm considering Jekyll for a site I'm putting together that will be a blog with lots of images (and other larg-ish media files). It's easy enough to to make a directory for images and then link to them as needed in the posts. But, as I understand it, when the site is generated, all the image data will be duplicated into the generated _site directory that holds the static files. Each time the site is generated the _site directory is emptied, and repopulated with the static version of the site.

Is there any way to, for example, drop a symlink to the images directory inside the site directory, and then maybe have jekyll ignore it when the static files are generated?

Or is there another way to go about this that makes more sense?

4

4 Answers

11
votes

Assuming you are running on an apache web server, you can setup an Alias directive to serve images from a directory outside of the normal docroot. You need access to edit the VirtualHosts config or some other ability to create aliases directives (e.g. via a control panel).

For an example of how this would work, let's say you are storing your jekyll files under a directory called "/web/jekyll". To get your images directory do the following:

  1. Add an "_images" directory along with your basic jekyll tree. Ending up with something like:

    _config.yml
    _images/
    _layouts/
    _posts/
    _site/
    index.md
    
  2. Update your apache config to add the Alias directive like:

    Alias /images /web/jekyll/_images
    
  3. Reload the apache config and run jekyll to build the site.

Since the image directory name starts with an underscore, jekyll won't push/copy it to the output _site during the build. Apache will happily serve most files from your _site directory as normal, but when it sees something like "http://jekyll/images/test.jpg", instead of looking for the file under "/web/jekyll/_site/_images/test.jpg", it'll serve it from "/web/jekyll/_images/test.jpg".


Incidentally, I like a little more separation of the source content and output content than jekyll defaults to. So, I setup my directory structure as follows:

/web/jekyll/html/
/web/jekyll/images/
/web/jekyll/source/
/web/jekyll/source/_config.yml
/web/jekyll/source/_layouts
/web/jekyll/source/_posts
/web/jekyll/source/index.md

With the following option set in _config.yml

destination: ../html

And the apache alias directive setup with:

Alias /images /web/jekyll/images

Jekyll is run in the "/web/jekyll/source" directory, but output is sent to the "/web/jekyll/html" dir. Similar to the first example, calls to "http://jekyll/images/test.jpg" are served from "/web/jekyll/images/test.jpg". This setup doesn't really make a difference from a site serving perspective. I just like the cleaner separation between the raw source files, the fully baked output files and the images which work via the alias.

0
votes

Correct, the first part of the jekyll command removes everything in the destination directory. The problem with that is the symlinks must be manually created again. So next, go ahead and create a script that does this each time.

Be sure that:

exclude: [jekyll, css, img] in the _config.yml file

linux: The ";" symbol runs first, second, third.. commands.

script: A file named jekyll with executable permissions containing

 jekyll;
 ln -s /var/www/css /var/www/_site/css;
 ln -s /var/www/img /var/www/_site/img;

Finally run (./jekyll) that program instead of jekyll.

-Dan

0
votes
  1. Make a project page for the images.
  2. Set up directory structure

    /home/git/svnpenn.github.io
    /home/git/img
    
  3. Run Jekyll

    # We cant add the symlink until after jekyll is done. We will remove the
    # site folder and wait for it to rebuild.
    rm -r _site
    jekyll --server &
    while [ ! -f _site/index.html ]
    do
      sleep 1
    done
    ln -s ../images _site/images
    

Note I was using this because I thought it would help publish time on GitHub pages. It does not. GitHub can take 1-10 minutes to publish depending on the server.

0
votes

I know this has already been answered, but I went a slightly different route. I hosted all of my images in a public directory on Dropbox and use grunt to generate a manifest of the images. It keeps my repository small because the images don't get checked in. I detailed it a while back in a blog post.