Using replace() on result from portal:createContentUrl() does not work

Enonic version: 4.7.11
OS: Centos

I’m trying to make a content url and then replace the base url of it. This turns out to be problematic.
Using the following code:

<xsl:variable name="originalURL" as="xs:string" select="portal:createContentUrl(contentdata/article-simple/content/@key)"/>
<xsl:variable name="newBaseURL" as="xs:string" select="''"/>
<xsl:variable name="newURL" as="xs:string" select="replace($originalURL, '^https?://[^/]*', $newBaseURL)"/>
newURL:'<xsl:value-of select="$newURL"/>'
<xsl:variable name="simpleTest" as="xs:string" select="replace($originalURL, 'http', 'noe annet')"/>
Simple test: '<xsl:value-of select="$simpleTest"/>'
<xsl:variable name="stringTest" as="xs:string" select="'http://localhost:8080/admin/site/57/612097/slik-skriver-du-gode-produktbeskrivelser'"/>
<xsl:variable name="stringTestResult" as="xs:string" select="replace($stringTest, 'http', 'noe annet')"/>
String test: <xsl:value-of select="$stringTestResult"/>

…produces the following output:

Simple test: 'http://localhost:8080/admin/site/57/612097/slik-skriver-du-gode-produktbeskrivelser' 
String test: noe annet://localhost:8080/admin/site/57/612097/slik-skriver-du-gode-produktbeskrivelser

I would expect the output from the “simple test” statement to have changed ‘http’ to ‘noe annet’.
Why is this not happening here?

The “string test” output is there to demonstrate what I would expect it to do.

I don’t understand what is going on here. Is createContentUrl() not producing a proper string?

It certainly looks like a string, but replace() doesn’t seem to handle it like one.

Any help on this is appreciated.

Hi Viggo!

I might be wrong, but as far as I know all url-functions create placeholders which are post-processed after all rendering (in order to cache robustly). Thus, there is no url in your result, but a placeholder value - hence your regex will never match.

1 Like

Yes, what Thomas says is correct.

Can you use relative URLs?

Like jsi suggests, this could be a criterion for you to use relative URLs on your site, and prefix these URLs with the protocol and server address, but make sure to do this prefixing outside (separately) of the XPath function call that generates the URL, or else the whole logic will be replaced when the content URL is generated by the portal function.

Alternatively: Construct a content URL manually. There are two types of content URL formats:

  1. Traditional content URL, created manually from the XML data available beneath the element in the content data

You have to be very explicit in your XPath query when generating the path to the content location, as it’s important that it belongs to the correct site and probably a few other snags that must be taken care of. I’ve never done this myself, but it should work.

  1. Content without any home (or ignoring content home)… a permalink. This will always work, but is a bit ugly.

The nice thing about generating a permalink is that it redirects to a content URL if the content in fact already has a home on that site. Or at least, that’s my vague recollection of what it does… Try it, and see if it works for you.

Hi @bhj, @jsi and tsi

Sorry for my very late response, as I was away for two weeks.
Thanks for your input. I will try out these methods and see what works best.

Great! Let us know what you find.

Just a followup on what we ended up with here.
We are now using method 1 with method 2 as fallback when contentlocation is not available.
When using contentlocation we also have to check if the type is a menuitem or not. If not, the name should be added to the end of the url.

1 Like