function amt_add_og_xml_namespace($content)
{
    $options = amt_get_options();
    if ($options['og_add_xml_namespaces'] == '1') {
        //return ' xmlns:og="http://ogp.me/ns#" ' . $content;
        return ' xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="https://www.facebook.com/2008/fbml" ' . $content;
    }
    return $content;
}
function amt_user_extra_fields_save($user_id)
{
    /* Verify the nonce before proceeding. */
    // Verify this came from the our screen and with proper authorization,
    // because save_post can be triggered at other times
    if (!isset($_POST['amt_noncename']) || !wp_verify_nonce($_POST['amt_noncename'], plugin_basename(AMT_PLUGIN_FILE))) {
        return;
    }
    // Get the Metadata metabox permissions (filtered)
    $metabox_permissions = amt_get_metadata_metabox_permissions();
    // Global Metadata metabox permission check (can be user customized via filter).
    if (!current_user_can($metabox_permissions['global_metabox_capability'])) {
        return;
    }
    // Get the Add-Meta-Tags options.
    $options = amt_get_options();
    // Check if the current user has permission to edit the post.
    if (!current_user_can('edit_published_posts')) {
        return;
    }
    // OK, we're authenticated: we need to find and save the data
    //
    // Sanitize user input
    //
    // Full metatags - We allow only <meta> elements.
    if (isset($_POST['amt_custom_full_metatags'])) {
        $full_metatags_value = esc_textarea(wp_kses(stripslashes($_POST['amt_custom_full_metatags']), amt_get_allowed_html_kses()));
    }
    // Image URL
    if (isset($_POST['amt_custom_image_url'])) {
        $image_url_value = amt_esc_id_or_url_notation(stripslashes($_POST['amt_custom_image_url']));
    }
    // If a value has not been entered we try to delete existing data from the database
    // If the user has entered data, store it in the database.
    // Add-Meta-Tags custom field names
    $amt_full_metatags_field_name = '_amt_user_full_metatags';
    $amt_image_url_field_name = '_amt_user_image_url';
    // As an extra security measure, here we also check the user-defined per box
    // permissions before we save any data in the database.
    // per user profile full meta tags
    if ($options['metabox_user_enable_full_metatags'] == '1' && current_user_can($metabox_permissions['user_full_metatags_box_capability'])) {
        if (empty($full_metatags_value)) {
            delete_user_meta($user_id, $amt_full_metatags_field_name);
        } else {
            update_user_meta($user_id, $amt_full_metatags_field_name, $full_metatags_value);
        }
    }
    // Image URL
    if ($options['metabox_user_enable_image_url'] == '1' && current_user_can($metabox_permissions['user_image_url_box_capability'])) {
        if (empty($image_url_value)) {
            delete_user_meta($user_id, $amt_image_url_field_name);
        } else {
            update_user_meta($user_id, $amt_image_url_field_name, $image_url_value);
        }
    }
}
Exemple #3
0
function amt_add_schemaorg_metadata_comment_filter($comment_text)
{
    global $post, $comment;
    $options = amt_get_options();
    if ($options["omit_vendor_html_comments"] == "0") {
        $metadata_arr[] = '<!-- BEGIN Metadata added by the Add-Meta-Tags WordPress plugin -->';
    }
    $metadata_arr[] = '<!-- Scope BEGIN: UserComments -->';
    $metadata_arr[] = '<div itemprop="comment" itemscope itemtype="http://schema.org/UserComments">';
    // Comment Author
    $metadata_arr[] = '<!-- Scope BEGIN: Person -->';
    $metadata_arr[] = '<span itemprop="creator" itemscope itemtype="http://schema.org/Person"' . amt_get_schemaorg_itemref('person_commenter') . '>';
    // name
    $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr($comment->comment_author) . '" />';
    // url
    if (!empty($comment->comment_author_url)) {
        // $metadata_arr[] = '<meta itemprop="url" content="' . esc_url( $comment->comment_author_url ) . '" />';
    }
    // gravatar
    if (!empty($comment->comment_author_email)) {
        // Contruct gravatar link
        $gravatar_url = "http://www.gravatar.com/avatar/" . md5($comment->comment_author_email) . "?s=" . 44;
        $metadata_arr[] = '<meta itemprop="image" content="' . esc_url_raw($gravatar_url) . '" />';
    }
    // END
    $metadata_arr[] = '</span> <!-- Scope END: Person -->';
    $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(get_permalink($post->ID) . '#comment-' . get_comment_ID()) . '" />';
    $metadata_arr[] = '<meta itemprop="commentTime" content="' . esc_attr(get_comment_time('c')) . '" />';
    $metadata_arr[] = '<meta itemprop="replyToUrl" content="' . get_permalink($post->ID) . '?replytocom=' . $comment->comment_ID . '#respond' . '" />';
    $metadata_arr[] = '<div itemprop="commentText">';
    $metadata_arr[] = $comment_text;
    $metadata_arr[] = '</div> <!-- itemprop.commentText -->';
    $metadata_arr[] = '</div> <!-- Scope END: UserComments -->';
    if ($options["omit_vendor_html_comments"] == "0") {
        $metadata_arr[] = '<!-- END Metadata added by the Add-Meta-Tags WordPress plugin -->';
    }
    // Allow filtering of the generated metadata
    $metadata_arr = apply_filters('amt_schemaorg_comments_extra', $metadata_arr, $post, $comment);
    return PHP_EOL . implode(PHP_EOL, $metadata_arr) . PHP_EOL . PHP_EOL;
    //return implode( '', $metadata_arr );
}
Exemple #4
0
 /**
  * Export settings and data to standard output.
  * 
  * ## OPTIONS
  * 
  * <what>
  * : The type of data to be exported. Supported: settings|postdata|userdata|termdata
  * 
  * ## EXAMPLES
  * 
  *     wp amt export settings > amt-settings.json
  *     wp amt export postdata > amt-postdata.json
  *     wp amt export userdata > amt-userdata.json
  *     wp amt export termdata > amt-termdata.json
  *
  * @synopsis <settings|postdata|userdata|termdata>
  */
 function export($args, $assoc_args)
 {
     list($what) = $args;
     if (!in_array($what, array('settings', 'postdata', 'userdata', 'termdata'))) {
         WP_CLI::error('Invalid argument: ' . $what . ' (valid: settings|postdata|userdata|termdata)');
     }
     $output = array();
     // Export AMT settings
     if ($what == 'settings') {
         $opts = amt_get_options();
         // Every time Add-Meta-Tags is run it checks and upgrades its settings.
         // Here we perform a check whether the returned settings are the defaults.
         //$default_options = amt_get_default_options();
         //var_dump(array_diff($opts, $default_options));
         //if ( empty( array_diff($opts, $default_options) ) ) {
         //    WP_CLI::error( 'No custom settings detected.' );
         //}
         if (empty($opts)) {
             WP_CLI::error('Could not retrieve Add-Meta-Tags options.');
         }
         $output = $opts;
     } elseif ($what == 'postdata') {
         $qr_args = array('numberposts' => -1, 'post_type' => 'any', 'post_status' => 'any', 'orderby' => 'id', 'order' => 'ASC', 'suppress_filters' => true);
         $posts_arr = get_posts($qr_args);
         $amt_post_fields = amt_get_post_custom_field_names();
         foreach ($posts_arr as $post) {
             foreach ($amt_post_fields as $amt_post_field) {
                 $amt_post_field_value = get_post_meta($post->ID, $amt_post_field, true);
                 //var_dump($amt_field_value);
                 if (!empty($amt_post_field_value)) {
                     // Export format: <post_id>;<amt_post_field>;<serialized_value>
                     //echo json_encode( sprintf( '%s;%s;%s', $post->ID, $amt_field, $amt_field_value ) );
                     $output[] = array($post->ID, $amt_post_field, $amt_post_field_value);
                 }
             }
         }
     } elseif ($what == 'userdata') {
         $qr_args = array('orderby' => 'login', 'order' => 'ASC', 'fields' => 'all');
         $users_arr = get_users($qr_args);
         $amt_user_fields = amt_get_user_custom_field_names();
         foreach ($users_arr as $user) {
             foreach ($amt_user_fields as $amt_user_field) {
                 $amt_user_field_value = get_user_meta($user->ID, $amt_user_field, true);
                 if (!empty($amt_user_field_value)) {
                     // Export format: <user_id>;<amt_user_field>;<serialized_value>
                     //echo json_encode( sprintf( '%s;%s;%s', $post->ID, $amt_field, $amt_field_value ) );
                     $output[] = array($user->ID, $amt_user_field, $amt_user_field_value);
                 }
             }
         }
     } elseif ($what == 'termdata') {
         // Get taxonomies
         // Get the custom taxonomy names.
         // Arguments in order to retrieve all public custom taxonomies
         $tax_args = array('public' => true, '_builtin' => true);
         $tax_output = 'names';
         // names or objects
         $tax_operator = 'and';
         // 'and' or 'or'
         $taxonomies = get_taxonomies($tax_args, $tax_output, $tax_operator);
         // Get terms
         $qr_args = array('orderby' => 'id', 'order' => 'ASC', 'fields' => 'all');
         $terms_arr = get_terms($taxonomies, $qr_args);
         // Iterate over our fields and export
         $amt_term_fields = amt_get_term_custom_field_names();
         foreach ($terms_arr as $term) {
             foreach ($amt_term_fields as $amt_term_field) {
                 $amt_term_field_value = get_term_meta($term->term_id, $amt_term_field, true);
                 if (!empty($amt_term_field_value)) {
                     // Export format: <term_id>;<amt_term_field>;<serialized_value>
                     //echo json_encode( sprintf( '%s;%s;%s', $term->term_id, $amt_field, $amt_field_value ) );
                     $output[] = array($term->term_id, $amt_term_field, $amt_term_field_value);
                 }
             }
         }
     }
     // Print output
     if (!empty($output)) {
         echo json_encode($output, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
     }
 }
Exemple #5
0
function amt_metadata_analysis($default_text, $metadata_block_head, $metadata_block_footer, $metadata_block_content_filter)
{
    // Analysis is appended only o content pages
    if (!is_singular()) {
        return $default_text;
    }
    // Check the filter based switch
    if (!apply_filters('amt_metadata_analysis_enable', true)) {
        return $default_text;
    }
    //
    // Collect data
    //
    $options = amt_get_options();
    $post = amt_get_queried_object();
    if (!isset($post->ID) || $post->ID <= 0) {
        return $default_text;
    }
    // Content and stats
    // Post content
    $post_content = strtolower(amt_get_clean_post_content($options, $post));
    $post_content_length = strlen($post_content);
    //var_dump($post_content);
    // Total words
    if (function_exists('wordstats_words')) {
        $post_word_count = wordstats_words($post_content);
        // provided by the word-statistics-plugin by FD
    } else {
        $post_word_count = str_word_count($post_content);
    }
    // Total sentences
    if (function_exists('wordstats_sentences')) {
        $post_sentence_count = wordstats_sentences($post_content);
        // provided by the word-statistics-plugin by FD
    } else {
        $post_sentence_count = preg_match_all('/[.!?\\r]/', $post_content, $dummy);
    }
    // Total syllables
    // TODO: Find better function
    $post_syllable_count = preg_match_all('/[aeiouy]/', $post_content, $dummy);
    // Titles
    // Original
    $post_title = strtolower(strip_tags(get_the_title($post->ID)));
    // Title HTML element
    if ($options['enable_advanced_title_management'] == '1') {
        // If Advanced Title management is enabled, use this directly:
        $post_title_html_element = strtolower(amt_get_title_for_title_element($options, $post));
    } else {
        if (version_compare(get_bloginfo('version'), '4.4', '>=')) {
            // Since WP 4.4
            // - https://make.wordpress.org/core/2015/10/20/document-title-in-4-4/
            //$post_title_html_element = strtolower( apply_filters('document_title_parts', array('title' => $post_title) ) );
            //$post_title_html_element = wp_get_document_title();
            $post_title_html_element = strtolower(get_wp_title_rss());
        } else {
            // Reverting back to the one argument version of the fitlering function.
            //$post_title_html_element = strtolower( apply_filters('wp_title', $post_title) );
            // Until testing is performed on old WP versions we just use post title
            $post_title_html_element = $post_title;
        }
    }
    //var_dump($post_title_html_element);
    // Title in metadata
    $post_title_metadata = strtolower(amt_get_title_for_metadata($options, $post));
    //var_dump($post_title_metadata);
    // URL
    $post_url = str_replace(get_bloginfo('url'), '', amt_get_permalink_for_multipage($post));
    //var_dump($post_url);
    // Description
    $description = '';
    if (array_key_exists('basic:description', $metadata_block_head)) {
        $description = strtolower(preg_replace('#^.*content="([^"]+)".*$#', '$1', $metadata_block_head['basic:description']));
    }
    //var_dump($description);
    // Keywords
    $keywords = array();
    if (array_key_exists('basic:keywords', $metadata_block_head)) {
        $keywords_content = strtolower(preg_replace('#^.*content="([^"]+)".*$#', '$1', $metadata_block_head['basic:keywords']));
        $keywords = explode(',', str_replace(', ', ',', $keywords_content));
    }
    //var_dump($keywords);
    // Keyword matching pattern
    //$keyword_matching_pattern = '#(?:%s)#';
    //$keyword_matching_pattern = '#(?:%s)[[:^alpha:]]#';
    //$keyword_matching_pattern = '#(?:%s)[[:^alpha:]]?#';
    $keyword_matching_pattern = '#(?:%s)(?:[[:^alpha:]]|$)#';
    $keyword_matching_pattern = apply_filters('amt_metadata_analysis_keyword_matching_pattern', $keyword_matching_pattern);
    // Whether to use topic keywords field or the keywords from the 'keywords' meta tag.
    $use_keywords = false;
    // First check for a field that contains topic keywords.
    $topic_keywords_field_name = apply_filters('amt_metadata_analysis_topic_keywords_field', 'topic_keywords');
    $topic_keywords_field_value = get_post_meta($post->ID, $topic_keywords_field_name, true);
    if (!empty($topic_keywords_field_value)) {
        $topic_keywords = explode(',', str_replace(', ', ',', $topic_keywords_field_value));
    } else {
        $topic_keywords = $keywords;
        $use_keywords = true;
        //var_dump($topic_keywords);
    }
    $BR = PHP_EOL;
    if ($options['review_mode_omit_notices'] == '0') {
        $output = $default_text . $BR . $BR;
        //$output .= $BR . '<span class="">Text analysis</span>' . $BR;
    } else {
        $output = '';
    }
    if ($options['review_mode_omit_notices'] == '0') {
        $output .= 'Metadata Overview' . $BR;
        $output .= '=================' . $BR;
        //$output .= 'This overview has been generated by the Add-Meta-Tags plugin for statistical and' . $BR;
        //$output .= 'informational purposes only. Please do not modify or base your work upon this report.' . $BR . $BR;
        $output .= 'NOTICE: Add-Meta-Tags does not provide SEO advice and does not rate your content.' . $BR;
        $output .= 'This <a target="_blank" href="http://www.codetrax.org/projects/wp-add-meta-tags/wiki/Metadata_Overview">overview</a> has been generated for statistical and informational purposes only.' . $BR . $BR;
        //$output .= '<a target="_blank" href="http://www.codetrax.org/projects/wp-add-meta-tags/wiki/FAQ#Is-Add-Meta-Tags-an-SEO-plugin">Read more</a> about the mentality upon which the development of this plugin has been based.' . $BR;
        //$output .= 'Please use this statistical information to identify keyword overstuffing' . $BR;
        //$output .= 'and stay away from following any patterns or being bound by the numbers.' . $BR . $BR;
    }
    if ($use_keywords) {
        $output .= sprintf('This overview has been based on post keywords, because the Custom Field \'<em>%s</em>\' could not be found.', $topic_keywords_field_name) . $BR;
    } else {
        $output .= sprintf('This overview has been based on <em>topic keywords</em> retrieved from the Custom Field \'<em>%s</em>\'.', $topic_keywords_field_name) . $BR;
    }
    if ($options['review_mode_omit_notices'] == '0') {
        $output .= 'Keyword Analysis' . $BR;
        $output .= '----------------' . $BR;
    } else {
        $output .= $BR;
    }
    $output .= '<table class="amt-ht-table">';
    $output .= '<tr> <th>Topic Keyword</th> <th>Content</th> <th>Description</th> <th>Keywords</th> <th>Post Title</th> <th>HTML title</th> <th>Metadata titles</th> <th>Post URL</th> </tr>';
    foreach ($topic_keywords as $topic_keyword) {
        $output .= sprintf('<tr> <td>%s</td>', $topic_keyword);
        $is_into = array();
        // Check content
        $is_into['content'] = '';
        $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_content, $matches);
        if ($occurrences) {
            // Only for content
            $topic_keyword_desnity = round($occurrences / $post_word_count * 100, 2);
            $output .= sprintf(' <td>%d (%.2f%%)</td>', $occurrences, $topic_keyword_desnity);
        } else {
            $output .= '<td> </td>';
        }
        // Check description
        $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $description, $matches);
        if ($occurrences) {
            $output .= sprintf(' <td>%d</td>', $occurrences);
        } else {
            $output .= '<td> </td>';
        }
        // Check keywords
        if ($use_keywords) {
            $output .= '<td>N/A</td>';
            $is_into['keywords'] = 'N/A';
        } elseif (in_array($topic_keyword, $keywords)) {
            // Always 1
            $output .= '<td>1</td>';
        } else {
            $output .= '<td> </td>';
        }
        // Check original title
        $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_title, $matches);
        if ($occurrences) {
            $output .= sprintf(' <td>%d</td>', $occurrences);
        } else {
            $output .= '<td> </td>';
        }
        // Check title element
        $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_title_html_element, $matches);
        if ($occurrences) {
            $output .= sprintf(' <td>%d</td>', $occurrences);
        } else {
            $output .= '<td> </td>';
        }
        // Check metadata titles
        $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_title_metadata, $matches);
        if ($occurrences) {
            $output .= sprintf(' <td>%d</td>', $occurrences);
        } else {
            $output .= '<td> </td>';
        }
        // Check post URL
        $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_url, $matches);
        if ($occurrences) {
            $output .= sprintf(' <td>%d</td>', $occurrences);
        } else {
            $output .= '<td> </td>';
        }
        // Close row
        $output .= ' </tr>' . $BR;
    }
    $output .= '</table>' . $BR;
    // Topic Keywords Distribution Graph
    if ($options['review_mode_omit_notices'] == '0') {
        $output .= 'Topic Keywords Distribution Graph' . $BR;
        $output .= '---------------------------------' . $BR;
        $output .= 'The following text based graph shows how the <em>topic keywords</em> are distributed within your content.' . $BR;
        $output .= 'You can use it to identify incidents of keyword overstuffing.' . $BR . $BR;
    }
    //$output .= $BR . $BR;
    $total_bars = 39;
    // zero based
    $step = $post_content_length / $total_bars;
    // Debug
    //$output .= $BR . $post_content_length . '  ' . $step . $BR;
    $max_weight = null;
    $weights = array();
    // Reset weights
    for ($x = 0; $x <= $total_bars; $x++) {
        $weights[$x] = 1;
    }
    foreach ($topic_keywords as $topic_keyword) {
        // Use preg_match_all with PREG_OFFSET_CAPTURE -- http://php.net/manual/en/function.preg-match-all.php
        $topic_keyword_occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_content, $matches, PREG_OFFSET_CAPTURE);
        //var_dump($matches);
        if (!empty($topic_keyword_occurrences)) {
            foreach ($matches[0] as $match) {
                $pos = $match[1];
                $step_index = absint($pos / $step);
                $weights[$step_index] = $weights[$step_index] + 1;
                if ($weights[$step_index] > $max_weight) {
                    $max_weight = $weights[$step_index];
                }
                // Debug
                //$output .= sprintf('kw: %s, pos: %s, step index: %s, step weight: %s', $topic_keyword, $pos, $step_index, $weights[$step_index]) . $BR;
            }
        }
    }
    //var_dump($weights);
    for ($x = $max_weight - 1; $x >= 1; $x--) {
        $line = '';
        for ($y = 0; $y <= $total_bars; $y++) {
            if ($weights[$y] > $x) {
                $line .= '#';
            } else {
                $line .= ' ';
            }
        }
        $output .= $line . $BR;
    }
    // Currently this text based ruler is used as base line.
    $output .= str_repeat('---------+', ($total_bars + 1) / 10) . $BR;
    if ($options['review_mode_omit_notices'] == '0') {
        $output .= $BR . '<code>#</code>: indicates a single occurrence of a <em>topic keyword</em>.' . $BR;
    } else {
        $output .= $BR;
    }
    // Stats and scores by algos provided by the word-statistics-plugin by FD
    if (function_exists('wordstats_words')) {
        // Readability Tests
        if ($options['review_mode_omit_notices'] == '0') {
            $output .= $BR . 'Readability Scores and Text Statistics' . $BR;
            $output .= '--------------------------------------' . $BR;
            $output .= 'These readability scores and text statistics are based on algorithms provided by the <em>FD Word Statistics Plugin</em>.' . $BR . $BR;
        }
        if (function_exists('wordstats_words')) {
            $output .= sprintf(' &#9679; Total words: <strong>%d</strong>', wordstats_words($post_content)) . $BR;
        }
        if (function_exists('wordstats_sentences')) {
            $output .= sprintf(' &#9679; Total sentences: <strong>%d</strong>', wordstats_sentences($post_content)) . $BR;
        }
        if (function_exists('wordstats_flesch_kincaid')) {
            $output .= sprintf(' &#9679; Flesch-Kincaid US grade level: <strong>%.1f</strong> <em>(For instance, a score of 9.3 means suitable for a 9th grade student in the US, <a target="_blank" href="%s">read more</a>.)</em>', wordstats_flesch_kincaid($post_content), 'https://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_tests#Flesch.E2.80.93Kincaid_grade_level') . $BR;
        }
        if (function_exists('wordstats_flesch')) {
            $output .= sprintf(' &#9679; Flesch reading ease: <strong>%.1f%%</strong> <em>(avg 11 y.o. student: 90-100%%, 13-15 y.o. students: 60-70%%, university graduates: 0-30%%, <a target="_blank" href="%s">read more</a>.)</em>', wordstats_flesch($post_content), 'https://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_tests#Flesch_reading_ease') . $BR;
        }
        if (function_exists('wordstats_fog')) {
            $output .= sprintf(' &#9679; Gunning fog index: <strong>%.1f</strong> <em>(wide audience: < 12, near universal understanding: < 8, <a target="_blank" href="%s">read more</a>.)</em>', wordstats_fog($post_content), 'https://en.wikipedia.org/wiki/Gunning_fog_index') . $BR;
        }
        $output .= $BR;
    } else {
        if ($options['review_mode_omit_notices'] == '0') {
            $output .= $BR . $BR . 'Note: There is experimental support for <em>FD Word Statistics Plugin</em>.';
            $output .= $BR . 'If installed, you can get some readability scores and text statistics here.' . $BR . $BR;
        }
    }
    return $output;
}
Exemple #6
0
function amt_add_html_prefixes_and_namespaces($content)
{
    $options = amt_get_options();
    $prefixes = array();
    if ($options['og_add_xml_namespaces'] == '1') {
        $prefixes['og'] = 'http://ogp.me/ns#';
        $prefixes['fb'] = 'https://www.facebook.com/2008/fbml';
    }
    // Dublin Core
    // See: http://wiki.dublincore.org/index.php/Dublin_Core_Prefixes
    if ($options['dc_add_xml_namespaces'] == '1') {
        $prefixes['dcterms'] = 'http://purl.org/dc/terms/';
    }
    // Generate the value of the prefix attribute
    $prefix_value = '';
    foreach ($prefixes as $key => $val) {
        $prefix_value .= sprintf(' %s: %s', $key, $val);
    }
    // return the final attributes
    $output = '';
    // Although not necessary in HTML 5, we also add the xmlns="http://www.w3.org/1999/xhtml"
    // Comment out if duplicate
    $output .= ' xmlns="http://www.w3.org/1999/xhtml"';
    // Add our prefixes
    $output .= ' prefix="' . trim($prefix_value) . '"';
    return $output . ' ' . $content;
}