Search code examples
phplaravel-5slugalgolia

Handling a confusingly slug'd URL in Laravel/Algolia


I'm using the the excellent algolia/algoliasearch-laravel package with laravel 5.2.

One of my "products" I'm uploading to Algolia has a forward slash in the product name:

Teal Stag Cashmere Scarf/Stole by Johnstons of Elgin

This is changed into the following url using the cviebrock/eloquent-sluggable package as so:

/products/women/Cashmere%20Patterned%20Scarves/teal-stag-cashmere-scarf++stole-by-johnstons-of-elgin

Note the ++ between scarf and stole.

When this is uploaded to Algolia I get this:

objectID: 8122
name: "Teal Stag Cashmere Scarf/Stole by Johnstons of Elgin"
imgsrc: "Stag Teal Cashmere Stole (Small)_small.jpg"
rank: 0
url: "https://mywebsite.com/products/women/Cashmere Patterned Scarves/teal-stag-cashmere-scarfstole-by-johnstons-of-elgin"

See how that url in algolia isn't right? I've tried crowbaring in a ++ into the url but I'm kinda lost now on how to proceed.


Solution

  • After working through this the answer was simply that my origonal URLs are badly formed. I re-wrote the way the urls are generated using the str_slug function from Laravel 5.2 and all is well again:

     /**
     * Generate a URL friendly "slug" from a given string.
     *
     * @param  string  $title
     * @param  string  $separator
     * @return string
     */
    public static function slug($title, $separator = '-')
    {
        $title = static::ascii($title);
    
        // Convert all dashes/underscores into separator
        $flip = $separator == '-' ? '_' : '-';
    
        $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
    
        // Remove all characters that are not the separator, letters, numbers, or whitespace.
        $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', mb_strtolower($title));
    
        // Replace all separator characters and whitespace by a single separator
        $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
    
        return trim($title, $separator);
    }