Using Replace on a Resource?

I would like to use string replace to process a text resource (an HTML file).

I use resources.ExecuteAsTemplate already - but there are other changes I’d like to make to change some of the strings.

Basically, I want a version of replace that works on resources - just like ExecuteAsTemplate does.

Ideally, I could make a pipeline that gets a resource, does a string replace, and then does an execute as template. Something like (I know this doesn’t work):

.Page.Resources.GetMatch "foo.js" | replace "s1" "s2" | ExecuteAsTemplate "new.js" $context

Is there a way to do this? Replace only seems to work on strings (not the contents of a resource).

Thanks!

Once you .Page.Resources.Get something, it should have a .Content that you can act on. So, with less pipes and untested:

{{ $myvar := page.Resources.GetMatch "foo.js" }}
{{ $myvarContent := $myvar.Content }}
{{ $output := $myvarContent | replace "s1" "s2" }}
{{ $output | ExecuteAsTemplate "new.js" }}

Something along the lines of this.

1 Like

.Content is a string here, so we might need to add a resources.FromString

still untested:

{{ $myvar := page.Resources.GetMatch "foo.js" }}
{{ $myvarContent := $myvar.Content }}
{{ $output := $myvarContent | replace "s1" "s2" }}
{{ $myResource := $output | resources.FromString "some-path" }}
{{ $myResource | ExecuteAsTemplate "new.js" }}
1 Like

Thank you @davidsneighbour and @irkode !

It works like a charm - and once I am in string land, I can do all kinds of other things!

Three small semi-related questions…

  1. ExecuteAsTemplate puts the result in a root-relative directory. Is there a way to put it in the same directory as the page bundle is going into (the html for the page bundle)?
  2. It seems like the temp file (“some-path” in the example) doesn’t actually become a file in the result. (this is good - I don’t want the temp file). Can I re-use the temp file name?
  3. It seems that the original file (from a page bundle) is copied into the result (in the example, foo.js would be in the built result alongside new.js). Is there a way to prevent this?

Thank you!

  1. {{ with resources.ExecuteAsTemplate (add page.Path "/target.json") page . }}
    this will use the same logical path as the current page

  2. no publish is expected. You will have to explicitly publish it in case you need that. see docs

    The resources.FromString function returns a resource created from a string, caching the result using the target path as its cache key.

    I did a quick test, and in that use case it works. Guess the caching will only affect publishing the resource twice blocking a duplicate render to the same path. I expect than the first publish wins. → So I would guess you can.

  3. use build options
    frontmatter of the page bundle index page

    [build]
       publishResources = false
    

Hint: if you use 3) to suppress the automatic publishing of resources, you may use the same name for your target file in 1) without a duplicatePathWarning.

if you just use the same name without setting 3) the resource will be published twice to the same path and the last one wins. (in your use case that may work, but in others won’t)

guess so you could name all TARGETPATH arguments the same

1 Like

Thank you! You not only answered my question, but you also answered my “next” question before I even had a chance to ask it!

Thank you! You’ve made a lot of things a lot easier for me…

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.