「WordPress」カテゴリーアーカイブ

マルチサイトで参加サイト一覧を新しい順に並べる | よくあるWordPress

マルチサイトにした場合「ダッシュボード → 参加サイト」から管理するサイトが一覧されます。

サイト一覧

こちら、サイトが作成された順になっているので、古いサイトが上に来てしまいます。
これを新しい順に並び替えます。

functions.php かプラグインで下記のようにします。

1
2
3
4
5
function my_sites_order() {
    global $blogs;
    $blogs = array_reverse( $blogs );
}
add_action( 'myblogs_allblogs_options', 'my_sites_order' );

これで並び替え完了です。

参加サイトを新しい順に並べる

– 2014/02/14追記 –
admin bar のサイト一覧も変えたいって場合は、下記のようにします。

1
2
3
4
function my_sites_order( $blogs ) {
    return array_reverse( $blogs );
}
add_action( 'get_blogs_of_user', 'my_sites_order' );

admin bar のサイト一覧も並べ替え
– 追記おわり –

ついでに、一覧のメニュー(表示 | ダッシュボード)の後にリンクを追加するには myblogs_blog_actions アクションを使用します。

1
2
3
4
function my_sites_blog_link( $link ) {
    return $link . ' | <a href="#">TEST</a>';
}
add_action( 'myblogs_blog_actions', 'my_sites_blog_link' );

サイト一覧にメニュー追加

カスタムポストのパーマリンクを投稿IDにする / よくあるWordPress

カスタムポストを利用するとパーマリンクがイマイチな感じになるので、試行錯誤してみました。
WordPress3.5 で、ブログサイトではなくビジネスサイトのCMSとして使用する前提です。
試したのはマルチサイトでしたが、そうでなくても大丈夫と思います、たぶん。

カスタムポストを使用するとパーマリンクは /custom_post_name/slug のようになります。
これだとお客さんとかに使ってもらう時にうっかりタイトル日本語で入れるとイロイロ面倒です。
管理画面からパーマリンクの設定を変更していたりするとスラッグの書き換えもできなくなったりしますし。

これを通常の投稿のように post_id で出来ないかとイロイロ調べていたら下記ページが見つかりました。
http://memocarilog.info/wordpress/theme-custom/3909
http://webpaprika.com/387.html

ただ、$wp_rewrite ルールの中を見ると既にイロイロ登録されているみたいです。
なので、参考にしつつもなるべく余計なルールを追加しない方向で検討しました。

まずは通常の投稿設定

カスタム投稿の前に通常の投稿を /blog のように使いたいので、管理画面の「設定 → パーマリンク設定」から、カスタム構造で「/blog/%post_id%」とします。

固定ページで blog ページをつくっておいて「設定 → 表示設定」からフロントページの表示を固定ページに、投稿ページを先ほどの blog ページにしておきます。

ここまではカスタムポスト関係ないんですが、後で関連してきます。

カスタムポストを登録する

試しにお知らせを news として登録する場合は、下記のように function.php に記述するかプラグイン作成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function custom_post_types() {
    $label = 'お知らせ';
    $slug = 'news';
    $option = array(
        'label' => $label,
        'labels' => array(
            'name' => $label,
            'singular_name' => $label,
            'add_new_item' => $label . 'を追加',
            'add_new' => '新規追加',
            'new_item' => '新規' . $label,
            'view_item' => $label . 'を表示',
            'not_found' => $label . 'は見つかりませんでした',
            'not_found_in_trash' => 'ゴミ箱に' . $label . 'はありません。',
            'search_items' => $label . 'を検索',
        ),
        'capability_type' => 'post',
        'menu_position' => 5,
        'rewrite' => array(
            'slug' => $slug,
            'with_front' => false
        ),
        'public' => true,
        'query_var' => true,
        'has_archive' => true,
        'hierarchical' => false,
        'supports' => array('title', 'editor'),
    );
    register_post_type('news', $option);
}
add_action('init', 'custom_post_types');

register_post_type の説明はリファレンス見て下さい。

ココでのポイントは ‘rewrite’ オプションですかね。
with_front を false にしないと、先のパーマリンク設定の影響を受けて /blog/news となってしまいます。
あと、’public’ オプション忘れるとページが見れなかったり、’has_archive’ がないと一覧ページがでなかったりします。

で、実はこの時点で /news から一覧ページ、/news/slug でパーマリンクが見えるので細かいこと気にしないという方はそれでもよかったりします。
ちょっと検索するとこの部分でも rewrite ルールの設定が必要という情報出てきますが、3.5からなのか特に設定しなくても大丈夫です。

2013.02.02追記
内容変更するたびに「設定 → パーマリンク設定」から変更を保存しないと反映されません。
自分もファイルアップしてから、ああそうだったと気づくことが多かったです。

パーマリンクを投稿IDに設定する

ここでようやく本題ですが、気にしないと言いつつも、facebook でシェアした時にURLの見栄えがよろしくないのは気になると思います。
日本語だとURLエンコードされちゃいますし。

そこでひかかったのですが、既に rewrite ルールが設定してあるので、先に紹介した参考サイトのように新たにルールを追加しても、適用済みのルールが優先されるので NOT FOUND になってしまいます。
※パーマリンクを POST ID にしたので、一致するスラッグがないからだ思われます

なので登録済みのルールを変更することにします。
パーマリンクの設定はカスタムポスト名(この場合 ‘news’)で登録されているので、参考サイトのようにスラッグの部分を投稿IDに変更します。

1
2
3
4
5
6
7
8
9
10
11
function myposttype_permalink($post_link, $id = 0, $leavename) {
    global $wp_rewrite;
    $post = &get_post($id);
    if ( is_wp_error( $post ) )
        return $post;
    $newlink = $wp_rewrite->get_extra_permastruct($post->post_type);
    $newlink = str_replace('%'.$post->post_type.'%', $post->ID, $newlink);
    $newlink = home_url(user_trailingslashit($newlink));
    return $newlink;
}
add_filter('post_type_link', 'myposttype_permalink', 1, 3);

リライトルールは既に追加してあるのですが、get_extra_permastruct のように取得する方法はどうもないみたいです。
ただ、ソース見た感じ、既にあるものは上書きしてくれるみたいです。
なので、そのまま %news% を置き換えることにします。

1
2
3
4
5
function myposttype_rewrite() {
    global $wp_rewrite;
    $wp_rewrite->add_rewrite_tag('%news%', '([0-9]+)', 'post_type=news&p=');
}
add_action('init', 'myposttype_rewrite');

参考サイトにある add_permastruct は既に登録済みなので add_rewrite_tag で上書きするだけでOKです。
以上で、ビジネスサイトとしてだいぶ理想的なURLに設定できたと思います。
マルチサイトに対応してるのがありがたかったです。

カスタムフィールド使ってみる / よくあるWordPress

カスタムフィールドでやりくりした時のメモ。

お客さんに使ってもらう時は管理画面ライクなインターフェイスにしたいのでプラグインのカスタムフィールド・テンプレートを使ってます。
使い方はこちらが詳しいです。
http://39kn.com/2011/05/30/5486/

ということでPHPでテンプレ側の処理を。
カスタムフィールド・テンプレート使った場合はショートコードがあるんだけど、普通の人に使ってもらうにはわかりにくいのでテンプレ側で処理します。

カスタムフィールドのデータはget_post_customで連想配列で取得できます。

1
2
3
4
5
6
7
8
9
10
$custom = get_post_custom();

foreach ($custom as $key => $value) {
    if (substr($key, 0, 1) == '_') {
        continue;
    }
    switch ($key) {
        case ...
    }
}

同じ名前で複数登録できるので一旦取り出したほうがイイかも。
ただ、foreachだと余計な変数入ってるので、「_」で始まるものは除外しとく。
カスタムフィールド・テンプレート使っててもデータは同様に取得できます。

よくあるWordPress / 投稿の最初か最後を判定する

投稿を一覧表示する際にデザイン上、リストの最初と最後が必要なときに。
記事ループ内だと $wp_query を使って下記のように判定します。
※テンプレ内で使用することを想定

1
2
3
4
5
6
<?php if ($wp_query->current_post === 0) : ?>
    <li class="first">
<?php elseif ($wp_query->current_post === $wp_query->post_count - 1) : ?>
    <li class="last">
<?php endif; ?>
...

自分で一覧取ってくる時もWP_Queryで取得していればだいたい同じ。

1
2
3
4
5
6
7
8
9
10
11
<?php
$result = WP_Query(array('posts_per_page' => 10)); // 適宜欲しい内容を取得
while ($result->have_posts()) {
    $result->the_post();
    if ($result->current_post === 0) {
        echo '<li class="first">';
    } elseif ($result->current_post === $feed->post_count - 1) {
        echo '<li class="last">';
    }
...
}

よくあるWordPress / トップを固定ページにした時に投稿一覧を表示するには

すげえ基本的なことなんだけど、忘れちゃうのでメモ。
CMSとして使う時にトップページはWordPressの固定ページにしたいんだけど、デフォルトのトップはお知らせ一覧として使いたいよって時の設定方法。
結果から言うと、基本機能で出来るんだけどテンプレートで解決しようとして迷わないように。

まずは、固定ページ機能から「トップページ」と「お知らせ一覧ページ」(デフォルトトップの投稿一覧を使いたいページね)を作成します。
トップはそれなりに作るとして、お知らせ一覧は本文は無視されるのでブランクで良いす。

WordPress管理画面の「設定 → 表示」にあるフロントページの表示を下記のように設定します。

そうなのよね、単に「投稿ページ」の所に設定するとそこがこれまでのトップと同様に投稿一覧を表示してくれるようになるのね。
トップを固定ページに差し替えるのはよくやってたけど、こちらは見逃してたわ。

よくあるWordPress / 更新情報のヘッドライン表示

WordPressでトップページにお知らせなどヘッドライン表示したい場合のやりくり。

1. まずは自分自身の更新情報取ってくるとき

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
$feed = new WP_Query(array(
    'cat' => 1,
    'posts_per_page' => 5
));
?>
<div class="feed">
<?php if ($feed->have_posts()): // データあったら表示 ?>
    <ul>
    <?php while($feed->have_posts()): ?>
        <?php $feed->the_post(); ?>
        <li>
            <a href="<?php the_permalink() ?>">
                <span class="date"><?php the_time('Y.m.d'); ?></span>
                <span class="title"><?php echo mb_strimwidth(the_title('', '', false), 0, 60, '…'); ?></span>
            </a>
        </li>
    <?php endwhile; ?>
    </ul>
<?php else: ?>
    <!-- データないよ -->
<?php endif; ?>
</div>

WP_Queryで特定のカテゴリ(‘cat’ => 1)から5件だけ(‘posts_per_page’ => 5)取ってくる場合。
他にもイロイロ指定できます。
テンプレートタグ/query posts – WordPress Codex 日本語版

タイトルのとこは長いのを省略してるけど、そんなの気にしない場合は下記でも。

1
<?php the_title('<span class="title">', '</span>'); ?>

あとは the_time() のトコは the_date() 使うと、同じ日付が続いたときに省略されてあわてがちなので注意。

2. Feedから更新情報とってくるとき
どこぞのRSSやら取ってきて表示したいときもあるよね。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
include_once ABSPATH . WPINC . '/feed.php';
// Feed取得
$feed = fetch_feed('http://example.com/feed/atom/');
if (is_wp_error($feed)) {
    $maxitems = 0;
} else {
    $maxitems = $feed->get_item_quantity(5);
    $items = $feed->get_items(0, $maxitems);
}
?>
<div class="feed">
<? if ($maxitems): // データあったら表示 ?>
    <ul>
    <? foreach ($items as $item): ?>
        <li>
            <a href="<?php echo $item->get_permalink(); ?>">
                <span class="date"><?php echo $item->get_date('Y.m.d'); ?></span>
                <span class="title"><?php echo mb_strimwidth($item->get_title(), 0, 60, '…'); ?></span>
            </a>
        </li>
    <? endforeach: ?>
    </ul>
<? else: ?>
    <!-- データないよ -->
<? endif; ?>
</div>

最初に表示する件数のやりくりあるけど、だいたい流れはおなじ。
あとは feed.php のインクルード忘れないように。fetch_rss は非推奨っぽいので、fetch_feed 使いました。

よくあるWordPress / カテゴリ別で画面遷移したい時

WordPressをCMSちっくに使うときに、「お知らせ」「お客様の声」とかでカテゴリ分けして、それぞれ /news, /voice みたいに出来ないかなと思い少し調べてみた。
今まで複数ブログ立てたり、ネットワークモードとかで何とかならんかと試行錯誤していたのだが、意外と簡単に出来た。

ブログを個別表示した際、ベージナビゲーションがカテゴリにまたがってしまうので、single.php の previous_post_link と next_post_link に 3 番目の引数として true を与えると解決します。
それぞれ上下2箇所ずつあります。

1
2
in_same_cat
    (論理値) 表示している記事と同じカテゴリーの次の記事を表示するかどうかを設定します。TRUE の場合、同じカテゴリーの記事だけが表示されます

next_post_link

あとは管理画面から「パーマリンク設定」で「一般的な設定」をカスタム構造にして、/%category%/%post_id%/ とか /%category%/%postname%/ とかで見えるようになります。
WordPressのページ機能とカブらないように注意!