We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

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.

// https://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";


23.6k

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";

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.



37.4k
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;
    }