Display image from a plugin (.rb / javascript file)

Hello,

In a .md file we can use the following format to display an image:

<img src={{ “images/joo.jpg” | relative_url }} />

But in a .rb file how to display an image which is in images folder ?
In my case this image is not found. Problem of path solved with relative_url in .md file

function _addMarkerToMap(leafletItem, map){
var m = leafletItem.value;

    if ('label' in m){
        var result = L.marker([m.latitude,m.longitude]).bindTooltip(m.label,{permanent:true}).addTo(map).openTooltip();
    } else {
        var result = L.marker([m.latitude, m.longitude]).addTo(map);
    }

    
    var potentialPopup = "";
    if('popupContent' in m){
            potentialPopup += m.popupContent;}
    if('href' in m){
        potentialPopup += '<a href="' + m.href + '">' + 
            '<img src="' + newWindowImgSrcBase64 + '"></img></a>';
    }
    
    if ('image' in m){
        potentialPopup += "<img src='" + m.img + "' />";       <<<< doesn't find the image !!!!
    }

    if(potentialPopup){
        result.bindPopup(potentialPopup).openPopup();
    }

    if(!('center' in tagInputArg)){
        // If the user didn't specify a center, infer from marker
        map.panTo(new L.LatLng(m.latitude, m.longitude));
    }
}

You asked “in a .rb file how to display an image”, but the code you show is Javascript? Assuming you meant Javascript, then you can use Liquid in a Javascript file by adding empty YAML front matter. For example (untested code):

File mycode.js:

---
---
var imagename="toy.jpg";
var imagepath = '{{ "/image" | relative_url }}/' + imagename;
console.log(imagepath);

The generate script at _site/mycode.js should output /image/toy.jpg to the console.

1 Like

Agreed. This is confusing. Is it perhaps a plugin that includes JS code.

It is not clear whether that code is yours or from an external plugin.

Break the problem up into smaller pieces. The whole JS snippet is a lot to read and the only line that matter is the img tag one. So focus on getting that to work outside of that large function.

You can use the approach from the previous answer to add a liquid variable into the JS

You can also set a JS constant

---
---
<script>
const BASE_URL = '{{ site.baseurl }}';
</script>

Then use

var imgSrc = `${BASE_URL}${m.img}`

If your problem is how to write a plugin that uses the baseurl in your ruby code, have a look at the Jekyll plugin docs on the Jekyll website. A plugin gets passed the site object so you could get fields like baseurl off of that.

@chuckhoupt: The .rb file calls the .js file !

Yes, It’s not my code ! I forked it and want to modify it !!

How to add Liquid code in this code:

(() => {
// Specify configuration variables, setup any elements and styling
    var leafletCdn = "https://unpkg.com/leaflet@1.7.1/dist/";
    var esriLeafletCdn = "https://unpkg.com/esri-leaflet/dist/";
...
if ('image' in m){
        potentialPopup += "<img src='" + m.img + "' />";       <<<< doesn't find the image !!!!
    }

If I add an empty YAML then my map is not displayed !

Does the Ruby file copy and entire JS file to assets? Or does it insert the JS into a page?

Either way you can use the suggestions above.

If you set this then it will look for a possible JS variable. I used the || part to allow it to be undefined and use empty string.

if ('image' in m){
        potentialPopup += "<img src='" + (BASEURL || '') + m.img + "' />";       
    }

Then in your layout or index.md you need to set this as I covered before.

<script>
const BASE_URL = '{{ site.baseurl }}';
</script>

Make sure that loads before your plugin script that will be something like

<script src="pluginmap.js"></script>
1 Like

This .rb code calls the js:

require ‘securerandom’
require ‘json’
module Jekyll
class LeafletMap < Liquid::Block

def initialize(tag_name, input, tokens)
    super
    if input.empty?
        @input = {}
    else
        @input = input
    end
    
    if !(input.is_a? String)
        raise "leaflet-map input argument must be a String"
    end

end


def render(context)
    text = super        
    if !(text.is_a? String)
        raise "leaflet-map content between the tag blocks must a String"
    end
    leaflet_providers_js_content = File.read(
        File.expand_path("./leaflet-providers.js", File.dirname(__FILE__)))

    map_js = File.read(
        File.expand_path("./leaflet-map.js", File.dirname(__FILE__)))
    map_html = File.read(
        File.expand_path("./leaflet-map.html", File.dirname(__FILE__)))

    @input = parse_liquid_output_in(@input, context)
    id = SecureRandom.hex
    map_js = map_js % {id: id,
                       leaflet_providers_js_content: leaflet_providers_js_content,
                       tag_input_arg_json: @input,
                       inside_block_leaflet_items: text}
    map_html = map_html % {id: id,
                           leaflet_map_js_content: map_js}

    map_html
end

end

end

Liquid::Template.register_tag(‘leaflet_map’, Jekyll::LeafletMap)

The .md module is:

---
permalink: /meyrin/
layout: splash
title: Lieux à Meyrin
classes: wide
---
<script>
const BASE_URL = '{{ site.baseurl }}';
</script>
...

Is it the answer to your question ?

That doesn't work !
if ('image' in m){
            var toto = '${BASE_URL}${m.img}'
            potentialPopup += "<img src='" + toto + "' />";
        }

That also doesn’t work !
BASE_URL defined in the meyrin.md file

Note: after debugging I note that BASE_URL is incomplete:

  • Locally, localhost:4000 is missing before BASE_URL
  • The string ‘{BASE_URL}{m.img}’ is not interpreted

[2020-11-27 15:43:40] ERROR `/faune_flore_meyrin/meyrin/{BASE_URL}{m.img}’ not found.

I did a typo error …
The solution is:
set BASE_URL in the .md file

<script>
const BASE_URL = '{{ site.baseurl }}';
</script>

next in the js file:

if ('image' in m){
        potentialPopup += "<img src='" + (BASEURL || '') + m.image + "' />";       
    }

Thank you so much !

1 Like

You’re welcome.

Please use triple backticks for you code in the forum. It makes it more readable

```
var x;
console.log(y)
```

Which gives

var x;
console.log(y)

It sounds like it is working then.

Please mark of my comments as Solution then this will be marked as solved.

Yes it works !
But I don’t know how to mark “solved” :confused:

I can’t see what you see as the poster but try the 3 dot menu under my relevant comment and see if it gives you an option

I see:

  • like this post
  • share this post
  • send notification
  • bookmark

Maybe on the question itself at the top you choose an answer

How do you proceed yourself ?!
we aren’t in Stack Overflow where we can choose an answer …
I like your answer but …

I’ve never posted a question so I don’t know how. But I see other questions here have answers marked as solved.

See for example Filter product collection loop with featured products and custom frontmatter

I asked the question …
Don’t worry, I will not abandon :grinning:

1 Like

@MichaelCurrin

I am sorry but the administrator is not able to help me.