Problem with images in posts

179 views
Skip to first unread message

Jérémie Bresson

unread,
Jan 5, 2016, 6:36:06 AM1/5/16
to JBake Users

I wanted to add images in my blog posts. I now have path problems depending because the path to this image is not the same, depending on which page the post is displayed.

 

Example of the output:

jbake-sample

|   about.html

|   archive.html

|   favicon.ico

|   feed.xml

|   index.html

|   sitemap.xml

|   tree.txt

|  

+---blog

|   \---2013

|           first-post.html

|           fourth-post.html

|           jbake-logo.png

|           second-post.html

|           third-post.html

|          

+---css

|       ...

|      

+---fonts

|       ...

|      

\---js

        ...


See it online: http://jmini.github.io/jbake-sample/


My problem is that the content of "fourth-post.adoc" (which uses this image) is printed at different places:

And the path to this image is not the same depending on the where the article is printed.

 

The path to the jbake-logo.png image is: ${rootpath}/blog/2013/jbake-logo.png

 

But the rootpath variable is template stuff and not something you can use in the post source.

My guess is that Asciidoctor could handle it (because there is this notion of variables) but it doesn’t make sense for HTML or Markdown sources.

 

I my opinion, it is the responsibility of JBake to fix the images path before including the post to the definitive page.

 

Please tell me if I missed something, otherwise I think I can fix it with a goovy method I will call before the post content is printed to the output file.

 

Jérémie Bresson

unread,
Jan 11, 2016, 3:56:50 PM1/11/16
to JBake Users

If anyone is interested, here is how my Proof of Concept code looks like to fix the image path. The idea is to fix the src attribute of all img tags before adding the content to the output file.

I will put this code in a Jar, add it on the JBake classpath (I am using the JBake maven plugin) and I will call it from the groovy template (in the gsp files).


import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public final class HtmlUtility {

 
public static String fixHtml(String htmlContent, String imgPrefixPath) {
   
Document doc = Jsoup.parseBodyFragment(htmlContent);
    doc
.outputSettings().charset("ASCII");

   
Elements elements = doc.getElementsByTag("img");
   
for (Element e : elements) {
     
String src = e.attr("src");
     
if (src != null) {
       
String newSrc = imgPrefixPath + src;
        e
.attr("src", newSrc);
     
}
   
}

   
return doc.body().html();
 
}
}

The definitive solution might be a little bit different. I have some optimizations in mind.

The complete jar will be available in this project (work in progress):
https://github.com/jmini/htmltools-jbake

And I will use it on my blog:
https://github.com/jmini/jmini.github.io

Now that I have created this project, I will also use it to store the code I have written to solve my "view on GitHub link" problem.

Jonathan Bullock

unread,
Jan 13, 2016, 8:05:19 AM1/13/16
to Jérémie Bresson, JBake Users
Hi Jérémie,

This is an issue that has been raised before, and I agree it is JBake's responsibility to address.

My plan was to address this via the plugin/extension system that has been in the pipeline for a while, but unfortunately is still in the planning phase, as some users have indicated they would want more than just image paths to be processed.

Thanks for sharing your solution, it may be worth adding a similar solution into the core of JBake until the plugin/extension system arrives if you would be interested?

Thanks,
Jon

--
You received this message because you are subscribed to the Google Groups "JBake Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jbake-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jérémie Bresson

unread,
Jan 15, 2016, 2:44:30 AM1/15/16
to JBake Users, jebr...@gmail.com

Hi Jon,


I am definitively interested…

The other types of path I can imagine are link to other pages/articles. Any other know issue in this domain?

 

My current solution relies on JSoup. Is this OK for you? Or do you prefer using another approach?

 

For the moment I did not took the time have a look at the code base. I need to setup an IDE for JBake.

 

I appreciate any pointer you can provide (What are the involved classes? Where should I add my code? ...).

Jonathan Bullock

unread,
Jan 17, 2016, 10:32:11 AM1/17/16
to Jérémie Bresson, JBake Users
Hi Jérémie,

You are correct that is the other main use case, for more info on what the plan for the plugin system looked like see: https://github.com/jbake-org/jbake/wiki/Plugin-System

Using JSoup is absolutely fine with me.


Jon

Jérémie Bresson

unread,
Feb 16, 2016, 11:59:19 PM2/16/16
to JBake Users

I am happy to inform you that the version 1.0.1 of my Utility Class contains the fix that handle the "href" attribute of the <a> tag.

 

This demonstration site now works as expected:

http://jmini.github.io/jbake-sample

(Notice the image and the links on the first page).

 

Feedback is appreciated.

 

Next step for me: propose this implementation as a patch for JBake (as discussed in the previous messages).



Le mardi 5 janvier 2016 12:36:06 UTC+1, Jérémie Bresson a écrit :

Jonathan Bullock

unread,
Mar 1, 2016, 8:39:22 AM3/1/16
to Jérémie Bresson, JBake Users
Excellent, looking forward to merging in the patch :)

Jon

--

m...@wadechandler.com

unread,
May 3, 2017, 6:15:26 AM5/3/17
to JBake Users, jebr...@gmail.com
On Tuesday, March 1, 2016 at 8:39:22 AM UTC-5, Jonathan Bullock wrote:
> Excellent, looking forward to merging in the patch :)
>
>

Jon,

Was this merged in? If so, is it in the documentation how this would work?

Thanks,

Wade

Jonathan Bullock

unread,
May 3, 2017, 7:37:55 AM5/3/17
to m...@wadechandler.com, JBake Users, Jérémie Bresson
Hi Wade,

No a PR was never raised for this as far as I'm aware.

Jon

--
You received this message because you are subscribed to the Google Groups "JBake Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jbake-user+unsubscribe@googlegroups.com.

Jérémie Bresson

unread,
May 7, 2017, 10:57:11 PM5/7/17
to JBake Users, m...@wadechandler.com, jebr...@gmail.com
This is absolutelly true... I am sorry about that and I will try to work on it.


Le mercredi 3 mai 2017 13:37:55 UTC+2, Jonathan Bullock a écrit :
Hi Wade,

No a PR was never raised for this as far as I'm aware.

Jon
On 3 May 2017 at 11:15, <m...@wadechandler.com> wrote:
On Tuesday, March 1, 2016 at 8:39:22 AM UTC-5, Jonathan Bullock wrote:
> Excellent, looking forward to merging in the patch :)
>
>

Jon,

Was this merged in? If so, is it in the documentation how this would work?

Thanks,

Wade

--
You received this message because you are subscribed to the Google Groups "JBake Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jbake-user+...@googlegroups.com.

dorin....@gmail.com

unread,
May 8, 2017, 5:27:19 AM5/8/17
to JBake Users
1. workaround 1 - I moved all my blogs inside the "content" directory and delete the "blog" directory
I moved "about" page into a sub-directory "more" inside "content" (easy to work when you need to regenerate blogs and bulk delete all 1000 blogs) and updated menu template.

2. Workaround - inside *.md we should have a conditional parsing like
if( #system.pages_are_for_index)
.....lines for index with all posts
else if( #system.pages_are_for_index)
..... lines for post
else if .... other tags fr other pages

How can we add lines to blogs that are parsed conditionally (we should have some way to path lines and some system variables to use)

Thank you

Dorin

Jonathan Bullock

unread,
May 12, 2017, 2:33:18 PM5/12/17
to dorin....@gmail.com, JBake Users
Jérémie,

No need to apologise, is your code change online somewhere I can see?

Jon 

--
You received this message because you are subscribed to the Google Groups "JBake Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jbake-user+unsubscribe@googlegroups.com.

Jonathan Bullock

unread,
May 12, 2017, 2:40:18 PM5/12/17
to dorin....@gmail.com, JBake Users
Dorin,

I'm not sure I follow what you've said. Is 1 a proposed workaround or something you've already done? Is 2 what you'd like to see? 

Any conditional parsing of content files has to work with both Markdown files as well as HTML and AsciiDoc, the later may not have a JBake specific metadata header either. Perhaps one solution would be to support more advanced metadata headers than just Java properties... 

Jon

On 8 May 2017 at 10:27, <dorin....@gmail.com> wrote:

dorin....@gmail.com

unread,
May 12, 2017, 3:35:49 PM5/12/17
to JBake Users, dorin....@gmail.com
Hello,

1. With workaround 1 Jbake generated code is already working here
https://storage.googleapis.com/apiabuc/jbake_test_100/output/index.html
I moved the specific pages like "about" into another directories because I have to manually or programmatic move and delete file at regenerating the site (output directory is not deleted by jbake -b, my engine generation of files and images toward jbake ...)

2. Any template language should offer a way to escape some special terms to you, to jbake. Conditional compiling of templates should be implemented in some of the template languages.
If some do not support, we have to migrate to other that can support escape forms. This is one use of compiling directoves, for this workarund, but in the future there may be other mandatory programming that we should do in templates and send info to JBake
Let me repeat here and check if it is good
if( #jbake.compile.pages_for_index)
.....lines for index with all posts (link type one to images = images/pic.jpg)
else if( #jbake.compile.details_pages)
..... lines for post (link type two to images = ../images/pic.jpg)
else if .... other tags for other pages, other links ...


Thank you

Dorin

Jonathan Bullock

unread,
May 16, 2017, 5:51:14 PM5/16/17
to Dorin Ionescu, JBake Users
Hi Dorin,

Thanks for clarifying.

All the template engines supported by JBake provide some kind of conditional compiling or rendering and what you suggest is certainly possible, however, I don't think performing this manipulation of image url's in the templates themselves is a scalable solution. I'd like to see this problem solved by JBake in a more automated way so the end user has to do less work.

Regards,
Jon

Wade Chandler

unread,
May 16, 2017, 10:02:45 PM5/16/17
to Jonathan Bullock, JBake Users, Dorin Ionescu
I was thinking a collective way to allow flexible processing in content could be to:

1) Allow content meta-data files independent of the content file, perhaps a file named the same ending with .yml or .json and support both those formats. The page type etc would go here along with other custom data.

2) Have more global variables to support image directories or other items defined in global meta-data and/or conventional properties/values accessible by a context which is available at render time; defined by JBake.

3) Allow content to be any supported template language such as Groovy template content.

4) Have a default template language which could be embedded inside any content file similar to how Liquid from Jekyll works; could be a pre-processing which runs over the file before a stream of it might be handed off to whatever content engine may be run. A bit trickier no doubt, and per the previous and following may not be necessary.

5) Do something like content rewriting done by the Apache httpd mod_substitute and others. This could perhaps depend on some post-processing support. This could possibly be an extension point for the plugin system. Rules or configuration files could be located in a central location as well as be able to be placed in the content hierarchy to allow different overrides depending on content sections/locations.

I think 1, 2, 3, and 5 would be really nice, and would probably work into the current design fairly easily along with some of the future direction related to plugins. I also think allowing meta-data be separate from the content allows the file types to be more pure for editor support less needing embedded syntax capabilities.

Thanks

Wade


You received this message because you are subscribed to a topic in the Google Groups "JBake Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jbake-user/64MiZRTl_3I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jbake-user+unsubscribe@googlegroups.com.
Message has been deleted

Jonathan Bullock

unread,
May 23, 2017, 6:18:15 PM5/23/17
to Wade Chandler, JBake Users
Hi Wade,

1. I like this idea, it would enable Markdown and raw HTML content files to be independent of JBake like AsciiDoc files can be. Could you raise an issue for this on GitHub?

2. I may have mis-understood what you mean but this is possible right now via jbake.properties you can define any global meta-data in here and it's exposed to each of the template engines, it can also be injected/exported into Asciidoctor so the values are usable in AsciiDoc content as if they have been defined as attributes in the document.

3. I'm assuming you mean the whole content file would be made up of template engine syntax. This was explored in a pull request but never fully implemented. But I'm unsure how this would be beneficial, when the content file is processed by the relevant template engine what data model/context would be exposed for use during the conversion process from template syntax to HTML? Perhaps we can explore an example scenario/file to flesh out how this would work?

4. This would solve a number of issues. Just to confirm we're on the same page I'm envisaging the template engine runs first and processes any template syntax then the content is passed to the relevant markup engine for processing. My initial thought was to use Groovy here as it provides much more than other template engines.

5. Manik (thanks for this by the way) has implemented a post processor that alters img src values to be relative as he's mentioned. It's a starting point and hopefully it can be expanded upon by the plugin/extension system eventually. This is scheduled to be included in 2.6.0 too.

Regards,
Jon

Wade Chandler

unread,
May 25, 2017, 8:21:19 AM5/25/17
to Jonathan Bullock, JBake Users

On May 23, 2017 6:18 PM, "Jonathan Bullock" <jonbu...@gmail.com> wrote:
Hi Wade,

1. I like this idea, it would enable Markdown and raw HTML content files to be independent of JBake like AsciiDoc files can be. Could you raise an issue for this on GitHub?

Will do.


2. I may have mis-understood what you mean but this is possible right now via jbake.properties you can define any global meta-data in here and it's exposed to each of the template engines, it can also be injected/exported into Asciidoctor so the values are usable in AsciiDoc content as if they have been defined as attributes in the document.

As a point it was really to go along with the rest of the items to follow, but I didn't realize AsciiDoc was so powerful in this context already. But too, I am not sure how many conventional variables/properties JBake defines without editing jbake.properties, and so was also suggesting more convention over configuration as defaults for most things generally needed to bake a site. This may already be the case as well, in which case it already supports these ideas. It would be nice if all config supported YAML, JSON, and properties files though; myself preferring YAML :-)


3. I'm assuming you mean the whole content file would be made up of template engine syntax. This was explored in a pull request but never fully implemented. But I'm unsure how this would be beneficial, when the content file is processed by the relevant template engine what data model/context would be exposed for use during the conversion process from template syntax to HTML?

Yes, the content file is made up of template syntax. I am thinking the output could be either rendered to a supported content type for the current rendering engine, such as MD, HTML, or AsciiDoc, and then go through the pipeline, or it could come out in its final state to allow all forms of end result material to be created, and not just HTML. But, the template engine would perform the rendering in either case. The page meta-data could detail stages needed perhaps allowing various points of entry or jumping off. i.e. the meta-data would have a property telling JBake to either

1) once processed the result is final, and one must produce the end result MIME type or the HTML to be merged into the template; a property in the meta-data could detail whether this content is to be merged with a template, so if not, then the result is standalone content of some type, but if so, then take the output as is to the template as happens now after JBake has already processed a content file

2) once processed the result is intermediary, so assume the result is content as defined today, and thus run that output through the conversion pipeline as if it were originally its output MIME type, and so a content  file might mostly look like Markdown with some replacements in it or iterative logic for lists or structures from meta-data as that is a fairly trivial format, and then let JBake and MD engine do the HTML magic as today

3) once processed, consider final, to be merged into the template, but be sure and run post-processing, and this would be the default since we are also discussing some default notion of a language inside content in an item below  (Groovy perhaps)

In all cases the content template engine would have access to properties and meta-data in the context like you describe AsciiDoc having

Perhaps we can explore an example scenario/file to flesh out how this would work?

Definitely; we can kick up a branch.


4. This would solve a number of issues. Just to confirm we're on the same page I'm envisaging the template engine runs first and processes any template syntax then the content is passed to the relevant markup engine for processing. My initial thought was to use Groovy here as it provides much more than other template engines.

I think we are on the same page. I also think Groovy's template syntax would play nice with most content.


5. Manik (thanks for this by the way) has implemented a post processor that alters img src values to be relative as he's mentioned. It's a starting point and hopefully it can be expanded upon by the plugin/extension system eventually. This is scheduled to be included in 2.6.0 too.

Awesome!

Thanks much,

Wade

Jonathan Bullock

unread,
Jun 5, 2017, 5:39:03 PM6/5/17
to Wade Chandler, JBake Users
Hi Wade,

1. I noticed an e-mail about this so thanks.

2. The jbake.properties file provides 2 main features, allows you to override the default JBake configuration (defined in default.properties within JBake) values, you only need to define in your project jbake.properties what you need to change and it allows you to define additional global metadata values - you are limited by the format and that is something we can look to address. In 2.6.0 you'll also be able to control the config via system properties as well.

3. That would be good to explore this further so we can see how it would work in practice.

4. I'll log this down as an issue to be worked on.

Thanks,
Jon

Jérémie Bresson

unread,
Jul 31, 2017, 3:04:10 AM7/31/17
to JBake Users, dorin....@gmail.com

Nothing is online beside the code presented in this utility class: HtmlUtility#fixHtml(..) method line 22

=> https://github.com/jmini/htmltools-jbake/blob/master/src/main/java/com/bsiag/htmltools/jbake/HtmlUtility.java#L22


And the usage example in this repository: https://github.com/jmini/jbake-sample

Notice the modifications made to the templates (feed.gsp or index.gsp in commit b7aeb18)


---

 

I had a first look at the JBake code:

 

MarkupEngine line 130 [1] is in my opinion not the correct position to fix the HTML. The problem is not when the sources (markdown, asciidoctor or HTML) are read and converted to HTML, but when the content is written into its final destination.

 

With a “flat only” structure, you will have no problem at all. The problem starts to appear if you produce something like:

/feed.xml

/index.html

/blog/post1.html

/blog/img.png

 

With the sources:

src/main/jbake/content/blog/post1.md

src/main/jbake/templates/feed.gsp

src/main/jbake/templates/index.gsp

src/main/jbake/templates/post.gsp

 

When the content of "post1.md" is written to "/blog/post1.html", the paths to link, images and so on are correct. When the same content is written to "/index.html" or to "/feed.html", then the paths are broken.

 

My solution is to fix it in the groovy template. This is probably too late. I think that not every templating engine allows to call an arbitrary Method of a utility class on the classpath as it is possible with Groovy.

When JBake provide a list like "published_posts" in the model of a template, then each ${post.body} should be correct for this template (given the fact that at this point the output location is clear).

 

My guess is that all extractors implementing ModelExtractor<DocumentList> are concerned by this transformation. I just need to figure out how I modify how I modify the "body" attribute of each of the documents extracted by the query. I also need to be sure that this will not induce any side effect (I do not want to modify the document itself but just the copy of the body, given one specific extraction context). I also need to write tests for that.

 

I would be happy to know what you think.

 

[1] https://github.com/jbake-org/jbake/blob/master/src/main/java/org/jbake/parser/MarkupEngine.java#L130

To unsubscribe from this group and stop receiving emails from it, send an email to jbake-user+...@googlegroups.com.

Jonathan Bullock

unread,
Aug 13, 2017, 8:31:59 AM8/13/17
to Jérémie Bresson, JBake Users, Dorin Ionescu
Thanks for sharing your fix for this Jérémie. Since this thread started work has been done to try and improve this: https://github.com/jbake-org/jbake/pull/367 for the next release.

It's a start to improving the situation... and hopefully more work can be done in subsequent releases.

Thanks,
Jon

To unsubscribe from this group and stop receiving emails from it, send an email to jbake-user+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages