Is it possible replaceRE function can include relURL?

I just want to make lazyload function work for my theme.

I use the following code to change content if the content has images

       {{ $img := findRE "src=\"(.+?png|jpg|jpeg|gif|bmp)\"" .Content }}
        {{ if gt (len $img) 1 }}
          
          {{ (.Content | replaceRE "src=\"(.+?png|jpg|jpeg|gif|bmp)\"" "src=\"/placeholder.svg\" data-src=\"$1\"") | safeHTML  }}
        {{ else }}
          {{ .Content }}
        {{ end }}          

This worked for my website. Because placeholder.svg is placed on the root directory.
But if the users of my theme use another directory, it will meet 404 error. So I want to use

     {{ (.Content | replaceRE "src=\"(.+?png|jpg|jpeg|gif|bmp)\"" "src=\"{{ "/placeholder.svg" | relURL }}\" data-src=\"$1\"") | safeHTML  }}

But this is not working.

Is there a way to do this? Thanks for reply.

The following is untested but it might work.

  • Try placing placeholder.svg under assets.
  • Then store it in a variable like {{ $placeholder := resources.Get "placeholder.svg" }}
  • Use it in your template like so: src=\"/$placeholder\"
  • And in your theme’s README instruct users that placeholder.svg needs to go under the root of /assets/
1 Like

I like @alexandros’s recommendation. To build off that, try doing it this way:

{{ $regex := "src=\".+(png|jpg|jpeg|gif|bmp)\"" }}
{{ $img := findRE $regex .Content }}

{{ if gt (len $img) 0 }}
  {{ $placeholder := resources.Get "placeholder.svg" }}
  {{ $replacement := print "src=\"" $placeholder.RelPermalink "\" data-src=\"$1\"" }}
  {{ .Content | replaceRE $regex $replacement | safeHTML }}
{{ else }}
  {{ .Content }}
{{ end }}  

A few notes:

  • Your original regex would only match images with the extension png, you just needed to move the parentheses over to fix this
  • You were checking if $img was greater than 1, but I think what you want is to check if it’s greater than 0
  • You no longer need to use relURL since you can grab the .RelPermalink of the resource
2 Likes

Thanks to @alexandros and @zwbetz. Your solution works like a charm.
I just use the following code:

        {{ $regex := "src=\"(.+?)\"" }}
        {{ $img := findRE $regex .Content }}

        {{ if gt (len $img) 0 }}
          {{ $placeholder := resources.Get "placeholder.svg" }}
          {{ $replacement := print "src=\"" $placeholder.RelPermalink "\" data-src=\"$1\"" }}
          {{ .Content | replaceRE $regex $replacement | safeHTML }}
        {{ else }}
          {{ .Content }}
        {{ end }}         

Because I found a old post has image src=“data:img…” if use png|jpg it will found from one image “src” to anther image with png or jpg file. So to be safer I just use "src=\"(.+?)\""

About {{ if gt (len $img) 1 }}, just think there is no need to lazy load with only one image.

But I used {{ if .Site.Params.lazyload }} to load javascript file already, and placeholder.svg size is only 2 kb. So perhaps it is better to set {{ if gt (len $img) 0 }} as @zwbetz code.

Thanks again.

Use "src=\"(.+?)\"" still has some problem. If the user post javascript code with <script src="blabla"> this will be another problem.

I can use findRE to get the whole img with <img .*?src=\"(.*?)\".*?>

But is it a way to just replaceRE the findRE match results?

Just use the following regex to make it better
{{ $regex := "(?i)src\\s*=\\s*\"([^\"]*(png|jpg|jpeg|gif|bmp|svg))\"" }}

case insensitive and discard img src:data mode(I think not too many people use that style)

2 Likes