Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

URL slug

Hello,

How to make slug in routes (links) .. I have to convert " " in "-" and characters like "ä" in "a" , "ë" in "e" ...

Foe example:

I have in cars database table car_name "Aston Martin" .. when I want to open that car, url should bee api.car.dev/cars/aston-martin

For now i have cars id in my url but i want to change it to names.

// http://api.cars.dev/cars/{cars_id}
$router->addGet("/cars/{cars_id:[0-9]+}", array(
    'module' => 'cars',
    'controller' => 'cars',
    'action' => 'car'
));

Hello, phalcon does not have such built in function. Here is a function i use:

    // Slugalize
    public static function slugalize($text)
    {
        // Latinize
        $cyrillic = array('А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ь', 'Ю', 'Я', 'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ь', 'ю', 'я');
        $latin    = array('A', 'B', 'V', 'G', 'D', 'E', 'J', 'Z', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', 'C', 'Ch', 'Sh', 'Sht', 'Y', 'I', 'U', 'Ja', 'a', 'b', 'v', 'g', 'd', 'e', 'j', 'z', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sh', 'sht', 'y', 'i', 'u', 'ja');                
        $latinized = str_replace($cyrillic, $latin, $text);

        // Unaccent
        $unaccent = strtr($latinized, 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', 'AAAAAAACEEEEIIIIDNOOOOOOUUUUYTsaaaaaaaceeeeiiiienoooooouuuuyty');                

        // Urlize
        $urlized = trim(strtolower(preg_replace('/[^A-Z^a-z^0-9^\/]+/', '-', preg_replace('/([a-z\d])([A-Z])/','\1-\2', preg_replace('/([A-Z]+)([A-Z][a-z])/','\1-\2', preg_replace('/::/', '/',$unaccent))))));

        return str_replace(array('_','/'), array('-',''), $urlized);        
    }

Its mostly for cyrilic alphabet, but should do the job for you as well, or you can modify it to fit your needs.

edited Dec '15

But what problem you have ? Its only link. You can just put it like:

$router->addGet("/cars/{cars_brand}-{cars_model}", array(
    'module' => 'cars',
    'controller' => 'cars',
    'action' => 'car'
));

Then in controller:

$name="$cars_brand $cars_model";


8.6k

But what problem you have ? Its only link. You can just put it like:

```php $router->addGet("/cars/{carsbrand}-{carsmodel}", array( 'module' => 'cars', 'controller' => 'cars', 'action' => 'car' )); ```

Then in controller:

```php $name="$carsbrand $carsmodel"; ```

Problem is when i have cars_brand like "Aston Martin" .. my link must looks like: api.cars.dev/cars/Aston-Martin

Also, Fiat "Stilö" .. my link must looks like: api.cars.dev/cars/Fiat/Stilo <--- (So ö is replaced with o)

So let it look like this, i give you example above. Router and url have nothing to do with content in database.



14.3k
Accepted
answer

i use this in my ControllerBase :

 public function URLGenerator($str)
    {
        setlocale(LC_ALL, 'en_US.UTF8');
        $clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
        $clean = preg_replace("/[^a-zA-Z0-9\/_| -]/", '', $clean);
        $clean = strtolower(trim($clean, '-'));
        $clean = preg_replace("/[\/_| -]+/", '-', $clean);
        return $clean;
    }