SSbits - Home page
Site by Carbon Crayon
Submit a Post >

Tutorials - Big bits of code to help you do more

Autofill MetaDescription and MetaKeywords on page save

Most of my customers don't want to add meta info manually, so I add an onBeforeWrite() function to update the Meta Description field and count the keyword density of the content with a separate function and add these keywords to the Meta Keywords fields when a page is saved.

In my humble SEO opinion every page needs an unique Meta Description. Keywords seems to be less important for search engines, but why not add them automatically anyway! The function counts how many times each word exist in the Content, order the words by occurrence and glues the words to a comma separated string. In this function only words with more then 4 characters are counted, but you can adjust that if you like.

To do this, add an onBeforeWrite() function in your Page class (mysite/Page.php).
This will fill in the Meta Description with the Content (The Meta Description Field is limited to 255 characters).

public function onBeforeWrite () {
        parent::onBeforeWrite ();
        if($this->ID){
            // fill in MetaDescription without any tags
            if($this->record['Content']){
                $this->record['MetaDescription'] = strip_tags($this->record['Content']);
            }
            // fill in MetaKeywords
            if($this->record['Content']){
                $this->record['MetaKeywords'] = self::calculateKeywords($this->record['Content'], 4, 15);
            }
        }
    }

For the keywords we need two extra functions to calculate the keyword density (borrowed from Gabriel Comarita):
Add the following functions to your Page class (mysite/Page.php)

/**
     * Extract Keywords
     * Returns a lowercase string with keywords ordered by occurance in content seperated with comma's
     * @var $string
     * @var $min_word_char
     * @var $keyword_amount
     * @var $exclude_words
     */
    private function calculateKeywords($string = '', $min_word_char = 4, $keyword_amount = 15,  $exclude_words = '' ) {
        
        $keystring = '';
        $exclude_words = explode(", ", $exclude_words);
        // get rid off the htmltags
        $string = strip_tags($string);
        
        // count all words
        $initial_words_array  =  str_word_count($string, 1);
        $total_words = sizeof($initial_words_array);
        
        $new_string = $string;
        
        // strip excluded words
        foreach($exclude_words as $filter_word)    {
            $new_string = preg_replace("/\b".$filter_word."\b/i", "", $new_string); 
        }
        
        // calculate words again without the excluded words
        $words_array = str_word_count($new_string, 1);
        $words_array = array_filter($words_array, create_function('$var', 'return (strlen($var) >= '.$min_word_char.');'));
        
        $popularity = array();
        $unique_words_array = array_unique($words_array);
        
        // create density array
        foreach($unique_words_array as  $key => $word)    {
            preg_match_all('/\b'.$word.'\b/i', $string, $out);
            $count = count($out[0]);    
            $popularity[$key]['count'] = $count;
            $popularity[$key]['word'] = $word;
            
        }
        
        usort($popularity, array($this,'cmp'));
        
        // sort array form higher to lower
        krsort($popularity);
        
        // create keyword array with only words
        $keywords = array();
        foreach($popularity as $value){
                        $keywords[] = $value['word']; 
                    }
                    
        // glue keywords to string seperated by comma, maximum 15 words
        $keystring =  strtolower(implode(', ', array_slice($keywords, 0, $keyword_amount)));
        
        // return the keywords
        return $keystring;
    }
    
    /**
     * Sort array by count value
     */
    private static function cmp($a, $b) {
        return ($a['count'] > $b['count']) ? +1 : -1;
    }

Now every time a Page (or an extended page type like the Blog Page) is saved, it updates the Meta Description or Meta Keywords fields.

Since the CMS forms are posted with Ajax, you need to refresh the page to see the results immediately. You can automate this by adding a onAfterWrite function to you Page class:

public function onAfterWrite(){
        parent::onAfterWrite ();
        LeftAndMain::ForceReload ();
  }

You could extend this by adding a check-box field, so you can choose if you want to update the meta fields or not each time you save a page.

With this idea I made a separate Decorator extension with its own _config.php file for the configuration options.

The code to update the meta fields is slightly different then this tutorial and I added some options to suppress the confirm dialog each time you change the page title and to hide some of the meta fields. Put the files in the Metamanager package to you siteroot so you get siteroot/metamanager/ . Change the settings in the config file to suit you needs and voila Automated meta info!

Martijn van Nieuwenhoven avatar

Martijn van Nieuwenhoven

Martijn van Nieuwenhoven is a freelance Silverstripe developer based in the Netherlands and runs the largest Dutch Jobboard for Media, Marcom and Graphic related jobs.

No one has commented on this page yet.

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image Ty Barho
6 article image Martijn van Nieuwenhoven
7 article image Darren-Lee
8 article image Roman Schmid
9 article image Matt Clegg
10 article image dalesaurus

View full leaderboard


Advertisement