February 25, 201214 yr Anyone got a decent slug generator function hanging around that they'd like to share?
February 25, 201214 yr function titleToSlug($title, $maxLength) { $result = strtolower($title); $result = preg_replace("/[^a-z0-9\s-]/", "", $result); $result = trim(preg_replace("/[\s-]+/", " ", $result)); $result = trim(substr($result, 0, $maxLength)); $result = preg_replace("/\s/", "-", $result); return $result; } Have to do your own duplicate checking.
February 25, 201214 yr Edit - you might want to remove low-value stop words. I'll leave that fo you to cobble together too.
February 25, 201214 yr This is a custom slug function I've wrote for a clients website: function makeSlug($title) { $title = strtolower($title); $title = preg_replace("/[^a-z\s]/", "", $title); function removeCommonWords($input){ // INSERT MORE WORKS YOU WONT WANT IN YOUR SLUG HERE $commonWords = array('a','and','at','for','off','in','the','up','to','off','deal','cheap','half','price','buy','get','london'); return preg_replace('/\b('.implode('|',$commonWords).')\b/','',$input); } $title = removeCommonWords($title); function removeDouble($title) { $str = $title; $word_array = preg_split('/[\s?:;,.]+/', $str, -1, PREG_SPLIT_NO_EMPTY); $unique_word_array = array_unique($word_array); $unique_str = implode(' ',$unique_word_array); return $unique_str; } $title = removeDouble($title); $title = preg_replace('/\s+/', '-', $title); return $title; } makeSlug($textTOslug); Hope this helps. Example: CLICK ME Edited February 25, 201214 yr by alecish2
February 25, 201214 yr Author I personally usually store these in a database, as opposed to generating them on the fly. Codeigniter also has a a function titled "url_title" located at /system/helpers/url_helper.php that you could borrow. I'm sure other frameworks will have something similar. I intend to store the slug in the database, but i'd need to generate it first. Also i'm using CI, but just looking at that. Seems to do the job properly, i'll most likely need to extend it abit to consider duplicates and what not though. Thanks everyone else. Edited February 25, 201214 yr by Samus
February 26, 201214 yr Author That's insanely easy using codeigniter then - good choice on the framework (bias) You can make use of validation callbacks - no need to extend anything Remeber with codeigniter you should try to keep things as DRY as possible when writing code. So in your controller add a validation rule as normal (or add the validation rules in seperate config file to be even neater) : $this->form_validation->set_rules('slug', 'Slug', 'callback_slug_exists'); Youd' then add a function called "slug_exists" that would return either true or false - this result would come from a call you posts/blog/whatever model. All done in a couple of lines of code without extending anything. Also, but extending, I hope you don;t mean extending core helpers/libraries? If that's the case, you really shouldn;t be doing that as everything will break when you update CI Also, you could extend the core validation library (notice, extend, not edit directly) and use the MY_Validation approach. I personally don;t think that;s as neat though - but it's a similar idea to be honest. That's a good approach. How would I deal with multiple slugs that are exactly common? This is how I pictured the flow in my head. Make a callback validation rule which calls a method from a model. The model method returns either true or false if the slug exists. If returns true, generate slug and store in DB. If returns false, generate slug, add some type of increment to the slug. e.g 'this-is-a-slug-I' and insert. But then let's say I go for this approach and it works fine. I now have 'this-is-a-slug' & 'this-is-a-slug-I' how would I go about checking if 'this-is-a-slug-I' exists to increment again? For some reason this approach doesn't seem as effecient? Would you perhaps have another solution for dealing with multiple common slugs? Actually how would using a validation callback even work in this situation? The slug isn't apart of the input fields in my form, it's generated once my form passes validation and inserted into the db. Something like this.. if (!$this->form_validation->run('testimonial') == FALSE) : $insert = array( 'content' => $this->input->post('content'), 'title' => $this->input->post('title'), 'slug' => $this->_slug_gen($this->input->post('title')), 'user' => $this->session->userdata('user_id') ); $this->endaproblem->add('testimonials', $insert); Edited February 26, 201214 yr by Samus
February 26, 201214 yr Author BTW, you shouldn;t technically be calling a private function directly from a controller :| Could you elaborate on this? I always assumed private methods could only be accessed by the class that has declared them?
February 26, 201214 yr Author That's right If you;ve defined the method as private, then calling it outside your model shouldn't work. I assume the above code is from your controller as your running validation rules...which leads me to believe the method isn;t set as private. IIRC codeigniter blackloists private funtions from being called via the url too. Sorry the private function is in my controller, it calls a method from my model. But I still don't see how your callback method would work, even if I did generate the slug before inserting it. Because doesn't the validation library only run on form submit? That would be before the string being converted into a slug is even POSTed. So I wouldn't even be able to make use the callback as there will be no value for it. Another way I was thinking, was if I generated the slug before it was even submitted, then i'd be able to put the value in a hidden input field and it'll come along in the POST. I know wordpress does this somehow, maybe through ajax or something. The idea just sounds abit overkill though. But thanks for your help this night/morning, got me thinking alot.
Create an account or sign in to comment