- Any calls to the_category() can be replaced by calls to the_tag()
- in "page.php", wrap the whole file in the following if block:
...rest of file...
* OPTIONALLY, you can also conditionally create the content of the 'tag'
static page by wrapping the content display area of 'page.php' with an if
block:
- in your sidebar, or wherever, you can add a call to to
display a list of your current tags
4) Now you can access your tagged "category" pages via:
http://your.url/goes-here/tag/TAGNAME/
And if you followed the OPTIONAL step above, the tag archive page is:
http://your.url/goes-here/tag/
NEW TEMPLATE TAGS:
', $aff='', $showcount=true, $thresh=0, $href=true);?>
See below for usage of these tags.
*/
/* You can change these constants if you wish for further customization*/
// post meta key used in the wp database
define('WPTAGS_META', 'tags');
// get/post variable name for querying tag from WP
define('WPTAGS_QUERYVAR', 'tag');
// URL to use when querying tags
define('WPTAGS_TAGURL', 'tag');
// template file to use for displaying tag queries
define('WPTAGS_TEMPLATE', 'archive.php');
// flag to determine if plugin can change WP rewrite rules
define('WPTAGS_REWRITERULES', '1');
/* Shouldn't need to change this - can set to 0 if you want to force permalinks off */
if (isset($wp_rewrite) && $wp_rewrite->using_permalinks()) {
define('WPTAGS_REWRITEON', '1'); // nice permalinks, yes please!
define('WPTAGS_LINKBASE', $wp_rewrite->root); // set to "index.php/" if using that style
} else {
define('WPTAGS_REWRITEON', '0'); // old school links
define('WPTAGS_LINKBASE', ''); // don't need this
}
/**** actions ****/
/* editing */
add_action('edit_form_advanced', 'tag_admin_edit_form');
add_action('edit_form', 'tag_admin_edit_form');
add_action('simple_edit_form', 'tag_admin_edit_form');
add_action('edit_post', 'tag_admin_edit_form_update');
add_action('publish_post', 'tag_admin_edit_form_update');
add_action('save_post', 'tag_admin_edit_form_update');
/* feed */
add_filter('the_category_rss', 'tag_rss_filter');
/* for keyword/tag queries */
add_filter('query_vars', 'tag_addQueryVar');
add_action('parse_query', 'tag_parseQuery');
/* generate rewrite rules for above queries */
if (WPTAGS_REWRITEON && WPTAGS_REWRITERULES)
add_filter('search_rewrite_rules', 'tag_createRewriteRules');
/*
* ACTION HOOK: edit_form_advanced, edit_form, simple_edit_form
*
* Displays a list of current tags for your convenience when tagging posts.
*/
function tag_admin_edit_form() {
global $postdata, $content;
$post_tags = get_post_meta($postdata->ID, WPTAGS_META, true);
echo "
";
}
/*
* ACTION HOOK: edit_post, publish_post, save_post
*
* Responds to the new tag edit box and updates the tags field appropriately.
*/
function tag_admin_edit_form_update($id) {
// remove old value
delete_post_meta($id, WPTAGS_META);
// clean up tags list & save
$tag_list = "";
$post_tags = explode(",", $_REQUEST['tags_list']);
foreach($post_tags as $tag) {
if ( !empty($tag ) ) {
if ( !empty($tag_list) )
$tag_list .= ",";
$tag_list .= trim($tag);
}
}
if (!empty($tag_list) )
add_post_meta($id, WPTAGS_META, $tag_list);
}
/*
* FILTER: the_category_rss
*
* This puts tags into the atom and rss2 feeds.
*/
function tag_rss_filter($the_list) {
return the_tag_rss(false);
}
/*
* FILTER: query_vars
*
* Part of the URL-ness. (directly from Jerome's Keywords)
*/
function tag_addQueryVar($wpvar_array) {
$wpvar_array[] = WPTAGS_QUERYVAR;
return($wpvar_array);
}
/*
* ACTION HOOK: parse_query
*
* Part of the URL-ness. (directly from Jerome's Keywords)
*/
function tag_parseQuery() {
// if this is a keyword query, then reset other is_x flags and add query filters
if (is_tag_single()) {
global $wp_query;
$wp_query->is_single = false;
$wp_query->is_page = false;
$wp_query->is_archive = false;
$wp_query->is_search = false;
$wp_query->is_home = false;
add_filter('posts_where', 'tag_postsWhere');
add_filter('posts_join', 'tag_postsJoin');
add_action('template_redirect', 'tag_includeTemplate');
}
}
/*
* FILTER: posts_where
*
* Part of the URL-ness. (directly from Jerome's Keywords)
*/
function tag_postsWhere($where) {
$tag = $GLOBALS[WPTAGS_QUERYVAR];
tag_mangle($tag);
$tag_list = explode(' ', $tag);
$where .= " AND wptags_meta.meta_key = '" . WPTAGS_META . "' ";
foreach ($tag_list as $tag) {
$where .= " AND wptags_meta.meta_value RLIKE '^$tag$|^$tag | $tag$| $tag ' ";
}
return ($where);
}
/*
* FILTER: posts_join
*
* Part of the URL-ness. (directly from Jerome's Keywords)
*/
function tag_postsJoin($join) {
global $wpdb;
$join .= " LEFT JOIN $wpdb->postmeta AS wptags_meta ON ($wpdb->posts.ID = wptags_meta.post_id) ";
return ($join);
}
/*
* ACTION HOOK: template_redirect
*
* Part of the URL-ness. (directly from Jerome's Keywords)
*/
function tag_includeTemplate() {
if (is_tag_single()) {
$template = '';
if ( file_exists(TEMPLATEPATH . "/" . WPTAGS_TEMPLATE) )
$template = TEMPLATEPATH . "/" . WPTAGS_TEMPLATE;
else if ( file_exists(TEMPLATEPATH . "/archive.php") )
$template = TEMPLATEPATH . "/archive.php";
else
$template = get_category_template();
if ($template) {
load_template($template);
exit;
}
}
return;
}
/*
* FILTER: search_rewrite_rules
*
* Part of the URL-ness. (directly from Jerome's Keywords)
*/
function tag_createRewriteRules($rewrite) {
global $wp_rewrite;
// add rewrite tokens
$keytag_token = '%' . WPTAGS_QUERYVAR . '%';
$wp_rewrite->rewritecode[] = $keytag_token;
$wp_rewrite->rewritereplace[] = '(.+)';
$wp_rewrite->queryreplace[] = WPTAGS_QUERYVAR . '=';
$tag_structure = $wp_rewrite->root . WPTAGS_QUERYVAR . "/$keytag_token";
$tag_rewrite = $wp_rewrite->generate_rewrite_rules($tag_structure);
return ( $rewrite + $tag_rewrite );
}
/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////
/*
* TEMPLATE: the_tag
*
* ++ Inside THE LOOP ++
*
* Behaves much like 'the_category' does in that it provides you an alphabetical
* list of the tags for the current post.
*
* Parameters:
* $sep : the separator to put between the tag links. Defaults to ', '
* $href : true/false. If true, the url is wrapped in an tagname, otherwise just the URL is returned.
*
* Returns:
* Nothing.
*
* Outputs:
* The hyperlinked tag list.
*/
function the_tag($sep = ', ', $href = true) {
$custom = get_post_custom_values(WPTAGS_META);
if ( is_array($custom) ) {
$tags = implode(' ', $custom);
tag_mangle($tags);
$tag_list = explode(' ', $tags);
sort($tag_list);
for ($i = 0; $i < count($tag_list); $i++) {
$tag = $tag_list[$i];
if ( $href ) {
$tag_list[$i] = tag_link($tag);
} else {
$tag_list[$i] = $tag;
}
}
$out = implode($sep, $tag_list);
echo $out;
} else {
echo '';
}
}
/*
* TEMPLATE: the_tag_rss
*
* ++ Inside THE LOOP ++
*
* Puts the tags into a form for feeds.
*
* Parameters:
* $display : true/false. If true, the tag name is output as well as returned
*
* Returns:
* The same tag list as it would print.
*
* Outputs:
* The properly formatted chunk of XML that should go into a feed to contain the tags.
*/
function the_tag_rss($display = true) {
/* global $id, $post, $more, $single, $withcomments, $page, $pages, $multipage, $numpages;
global $preview, $cookiehash;
global $pagenow;*/
$custom = get_post_custom_values(WPTAGS_META);
$out = '';
if ( is_array($custom) ) {
$tags = implode(' ', $custom);
tag_mangle($tags);
$tag_list = explode(' ', $tags);
sort($tag_list);
for ($i = 0; $i < count($tag_list); $i++) {
$tag_list[$i] = "\n\t".convert_chars($tag_list[$i])."";
}
$out = implode('', $tag_list);
}
if ( $display ) {
echo $out;
}
return $out;
}
/*
* TEMPLATE: tag_link
*
* Fashions an URL to link to the given tag.
*
* Parameters:
* $tag : Tag to link to, defaults to ''. If equal to '', then it provides a
* link to the general tag display page instead.
* $href : true/false. If true, the url is wrapped in an tagname, otherwise just the URL is returned.
*
* Returns:
* Either a plain URL or a hyperlinked URL.
*
* Outputs:
* Nothing.
*/
function tag_link($tag = '', $href = true) {
if ( $tag == '' ) {
$href = false;
$url = get_settings('home').'/tag/';
} else {
if ( WPTAGS_REWRITEON ) {
$url = get_settings('home') . '/' . WPTAGS_LINKBASE . WPTAGS_TAGURL .
'/' . str_replace('%2F', '/', urlencode($tag));
} else {
$url = get_settings('home') . "/?" . WPTAGS_TAGURL . "=" . urlencode($keyword);
}
//rl = get_settings('home').'/tag/'.$tag.'/';
}
if ( $href ) {
return ''.$tag.'';
} else {
return $url;
}
}
/*
* TEMPLATE: is_tag_single
*
* If a page listing for a single tag name is requested, this returns true.
*
* Parameters:
* None.
*
* Returns:
* True/false depending upon whether a tag page is requested.
*
* Outputs:
* Nothing.
*/
function is_tag_single() {
if ( !empty($GLOBALS[WPTAGS_QUERYVAR]) )
return true;
else
return false;
}
/*
* TEMPLATE: the_single_tag
*
* Displays the tag name when a single tag is requested.
*
* Parameters:
* $convertspaces : true/false. If true, the spaces in the tag list will be
* converted to plusses
* $display : true/false. If true, the tag name is output as well as returned
*
* Returns:
* the tag name
*
* Outputs:
* conditionally outputs the tag name
*/
function the_single_tag($convertspaces = false, $display = true) {
$tag = stripslashes($GLOBALS[WPTAGS_QUERYVAR]);
$tag = get_magic_quotes_gpc() ? stripslashes($tag) : $tag;
/* SPLIT */
tag_mangle($tag);
if ( $convertspaces ) {
$tag = str_replace(' ', '+', $tag); // convert + to spaces
}
if ( $display ) {
echo $tag;
}
return $tag;
}
/*
* TEMPLATE: get_tags
*
* Gets an alphabetical list of all current tags.
*
* Parameters:
* $pre : Text to prefix each element with. Defaults to '
'.
* $aff : Text to affix each element with. Defaults to '
'.
* $showcount : true/false. If true, the total count is displayed after the
* hyperlinked tag name. Defaults to true.
* $thresh : only tags with more than this number of entries will be listed
* $href : true/false. If true, the url is wrapped in an tagname, otherwise just the URL is returned.
*
* Returns:
* Nothing.
*
* Outputs:
* The hyperlinked tag list.
*/
function get_tags($pre = '
', $aff = '
', $showcount = true, $thresh = 0,
$href = true) {
global $post_meta_cache; // for the primary way
global $wpdb, $tableposts, $tablepostmeta; // for the alternate way
if (!isset($tableposts)) {
$tableposts = $wpdb->tableposts;
$tablepostmeta = $wpdb->tablepostmeta;
}
$tags = "";
$tagarray = array();
// go through the cache
if ( isset($post_meta_cache) && false ) {
foreach ($post_meta_cache as $post_meta) {
if ( is_array($post_meta[WPTAGS_META]) ) {
foreach ($post_meta[WPTAGS_META] as $post_tags) {
tag_mangle($post_tags);
$taglist = explode(" ", $post_tags);
foreach ($taglist as $tagname) {
if ( isset($tagarray[$tagname]) ) {
$tagarray[$tagname]++;
} else {
$tagarray[$tagname] = 1;
}
}
}
}
}
} else {
// retrieve the data manually
$sql = "SELECT meta_value FROM $tableposts, $tablepostmeta".
" WHERE $tableposts.ID=$tablepostmeta.post_id AND".
" $tableposts.post_status='publish' AND".
" $tablepostmeta.meta_key='tags' AND".
" $tableposts.post_password='' AND $tablepostmeta.meta_value!= ''";
$results = $wpdb->get_results($sql);
if ( !empty($results) ) {
foreach ($results as $tag) {
$name = $tag->meta_value;
tag_mangle($name);
$tlist = explode(' ', $name);
foreach ($tlist as $t) {
if ( isset($tagarray[$t]) ) {
$tagarray[$t]++;
} else {
$tagarray[$t] = 1;
}
}
}
}
}
// generate output
if ( is_array($tagarray) ) {
ksort($tagarray);
foreach ($tagarray as $tag => $count) {
if ( $count > $thresh ) {
$line = '';
if ( $href ) {
$line = tag_link($tag);
} else {
$line = $tag;
}
if ( $showcount ) {
$line .= " ($count)";
}
echo $pre.$line.$aff."\n";
}
}
}
}
/*
* TEMPLATE: tag_mangle
*
* Mangles a parameter string to remove invalid tag characters
*
* Parameters:
* $s : REFERENCE to the string you wish to alter
*
* Returns:
* Nothing, though it does alter its inputs directly.
*
* Outputs:
* Nothing.
*/
function tag_mangle(&$s) {
trim($s);
$s = strtolower($s);
$s = preg_replace("/\++/", ' ', $s); // convert + to spaces
$s = preg_replace("/\s+/", ' ', $s); // concatenate all whitespace together
$s = preg_replace('/[^a-z0-9_. -]/', '', $s); // no bad characters
}
?>