How can I use Custom Fields for meta description/keyword content?


#1

Sitepoint,
I don't want to use a plugin for description and keywords tags in the head of my wordpress (php) theme. The code I've been finding to do it uses the same description and keywords for every page. I need it so the different descriptions and sets of keywords I have for each different page are displayed for the different pages I have. The title already changes for each page without a plugin and without custom fileds, so I hope a simialr way can be used for descriptions and keywords. It doesn't have to be done through wordpress' custom fields.

Thanks,

Chris


#2

To use custom fields, you'll have to either start The Loop early (within the head) or start an extra loop within the head to pull out the custom fields.


#3

Azuaron,
I would guess a separate loop in the header.php. I foud these two pages on custom fileds and loops
http://codex.wordpress.org/The_Loop
http://codex.wordpress.org/Using_Custom_Fields

but they're above my vocabulary.

Can you give me the code for the loop that goes in header.php.
If it matters, I don't have any posts on my site, I use only pages.

Once the loop is in, is it true that all I have to do is create the custom fields ("description", "keywords") in the custom filelds section of the wordpress editor?

Thanks,

Chris


#4

Well, you'll probably want to ensure you're only calling the secondary loop on single pages, so:

<?php
if(is_single())
{
    if(have_posts())
    {
        the_post();
        
        //Do stuff
        
        rewind_posts(); //Resets the Loop. Very important for using the Loop later.
    }
}
?>

As for getting the custom fields:

$keywords = get_post_meta($post->ID,'keywords',true);
$description = get_post_meta($post->ID,'description',true);

Then you have the variables $keywords and $description to do with as you please. Note that $post->ID only works within the scope of the_post (so it should be fine if you put it where "//Do stuff" is above). Then, yes, all you have to do is add the custom fields "keywords" and "description" to the page in WP Admin.


#5

Azuaron,
Does "if you put it where "//Do stuff" is above" mean

Put these two lines:
$keywords = get_post_meta($post->ID,'keywords',true);
$description = get_post_meta($post->ID,'description',true);

In this code:

//Do stuff

    rewind_posts(); //Resets the Loop. Very important for using the Loop later.
}

} .....

right after rewind_posts(); ? Or would I put the two lines just before rewind_posts(); ?

Thanks,

Chris


#6

Good point about the rewind; I wouldn't have thought of that and been scratching my head when things were messed up.

I had some time to play with it and I got things working.

Keep in mind, one of the benefits of using plugins is you don't have to hack the files again if you upgrade or change your theme.

And the "inside the Loop requirement" is very true. The docs say custom fields work with "posts or pages" but I guess they assume they will be used in the page content, not the header.

Anyway I added custom fields to a post and a page using:
meta-description
meta-keywords

and added some test text.

Then in the header template I put the code that writes the meta tags, inserting the custom field values for the content values.

*This is very crude hackish code, and it will "break" if you use the custom fields more than once per page.

<title><?php wp_title('&laquo;', true, 'right'); ?> <?php bloginfo('name'); ?></title>

<?php
if (have_posts()) : the_post();
$custom_fields = get_post_custom();
$custom_meta_description = $custom_fields['meta-description'];
$custom_meta_keywords = $custom_fields['meta-keywords'];
if ( !empty($custom_meta_description[0]) )
{
	echo "<meta http-equiv='description' content='" . $custom_meta_description[0] . "' />\\r\
";
}
if ( !empty($custom_meta_keywords[0]) )
{
	echo "<meta http-equiv='keywords' content='" . $custom_meta_keywords[0] . "' />\\r\
";
}
rewind_posts(); // Thanks Azuaron !!
endif;
?>

and I get this view-source for a post

<title>Hello world! &laquo; test blog</title>

<meta http-equiv='description' content='initial default blog post' />
<meta http-equiv='keywords' content='hello world post' />

and this for a page

<title>About &laquo;  test blog</title>

<meta http-equiv='description' content='this page talks about me' />
<meta http-equiv='keywords' content='all, about, testing' />

You need to remember to put in the commas where you want them.


#7

Mittineague,
Thanks for the time and effort. One little problem though, via the wordpress editor, I created the 2 custom fields description and keywords. After putting your code in my header.php, unfortunately there's no description and keywords meta tags found in view source. Any thoughts? Feel free to log in. The validator I use doesn't say there's a syntax error. You know a while back I removed the comment.php file so you can't actually put a post on my site even if you wanted to - that wouldn't cause this problem would it?

Thanks,

Chris


#8

When I tested I didn't use the "description" field that was there because I have no idea where it came from, what might be using it, or how its being used (if it even is being used).

You can name the Custom Fields just about anything you want so I used

meta-description
meta-keywords

as the "field name / array keys"

i.e.

With a Custom Field named "my_test_field_name"

The array must use

$array_variable_name['my_test_field_name']

So if you named the fields "description" and "keywords" and used my code which uses "meta-description" and "meta-keywords" it won't work. They must match.

BTW the "[0]"s in the code mean "use the first one" so if you have more than one with the same name (which I don't think is possible) it will only use the first.

The code I posted doesn't replace anything. I left the "title" tag in it to show where the new PHP code should be inserted (i.e. after the title tag) in the header.php template file.


#9

Mittineague,
Thanks for saving me from myself. I overlooked that. I thought those were technical jargon I didn't understand, when actually they are names for the custom fields. I was right that there was a problem, what I didn't know was that I was the problem smile

View source looks great. Is there any noteworthy difference between
<meta http-equiv='keywords' ...
and
<meta name="keywords" .... ?

Thanks Mittineague,

Chris


#10

Good catch, that's me being the problem wink

I was working with http-equiv a while ago (caching) and I automatically used that instead of name without thinking. But yes, name is the correct thing to use for description and keywords.


#11

Mittineague,
Had a freaky error where some unknown character in the text of the description was throwing off the meta name syntax. Works great now.

I have a program I use to check seo, Deep Trawl. I wonder if all in one seo pack is more for sites with posts. It would be nice if all ine one showed a list of all the changes it makes on a site.

Thanks for your help and patience Mittineague,

Chris


#12

Anyone,
This may be a dumb question but with the strictness of syntax you worry anyway: Is there any important difference between a single mark (') quote mark and a double mark (") quotemark? I saw this come up with the coding Mittineague worked out for me above. Is it that a single mark is necessary in coding when using a quote within a quote, maybe becuase you can't have two of the same type of quote marks next to each other?

Thanks,

Chris


#13

I guess the definitive source is Strings and the best thing to do is find a style that you like and try to be consistent. - Something I've been working on but have yet to achieve blush Although I'm getting in the habit of using heredoc syntax instead of having a mess of escaped quotes inside quotes inside quotes. (sound confusing? try reading the mess of code it results in!)

Perhaps the most important thing to remember is

Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.


#14

Mittineague,
What does "will not be expanded" mean? Does it mean special characters won't show/print when single quote marks are used? If so then does this mean if I have a special character in my description or keywords, the special character won't display in view source and elsewhere?
<meta name='description' content='CO2 ......' />
<meta name='keywords' content='CO2, .....' />
Everything else in the <head> is double quotes, so I thought I'd ask. What would I do to make the single quote marks double quote marks?

Thanks,

Chris


#15

.... I guess I should say I went in and changed the single to double but it crashed the site. Maybe I should be certain to change every single quote mark, may I missed one.

Thanks,

Chris


#16

If you think of "expanded" as meaning "processed" and
$var = "something"

Then
echo "$var"; // renders -> something
echo '$var'; // renders -> $var

The "escape sequences" are things like newlines - "\r\
"

Inside double quotes the newlines will be written and will be seen in view-source, inside single quotes the characters will be interpreted as being "literal" and the characters themselves will be written out - not what they represent.

I have seen many different styles of writing code.
Escaping, $code . 'O\'brien'
Using different quotes, "$code O'Brien"

It can be confusing at first with so many different ways to get the job done. That's why I think finding a way you like and sticking with it helps.


#17

Mittineague,
Are you saying the code would have to be rewritten to get double quotes in view source, and so a little tweak of character changes won't turn the single quotes to double quotes? If so, then I'm leaving the code as is.

Thanks,

Chris


#18

Like I said, the code was a quick POC test and unfortunately I didn't use very good test words.

It depends on what you have for the value content. With single quotes something like
content='O'brien'
would break. And with double quotes something like
content="really "sexy" CSS"
would break. IMHO the best practice solution is to convert quotes (and any other potentially problem causing characters) to their entities so they're like " instead of "

i.e.

<?php
if (have_posts()) : the_post();
$custom_fields = get_post_custom();
$custom_meta_description = $custom_fields['meta-description'];
$custom_meta_keywords = $custom_fields['meta-keywords'];
if ( !empty($custom_meta_description[0]) )
{
    echo "<meta name='description' content='" . htmlentities($custom_meta_description[0]) . "' />\\r\
";
}
if ( !empty($custom_meta_keywords[0]) )
{
    echo "<meta name='keywords' content='" . htmlentities($custom_meta_keywords[0]) . "' />\\r\
";
}
rewind_posts(); // Thanks Azuaron !!
endif;
?>

#19

Mittineague,
Once you put in htmlentities, I see that view > page source is being stylized (for those two lines), which made me realize that I think the problem is that it's php coding along side xhtml coding in the <head> of xhtml (and I have an option turned on somewhere on the webhost server to understand php) - xhtml uses doubles and php uses singles. This is what I didn't see isn't it.

Thanks,

Chris


#20

TBH I don't think it makes much difference what kind of quotes the attribute values are inside of as long as they're inside quotes. But if you want them to be the same (who's going to know or really care?) try:

<?php
if (have_posts()) : the_post();
$custom_fields = get_post_custom();
$custom_meta_description = $custom_fields['meta-description'];
$custom_meta_keywords = $custom_fields['meta-keywords'];
if ( !empty($custom_meta_description[0]) )
{
    echo '<meta name="description" content="' . htmlentities($custom_meta_description[0]) . '" />' . "\\r\
";
}
if ( !empty($custom_meta_keywords[0]) )
{
    echo '<meta name="keywords" content="' . htmlentities($custom_meta_keywords[0]) . '" />' . "\\r\
";
}
rewind_posts(); // Thanks Azuaron !!
endif;
?>