Local post assets with Jekyll - jekyll

I was wondering how other people are organising their assets for individual posts when using Jekyll. For example, if a post has an image, do you just dump it in a shared images folder? I don't really like the idea of doing this - it means that an image is completely separated from a post, when I think they should be paired.

I wrote a plugin to let me organise assets in subdirectories easily:
https://github.com/samrayner/jekyll-asset-path-plugin
{% asset_path my-image.png %}
in post 2013-01-01-post-title would output:
/assets/posts/post-title/my-image.png
in page my-first-page would output:
/assets/my-first-page/my-image.png

I prefer to think of images as stand alone assets that are included in zero or more pages. Most of the time, my images show up in a single page. There are times when I want to have them in multiple pages and in other cases I don't link an image at all. If your workflow is to put each image in a directory with a post, finding them starts to require a significant amount of searching and you have to come up with something different for images that don't belong to a specific post.
The approach I use is on the opposite side of the spectrum. I have a single image directory (served from "/images") and 100% of my images are housed there. Benefits of this are:
When I'm adding an image to a post it's easy to know what path to use. It's always:
/images/{image-name}
For example: http://alanwsmith.com/i/aws-20111017--0906-02. This makes it possible to write a plug-in so all you have to enter is the image name and the rest of the known path is filled out automatically.
With an application like Photo Mechanic, it's incredibly easy to browse the single directory locally and see every image. If I want to include an image on another page, this drastically reduces the time to find it.
There isn't a separate location/process if I want to send an image to someone without actually including it in a page (i.e. send them a direct link to the image file). I just throw the image in the standard directory and send the direct link.
If you want to get a little more advanced, keeping all your images in a single directory makes some nice tweaks possible as well. For example, even though the URLs for my images start with "/images", the images are actually stored in a directory outside of the ones jekyll uses. In my case, the top of my source tree looks like this:
./html
./source-files
./image-files
All of my images are stored in the "./image-files" directory. In my apache config, I've setup an alias so that the URL "/images" points to the "./image-files" directory. For example:
Alias /images /webroot/image-files
When I run jekyll, it process everything in "./source-files" and drops it in "./html". Because all of the images are outside those two directories, jekyll never sees/touches them. As your image library grows this will help speed things up and will prevent a tremendous amount of unnecessary file copying.
Another tweak I like in Apache is turning on:
Options +MultiViews
This lets you call your images without having to use the file extension (e.g. no '.jpg', '.png', etc...). You can see that in the example link I provided above. It doesn't really matter for performance. I just like the way it looks and it saves me from having to type the extension every time I'm calling an image.
MultiViews also makes it possible to replace an image of one format with another without having to recode anything else. For example, if you remove "some-image.gif" and replace it with "some-image.png", you wouldn't have to touch any HTML. It would still be served form "/images/some-image". Needing to make changes like that is probably exceedingly rare. I just think it's an interesting thing to be able to do.
Finally, you can make a single decision about allowing or disallowing your image directory to be browsed. Personally, I only want my images to show up where I place them. So, I've set the .htaccess file in my images directory to:
Options -Indexes
If you are going to be working on a site with many thousands or tens of thousands of pages and images, this might not scale. For a normal sized, personal site, I find that this approach makes maintaining images easier.

I have now managed to develop a Jekyll plugin that helps keep posts assets alongside the Markdown file:
https://nhoizey.github.io/jekyll-postfiles/

Just like you, I really hate having all images in one single shared folder.
Most, if not all, of my images are useful in one single post, and keeping them alongside the Markdown file is really better for posts management:
I can drop a new post as one single sub-folder of /_posts/ in one step, without having to put the Markdown at one place and the image(s) at another
When I want to edit the image(s) of an existing post, I don't have to find the right image in a huge /assets/ folder, it is located just near the Markdown file
In my Markdown, I can use the image file name directly, without any path
If I want to use any Markdown editor with live preview, it works, no need for a specific assets folder configuration
I tried to have this for my blog (example post here).
For responsive images, I used the Jekyll Picture Tag plugin, but I had to fork it, because the Pull Request to deal with such paths was not accepted.
Now that Jekyll 3 is there, I wish it could let us use images both in a post folder AND in the /assets/ one, looking for an image marked with ![alt](image-file-without-path.jpg) in both, in that order.

For JavaScript and CSS, you may want to consider an asset pipeline. You can get a good performance improvement through bundling and compression. I also use CoffeeScript and Sass, so I needed a preprocessor to convert my assets. I use Jekyll Asset Pipeline to manage this whole process automatically when I run the jekyll command.
For images/video, I recommend you develop a convention for naming folders in your project. I generally have an "assets" folder then subfolders with the date of each post that holds the images related to those posts. If you have multiple posts per day, you might consider including the name of the post.

This answer:
Does not use plugins (works with GitHub Pages)
Allows you to keep images directly next to their relevant posts
Allows you to edit using Typora locally and see the images WYSIWYG
Just name your folders like _posts/2020-10-10-My-Title/ and include files like index.md and hero.svg or other images.
Then set your permalink: key in _config.yaml to :path.
Caveats:
Your folder names must be sluggified
Your images must all be SVG

Related

Pre-Linking Pages in HTML Before Uploading

I am currently creating a website with over 700 pages and I would like to be able to link them together before I upload the files to my host server if possible. Is there a good way to link pages together pre-upload without for sure knowing what the final URLs are going to be?
I am working in and plan to upload/manage my website files through Dreamweaver.
I have seen the prompt in Dreamweaver to update links before. If I link the file paths now, will it update to the URLs when the site is uploaded?
you need to use root-relative links. do some searching on that. as long as you don't change your file structure you will be good where your site is run.
instead of using absolute links such as http://www.website.com/folder1/page1
you would use /folder1/page1
as long as your root was where you started the paths from you can start with "/" as above.
there are some instances where you would do a relative link from a certain folder to another one ../folder1/page1 this is not something i would recommend here.
good luck and comment on this if you have more questions.

A static blog generator with multiple image directories

Question: what software should I use to achieve a static site generator like described below?
I'm looking for a static blog generator, which... generates static blogs, of course :). However I need something more, like a nice set of themes to choose from, and, what is even more important, a specific way of managing assets.
When I write articles/posts/text, I create a new directory. Then inside I have a file like article.md, or article.textile. I also have files with code, and pictures, and charts etc. Everything is inside this one directory. Then I used to run a tool to convert it to html, and copy the html to a website for publishing. However there was always a problem with images. I had to copy the images somewhere e.g. to Wordpress and then change the image urls in the html. This is not the best way to do it.
I'd like to have a static blog generator, which would let me keep my normal structure: one directory per post, and keep all the images from the directory in generated structure, so I can have relative paths to the images.
I really don't like the idea to keep all articles in one global directory, and all images in another global one.
I've checked jekyll, and pelican so far, and read about couple others, but I haven't found any solution to that problem. I know that, as usually, you will have many nice ideas to check.
And of course I know that most probably this post will be "closed and not constructive", or with any other funny explanation, but maybe someone will manage to post any solution before that.
Hugo can do this. cd to empty folder of your choice, then
create the scaffolding:
hugo new site .
After that you can put your content in content, example:
content
post
alpha
index.md
1.jpg
2.jpg
bravo
index.md
1.jpg
2.jpg
Build site:
hugo
Result is generated in public folder:
public
post
alpha
index.html
1.jpg
2.jpg
bravo
index.html
1.jpg
2.jpg
Jekyll does not explicitly enforce a rule about where to put your assets like images with the exception that Jekyll will not copy files directly in a folder beginning with an underscore. Although the general practice would be to put all images in the \assets\ directory, you can put it anywhere else other than the _posts\ directory, which is what you wanted.
This is the default behavior, but there are ways to get around this:
Have your posts live outside the _posts directory
Put all your posts outside the default _posts folder along with the images (this will copy all the files without any YAML frontmatter, and preprocess all the files with the YAML frontmatter). However, any other function you can do with posts automatically in Jekyll won't work anymore. This may or may not be an issue.
Plugins
Here's a plugin (link to SO question) written specifically for making Jekyll copy files in the post directory. If you do use this you can definitely just write the following Markdown and it'll link relative to the post as it should. :
![Image title](my_image_filename.png)
Jekyll asset path plugin is another robust plugin that does something similar, but does not keep your images in one directory, it does however link images relative to your post title though.
Jekyll asset pipeline is another another plugin that handles CSS and JS, which might be something you want to have in conjunction with plugin 1.
Do note however that the use of third party plugins is not supported with GitHub Pages site generation, meaning you will have to generate them in another branch or locally, and then pushing the static HTML files to master. This might be an issue for you if you're planning to host with GitHub Pages, else on your own server instance you're good to go.
I also want my posts to be "self contained", text content and image assets being in one single folder. I'm using Jekyll.
I have made this possible with a Pull Request on the great jekyll-picture plugin.
I can then use the simple {% picture my-image.png %} syntax to show the image in my post that is in the same folder.
Here is an example: https://github.com/nhoizey/nicolas-hoizey.com/tree/master/_posts/2015/06/19-mon-jeu-esviji-integre-a-framagames
One year after my previous answer, I have now developed a Jekyll plugin that helps keep posts assets alongside the Markdown file, it might fill your needs: https://nhoizey.github.io/jekyll_post_files/

Is there a way to export a page with CSS/images/etc using relative paths?

I work on a very large enterprise web application - and I created a prototype HTML page that is very simple - it is just a list of CSS and JS includes with very little markup. However, it contains a total of 57 CSS includes and 271 javascript includes (crazy right??)
In production these CSS/JS files will be minified and combined in various ways, but for dev purposes I am not going to bother.
The HTML is being served by a simple apache HTTP server and I am hitting it with a URL like this: http://localhost/demo.html and I share this link to others but you must be behind the firewall to access it.
I would like to package up this one HTML file with all referenced JS and CSS files into a ZIP file and share this with others so that all one would need to do is unzip and directly open the HTML file.
I have 2 problems:
The CSS files reference images using URLs like this url(/path/to/image.png) which are not relative, so if you unzip and view the HTML these links will be broken
There are literally thousands of other JS/CSS files/images that are also in these same folders that the demo doesn't use, so just zipping up the entire folder will result in a very bloated zip file
Anyway -
I create these types of demos on a regular basis, is there some easy way to create a ZIP that will:
Have updated CSS files that use relative URLs instead
Only include the JS/CSS that this html references, plus only those images which the specific CSS files reference as well
If I could do this without a bunch of manual work, if it could be automatic somehow, that would be so awesome!
As an example, one CSS file might have the following path and file name.
/ui/demoapp/css/theme.css
In this CSS file you'll find many image references like this one:
url(/ui/common/img/background.png)
I believe for this to work the relative image path should look like this:
url(../../common/img/background.png)
I am going to answer my own question because I have solved the problem for my own purposes. There are 2 options that I have found useful:
Modern browsers have a "Save Page As..." option under the File menu, or in Chrome on the one menu. This, however does not always work properly when the page is generated by javascript
I created my own custom application that can parse out all of the CSS/Javascript resources and transform the CSS references to relative URLs; however, this is not really a good answer for others.
If anyone else is aware of a commonly available utility or something like that which is better than using the browser built in "Save page as..." option - feel free to post another answer.

Correct folder structure for sites

I've just started tidying up the server for a particular site and am running into some trouble when moving files.
I originally had style.css in my main folder, and another folder called images, so paths in the .css went images/myimage.png
Now I have moved style.css into another folder called css.
So the image links in the CSS no longer work, as it's looking for the folder images from it's own CSS folder.
I changed the file path to /images/myimage.png as I thought this would make it climb up a level and then look for the images folder, but this doesn't seem to work.
I'm interested to see what solutions people have and also any suggestions on how people organise their folders for a particular site.
Thanks!
Do this ../images/myimage.png
This should work, for each level you want to go up, add ../
Primary resources I structure in a way that will give some sort of mnemonic to the client process. E.g. if I have a bunch of resources representing employees, I'd put each at /employees/alice, /employees/bob, etc. If I have a resource representing all employees (a list etc.) I'd put it at /employees/, but if I didn't I'd still use that structure.
If this hierarchy is relatively simple, I'll follow it in terms of where I place the files.
If modelling something that is in itself hierarchical, I'd follow that hierarchy in the URI mapping. E.g. /ireland/leinster/coDublin/dublin. In this case I'd rather have the handler somewhere that doesn't have a direct correspondence to the path, like in wwwroot\placesHandler, as following it a bit, but not fully is less clear than obviously not following it.
For secondary resources like images, css, etc that are just part of rendering an entity rather than of primary interest to the client process, (most common on browser-focused human-readable sites). I normally just have an /s/ an /i/ and a /js/ and go with the fact that by default pretty much all webservers will mirror the directory structure of your files in the path-structure of the site. Within those I'll group /i/ and perhaps /js/ according to purpose.
And as I said in the comments, /images/myimage.png will mean http://whateverTheSiteDomainIs/images/myimage.png, to "climb up one" you want ../images/myimage.png.

referring to .css and images from script-generated HTML

I have a site with static HTML pages in the home directory. These HTML pages use relative paths to refer to images, css, and links i.e.
<img src="images/myimg.gif">
and
Contact Us
I also have a monolithic script whose URL is, i.e. http://mysite.com/myScript which uses "extra path info" to select functions... i.e. http://mysite.com/myScript/products shows a list of products. So in HTML generated from the script I need to refer to images, css and links like this:
<img src="../images/myimg.gif">
and
Contact Us
The problem is now I want to start moving common HTML into include files, (e.g. common header and footer), but the fact that the script and the static HTML refer to relative resources in different ways is complicating matters.
I don't want to use absolute paths because that messes up my colleague's work when she tries to work on the pages in DramWeaver, and it also makes the site less flexible.
What's the best way to solve this issue? One idea I had was to use URL rewriting in Apache to allow the URL to http://mysite.com/products to really use http://mysite.com/myScript/products but I don't have experience with URL rewriting so I don't know how easy that would be. Another idea I had was to use the META BASE attribute in HTML but I don't like the fact that I would have to hard-code that into every HTML page, and it would have to have the full URL hard-coded (e.g. http://mysite.com/) into each one. Any advice?
Can't you refer to your images with a slash at the beginning so all files linked to are from the root, no matter how deep you are in the directory structure you are? E.g:
<img src="/images/myimg.gif" />
EDIT:
You could use $_SERVER to get the path then use substr_count to count the number of slashes in the path. Add as many ../'s as you need based on that number. Would that work for you?