Alphabetical Index Page

时间:2019-03-05 作者:tylorreimer

我似乎不能完全理解创建字母索引页所需的逻辑。我可以得到一个基本的版本,但我想做的是创建这样的东西https://www.carryology.com/brands/.

到目前为止,我的代码输出了一组分类术语的第一个字母,然后每次它找到一个新字母时,都会将该字母添加到索引中。

我不知道的是A)如何将帖子平均划分为列(引导标记被包装在<div class="col-sm-2"> B)如果我能做到这一点,那么如何一次将3个字母组合在一起,即a-C、D-F等。

以下是我目前的代码:

<?php
$args = array(
    \'taxonomy\' => \'brands\',
    \'hide_empty\' => 0,
    \'orderby\' => \'name\',
    \'order\' => \'ASC\',
);
$category_list = get_categories($args);
$curr_letter = \'\';

foreach ( $category_list as $category ) {
    $this_letter = strtoupper(substr($category->name,0,1));

    if ($this_letter != $curr_letter) {
        echo !empty( $curr_letter ) ? \'</div>\' : null;
        echo \'<div class="row">\';
        echo \'<h3 class="col-sm-2">\' . $this_letter . \'</h3>\';
        $curr_letter = $this_letter;
    }
    echo \'<div class="col-sm-2">\' . $category->name . \'</div>\';
}
?>
我曾想过尝试将循环的每个第n次迭代存储到每个列的新数组中,然后在遇到新字母时清空数组,但我不完全确定如何做到这一点。也许有人能给我指出正确的方向。

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

您可以这样做:

// Group the categories by their FIRST LETTER.
$groups = [];
foreach ( $category_list as &$term ) {
    $letter = strtoupper( substr( $term->name, 0, 1 ) );
    if ( ! isset( $groups[ $letter ] ) ) {
        $groups[ $letter ] = [];
    }

    $groups[ $letter ][] = $term;
}

// Now display them, three groups in each row.
echo \'<div class="row">\';
$i = 0;
$letters = array_keys( $groups );
foreach ( $groups as $letter => $terms ) {
    $new_row = ( $i % 3 === 0 );
    if ( $i && $new_row ) {
        echo \'</div><div class="row">\';
    }

    // Show either "A - C", "A & B", or just a letter.
    if ( ! $i || $new_row ) {
        $range = array_slice( $letters, $i, 3 );
        if ( $end = $range[ count( $range ) - 1 ] ) {
            $sign = ( count( $range ) > 2 ) ? \' - \' : \' & \';
            $range = $letter . $sign . $end;
            echo \'<h2 class="col-12">\' . $range . \'</h2>\';
        } else {
            echo \'<h2 class="col-12">\' . $letter . \'</h2>\';
        }
    }

    echo \'<div class="col-sm">\';
    if ( ! empty( $terms ) ) {
        echo \'<ul>\';
        foreach ( $terms as $term ) {
            echo \'<li>\' . $term->name . \'</li>\';
        }
        echo \'</ul>\';
    }
    echo \'</div>\';

    $i++;
}
echo \'</div>\';
输出如下:


更新,因此这是正确的版本,基于上的布局Carryology.com/brands/ (写作时)。

我已经对代码(虽然不是所有部分)进行了注释,您应该不难修改代码:

// Group the categories by their FIRST LETTER.
$letters = range( \'A\', \'Z\' );
$groups = [];
foreach ( $category_list as &$term ) {
    $letter = strtoupper( substr( $term->name, 0, 1 ) );
    if ( ! isset( $groups[ $letter ] ) ) {
        $groups[ $letter ] = [];
    }

    $groups[ $letter ][] = $term;
}

$cols = 3; // number of letters in a range
for ( $i = 0; $i < count( $letters ); $i++ ) {
    if ( $i % $cols === 0 ) {
        $list = array_slice( $letters, $i, $cols );
        // Start the row.
        echo \'<div class="row">\';

        // Show the heading. (letter range)
        $end = $list[ count( $list ) - 1 ];
        $sign = ( count( $list ) > 2 ) ? \' - \' : \' & \';
        $range = $end ? $sign . $end : \'\';
        // Show either "A - C", "A & B", or just a letter.
        echo \'<h3 class="col-sm-2">\' . $list[0] . $range . \'</h3>\';

        // Put all the letter terms in a single group.
        $groups2 = [];
        for ( $j = 0; $j < count( $list ); $j++ ) {
            if ( isset( $groups[ $list[ $j ] ] ) ) {
                $groups2 = array_merge( $groups2, $groups[ $list[ $j ] ] );
            }
        }

        $cols2 = 5; // number of columns in a row, excluding the heading.
        $n = count( $groups2 );
        $rows = floor( $n / $cols2 );
        $diff = $n - $rows * $cols2;
        for ( $k = 0, $l = 0; $k < $cols2; $k++ ) {
            $x = $diff ? 1 : 0;
            // Start a column.
            echo \'<ul class="col-xs-4 col-sm-2">\';

            // Show the group terms.
            foreach ( array_slice( $groups2, $l, $rows + $x ) as $term ) {
                echo \'<li>\' . $term->name . \'</li>\';
                $l++;
            }

            $diff = $diff ? $diff - 1 : 0;
            // Column end.
            echo \'</ul>\';
        }

        // Row end.
        echo \'</div>\';
    }
}
输出如下:

相关推荐

Dropdown menu for categories

当我使用下面的代码时<?php wp_nav_menu( array(\'menu\' => \'categories\' )); ?> 我可以创建一个新的菜单来列出我创建的wordpress中的所有类别。我用它在页面中间列出所有类别。我现在的问题是:有没有一种简单的方法可以为存在的每个子类别创建下拉菜单?那么,当我点击一个特定的类别时,它的子类别会显示出来吗?