Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Customising the CMS /

Allowing same URLSegment in different locales


Reply


6 Posts   2567 Views

Avatar
smares

Community Member, 25 Posts

16 December 2011 at 3:30am

Edited: 16/12/2011 3:31am

Hey guys, I am trying to make SilverStripe allow the same URLSegment across different locales. This works because I am using the language in the URL in the format domain.com/eng/contact/ and domain.com/fra/contact/.

I figured out that the "problem" is in SiteTree's onBeforeWrite() or more precisely validURLSegment(). What I did was to add the locale to the existingPage query. The final method looks like this: http://www.sspaste.com/paste/show/4ee9ea6f46b04 (lines 23-26 + line 31).

This alone didn't work and I found out that I also have to modify Translatable's augmentValidURLSegment() which now looks like this: http://www.sspaste.com/paste/show/4ee9eb02a6afe (lines 17-20 + line 24 the same way as validURLSegment()).

With these two changes, having same URLs across locales appeared to work, but it doesn't fully. In some cases, SilverStripe renames the page to contact-2 when publishing, but ONLY in the SiteTree_Live table and NOT in the SiteTree table. Also, calling domain.com/fra/contact works as expected so you don't have to call domain.com/fra/contact-2.
Another problem resulting from this is that SilverStripe messes up something when it comes to checking whether a page was published or not. Example:

  • 1. Set default locale to en_GB and build default DB
  • 2. Create page in en_GB and publish
  • 3. Create translation of page in de_DE and publish
  • 4. Switch back to en_GB and publish the page again
  • 5. Switch to de_DE --> the page appears as not published

The most weird thing is that if I simply uncomment the loop responsible for generating unique URLSegments in onBeforeWrite() so that validURLSegment() and augmentValidURLSegment() are not being called, the problem above cannot be reproduced, but as far as I understand those functions, they only return true or false if a page with that name already exists, so they're not responsible for generating new names themselves.

What am I doing wrong?

Avatar
smares

Community Member, 25 Posts

16 December 2011 at 11:22pm

The problems seems to occur in onBeforeWrite() already and not in augmentValidURLSegment(). In step 4 described above, the onBeforeWrite() method is called 5 times. The first 3 times, validURLSegment() says that the segment was not used, the 4th time it says it exists and onBeforeWrite() appends -2.

Avatar
smares

Community Member, 25 Posts

17 December 2011 at 1:38am

Continued investigating and told validURLSegment to dump the ID of the page. The first 3 times onBeforeWrite() is called $this->ID is the ID of the page I am actually saving and the 4th time when validURLSegment also returns false $this->ID is the ID of the German page and NOT of the en_GB page. Wondering what is calling onBeforeWrite() the 4th time.

Avatar
smares

Community Member, 25 Posts

24 January 2012 at 12:02am

Number one, the changes I did to the files are way to exaggerated - it's enough to simply comment out the disable_locale_filter() in Translatable's augmentValidURLSegment.

Number two, the problem is caused when SilverStripe is "touching" the translations in Translatable->onBeforeWrite().

Avatar
smares

Community Member, 25 Posts

24 January 2012 at 3:48am

OK, so for this whole mess to work the way I want to, I only have to comment the disable_locale_filter() in Translatable' augmentValidURLSegment() and have SiteTree's onBeforeWrite() do the URL check if $this->Locale == Translatable::get_current_locale(). In this way I have unique URL segments per language (no /eng/home/ twice for example) and same URL segments across languages (/eng/home/, /deu/home/, etc.).

Avatar
suntrop

Community Member, 131 Posts

12 August 2012 at 3:14am

Thanks for sharing this!

Hope this won't end up in any problems :-)
Is there a cool way, I can overwrite/disable that within my config? Or do I have to edit the core file?