有一次,我做了一个客户项目,我必须在第一封信之前就有档案。回想起来,我想知道是否应该创建一个隐藏的分类法,然后将第一个字母保存为该分类法中的术语。
anyway, here\'s what i actually did:
/*
* Function Create Array of Letters that have post titles (for archive)
*/
/* When the post is saved, saves our custom data */
function kia_save_first_letter( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined( \'DOING_AUTOSAVE\' ) && DOING_AUTOSAVE )
return;
//check location (only run for posts)
$limitPostTypes = array(\'post\');
if (!in_array($_POST[\'post_type\'], $limitPostTypes)) return;
// Check permissions
if ( !current_user_can( \'edit_post\', $post_id ) )
return;
// OK, we\'re authenticated: we need to find and save the data
$alphabet = get_option( \'kia_alphabet_archive\' );
$alphabet = is_array($alphabet) ? $alphabet : array($alphabet);
// pop off first letter of post title
$letter = substr($_POST[\'post_title\'], 0, 1);
// if it doesn\'t exist, add it to array
if(!in_array($letter, $alphabet))
$alphabet[] = $letter;
sort($alphabet);
$alphabet = is_array($alphabet) ? array_unique($alphabet) : array($alphabet);
update_option( \'kia_alphabet_archive\', $alphabet );
}
add_action( \'save_post\', \'kia_save_first_letter\' );
如果您在添加此之前已经有帖子,则需要
run the following once to grab the first letters for the existing posts://create array from existing posts
function kia_run_once(){
$alphabet = array();
$posts = get_posts(array(
\'numberposts\' => -1
) );
foreach($posts as $p) :
$alphabet[] = strtoupper(substr($p->post_title, 0, 1)); //first letter of post title, capitalized
endforeach;
sort($alphabet);
update_option( \'kia_alphabet_archive\', array_unique($alphabet) );
}
add_action(\'init\',\'kia_run_once\');
一
/*
* Custom Archives by KIA
*/
function archive_queryvars( $qvars ) {
$qvars[] = \'showarchive\';
return $qvars;
}
add_filter(\'query_vars\', \'archive_queryvars\' );
function is_custom_archive() {
global $wp_query;
return isset( $wp_query->query_vars[\'showarchive\'] );
}
function archive_search_where( $where ){
global $wpdb;
if( is_custom_archive() ) {
$char = get_query_var(\'showarchive\');
if ( ! empty($char) ) {
$where .= "AND {$wpdb->posts}.post_title LIKE \'{$char}%\'";
}
}
return $where;
}
add_filter(\'posts_where\', \'archive_search_where\' );
little helper function to make links
/*
* add archive query arg to link
*/
function get_custom_archive_link($char = \'\') {
$params = array(
\'showarchive\' => $char,
);
return add_query_arg( $params, home_url(\'/\') );
}
now create our custom archive menu
$alphabet = get_option (\'kia_alphabet_archive\');
if(count($alphabet)>0){ ?>
<div id="archive-menu" class="menu">
<?php for ($i=65; $i < 91; $i++) :
$current = (chr($i) == get_query_var(\'showarchive\')) ? "current-menu-item" : "menu-item";
if (is_array($alphabet) && in_array(chr($i), $alphabet)){ ?>
<li class="az-char <?php echo $current;?>">
<?php printf(\'<a href="%s">%s</a>\', get_custom_archive_link(chr($i)), chr($i) ) ?>
</li>
<?php } else { ?>
<li class="az-char <?php echo $current;?>">
<?php echo chr($i); ?>
</li>
<?php } ?>
<?php endfor; ?>
</div>
<?php }
点击链接后,您将进入一个页面,该页面只显示带有该字母的帖子。回顾过去,我认为分类学的想法应该是少编写很多代码,并且从一开始就内置了更干净的重写支持(即,没有查询变量,即使这些变量可以重写……我不知道怎么写)。分类法方法还将向数据库中添加税务数据,而这只添加了一个选项。那么权衡呢?
*EDIT**
好吧,我尝试了一下分类路线,它比我想象的要优雅一些
首先注册分类法。我只在帖子上运行这个,但是你可以很容易地将它修改为适合你喜欢的任何帖子类型。
// Add new taxonomy, NOT hierarchical (like tags)
function kia_create_glossary_taxonomy(){
if(!taxonomy_exists(\'glossary\')){
register_taxonomy(\'glossary\',array(\'post\'),array(
\'show_ui\' => false
));
}
}
add_action(\'init\',\'kia_create_glossary_taxonomy\');
similar save function to store our tax data when a post is saved
/* When the post is saved, saves our custom data */
function kia_save_first_letter( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined( \'DOING_AUTOSAVE\' ) && DOING_AUTOSAVE )
return;
//check location (only run for posts)
$limitPostTypes = array(\'post\');
if (!in_array($_POST[\'post_type\'], $limitPostTypes)) return;
// Check permissions
if ( !current_user_can( \'edit_post\', $post_id ) )
return;
// OK, we\'re authenticated: we need to find and save the data
$taxonomy = \'glossary\';
//set term as first letter of post title, lower case
wp_set_post_terms( $post_id, strtolower(substr($_POST[\'post_title\'], 0, 1)), $taxonomy );
//delete the transient that is storing the alphabet letters
delete_transient( \'kia_archive_alphabet\');
}
add_action( \'save_post\', \'kia_save_first_letter\' );
again need to run something once to grab old posts, remove when done
//create array from existing posts
function kia_run_once(){
$taxonomy = \'glossary\';
$alphabet = array();
$posts = get_posts(array(\'numberposts\' => -1) );
foreach($posts as $p) :
//set term as first letter of post title, lower case
wp_set_post_terms( $p->ID, strtolower(substr($p->post_title, 0, 1)), $taxonomy );
endforeach;
}
add_action(\'init\',\'kia_run_once\');
add the menu 这是唯一一个不完全优雅的部分,因为测试一个术语是否有不带额外foreach循环的post并不容易。但我通过将其存储在仅在保存后重置的瞬态中,缓解了这种情况。$taxonomy = \'glossary\';
// save the terms that have posts in an array as a transient
if ( false === ( $alphabet = get_transient( \'kia_archive_alphabet\' ) ) ) {
// It wasn\'t there, so regenerate the data and save the transient
$terms = get_terms($taxonomy);
$alphabet = array();
if($terms){
foreach ($terms as $term){
$alphabet[] = $term->slug;
}
}
set_transient( \'kia_archive_alphabet\', $alphabet );
}
?>
<div id="archive-menu" class="menu">
<?php foreach(range(\'a\', \'z\') as $i) :
$current = ($i == get_query_var($taxonomy)) ? "current-menu-item" : "menu-item";
if (in_array( $i, $alphabet )){ ?>
<li class="az-char <?php echo $current;?>">
<?php printf(\'<a href="%s">%s</a>\', get_term_link( $i, $taxonomy ), strtoupper($i) ) ?>
</li>
<?php } else { ?>
<li class="az-char <?php echo $current;?>">
<?php echo strtoupper($i); ?>
</li>
<?php } ?>
<?php endforeach; ?>
</div>
因此,有两种解决方案。后者会让您的URL显示站点。com/glossary/l,无需任何htaccess规则来重新编写查询变量。希望这有帮助。