6. 3 サイトマップ 表示

サイトマップ メニュー ローカルナビ 投稿ナビ

 閲覧画面に次の表示を行います。
  ・サイトマップ表示(ショートコード)
  ・メニュー表示(ウィジェット)
  ・カテゴリのメインクエリ:設定に従いソート
  ・ローカルナビ(パンくず):テーマのカスタマイズが必要
  ・投稿ナビゲーション(前後表示):テーマのカスタマイズが必要
 次のように表示を制限します。
1.フロントページ(最新の投稿、固定ページ&投稿ページ)
  ・'publish'以外の除外
  ・サイトマップ除外固定ページの除外
  ・サイトマップ除外カテゴリの除外
2.カテゴリのメインクエリ
  ・'publish'以外の除外
  ・サイトマップ除外カテゴリの除外
  ・子カテゴリを除外
3.カテゴリの非メインクエリ
  ・サイトマップ除外カテゴリの除外
4.カテゴリ以外のアーカイブ
  ・'publish'以外の除外
  ・サイトマップ除外固定ページの除外
  ・サイトマップ除外カテゴリの除外
5.カテゴリ以外の非メインクエリ
  ・'publish'以外の除外
  ・サイトマップ除外固定ページの除外
  ・サイトマップ除外カテゴリの除外
6.投稿のRSS
  ・投稿と固定ページに設定
  ・'publish'以外の除外
  ・サイトマップ除外固定ページの除外
  ・サイトマップ除外カテゴリの除外
7.直接アクセスされた場合に下記をリダイレクト404
  ・サイトマップから除外する投稿・固定ページ・カテゴリ
  ・'publish'以外の投稿・固定ページ
  ・カスタム投稿
8.検索
  ・投稿と固定ページに設定
  ・'publish'以外の除外
  ・検索除外固定ページの除外
  ・検索除外カテゴリの除外

コード

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
class Hk_Sitemap {
    // ------ private プロパティ ------
    private $hk_sitemap_setup = false;      // セットアップフラグ
    private $map_order_open   = array();    // サイトマップデータ

    // セットアップ:閲覧用
    function setup() {
        global $hk_map_com;
        // セットアップ終了フラグクリア
        $this->hk_sitemap_setup = false;
        // 変数初期化
        $hide_empty = 1;    // 投稿のないカテゴリを除外
        $hk_map_com->init_var( $hide_empty );
        // DB読み出し・初期値の置き換え
        $rtc = $hk_map_com->db_read();
        // サイトマップ未設定の場合
        if ( ! $rtc )        return;
        // 除外固定ページ・カテゴリの処理
        $hk_map_com->exclude_page_cat();
        // サイト構造データ解析
        $this->map_order_open = array();
        $order_new = 1;
        $level     = 1;
        $children = $hk_map_com->id_data['top']['child'];
        if ( ! empty( $children ) )
            $this->map_order_open = $hk_map_com->site_structure_recursive( $children, $order_new, $level, $this->map_order_open );
        // セットアップ終了フラグセット
        $this->hk_sitemap_setup = true;
        return;
    }

    // サイトマップ表示
    function display_sitemap() {
        global $hk_map_com;
        // サイトマップ設定済みかチェック
        if ( ! $this->hk_sitemap_setup )            return '';
        // 表示開始
        $html  = "<ul>\n";
        // フロントページ
        $alias = $hk_map_com->id_data['top']['alias'];
        $alias = htmlspecialchars( $alias );
        $link  = $hk_map_com->id_data['top']['link'];
        $html .= '<li><a href="'.$link.'" title="'.$alias.'へ">'.$alias.'</a>';
        // 構造表示
        if ( ! empty( $this->map_order_open ) ) {
            $form = 1;
            $html .= $this->print_site_structure_view( $form );
        }
        $html .= "</li></ul>\n";
        return $html;
    }

    // サイト構造表示
    //   $form: 1:サイトマップ    2:マイメニュー
    private function print_site_structure_view( $form ) {
        global $hk_map_com;
        $html = '';
        if ( $form == 1 )    $level_now = 0;
        else                 $level_now = 1;
        foreach( $this->map_order_open as $id_str => $level ) {
            if ( $level > $level_now ) {
                $html .= "\n";
                for ( $i=1; $i<=$level_now+1; $i++ )        $html .= '  ';
                $html .= "<ul>\n";
                $level_now = $level;
            }
            else if ( $level < $level_now ) {
                $html .= "</li>\n";
                $i_max = $level_now - $level;
                for ( $i=1; $i<=$i_max; $i++ ) {
                    for ( $j=$i; $j<=$level_now; $j++ )     $html .= '  ';
                    $html .= "</ul></li>\n";
                }
                $level_now = $level;
            }
            else
                $html .= "</li>\n";
            // データ
            $link = $hk_map_com->id_data[ $id_str ]['link'];
            $type = $hk_map_com->id_data[ $id_str ]['type'];
            // 表示
            if ( $form == 1 ) {
                $title = $hk_map_com->id_data[ $id_str ]['title'];
                $title = htmlspecialchars( $title );
                $html .= '<li><a href="'.$link.'" title="'.$title.'へ">'.$title.'</a>';
            }
            else {
                $alias = $hk_map_com->id_data[ $id_str ]['alias'];
                $alias = htmlspecialchars( $alias );
                $html .= '<li><a href="'.$link.'" title="'.$alias.'へ">'.$alias.'</a>';
            }
            // サイトマップ表示でカテゴリの場合、投稿タイトル表示
            if (( $form == 1 ) && ( $type == 'cat' )) {
                $posts_html = $this->sitemap_post_list( $id_str );
                if ( $posts_html != '' ) {
                    $html .= "\n<ul>\n";
                    $html .= $posts_html;
                    $html .= "</ul>";
                }
            }
        }
        unset( $id_str );
        unset( $level );
        $html .= "</li>\n";
        $i_max = $level_now - 1;
        for ( $i=1; $i<=$i_max; $i++ ) {
            for ( $j=$i; $j<=$level_now; $j++ )        $html .= '  ';
            $html .= "</ul></li>\n";
        }
        if ( $form == 2 )        return $html;
        $html .= "  </ul>\n";
        return $html;
    }

    // カテゴリ別投稿タイトル表示
    private function sitemap_post_list( $id_str ) {
        global $hk_map_com;
        $cat_id = $hk_map_com->id_data[ $id_str ]['id'];
        list( $sort_order, $sort_orderby ) = $this->sort_param( $id_str );
        // 投稿取得 (子カテゴリ除外,'publish'以外の非表示)
        $args = array(
            'post_type'      => 'post',
            'post_status'    => 'publish', 
            'category__in'   => $cat_id,
            'orderby'        => $sort_orderby,
            'order'          => $sort_order,
            'posts_per_page' => -1,
        );
        $my_query = new WP_Query( $args );
        // 投稿タイトル表示
        $html = '';
        if ( $my_query->have_posts() ) {
            while ( $my_query->have_posts() ) {
                $my_query->the_post();
                $post_link = get_permalink();
                // post_title
                $post = get_post();
                if ( isset( $post->post_title ) )
                        $post_title = $post->post_title;
                else    $post_title = '';
                $post_title = htmlspecialchars( $post_title );
                $html .= '<li><a href="'.$post_link.'" title="'.$post_title.'へ">'.$post_title."</a></li>\n";
            }
        }
        wp_reset_postdata();
        return $html;
    }

    // ソートパラメータ
    //   戻り値:$order, $orderby
    private function sort_param( $id_str ) {
        global $hk_map_com;
        if ( ! isset( $hk_map_com->id_data[ $id_str ] ) )          return array( '', '' );
        $sort = $hk_map_com->id_data[ $id_str ]['sort'];
        // ORDER 昇順か降順か
        if (( $sort == 1 ) || ( $sort == 3 ) || ( $sort == 5 ))    $order = 'ASC';
        else                                                       $order = 'DESC';
        // ORDERBY タイトルか日付かスラッグか
        if      (( $sort == 1 ) || ( $sort == 2 ))                 $orderby = 'title';
        else if (( $sort == 3 ) || ( $sort == 4 ))                 $orderby = 'date';
        else                                                       $orderby = 'name';
        return array( $order, $orderby );
    }

    // マイメニュー表示
    function my_menu() {
        global $hk_map_com;
        // サイトマップ設定済みかチェック
        if ( ! $this->hk_sitemap_setup )        return '';
        // 表示開始
        $html  = "<ul>\n";
        // フロントページ
        $alias = $hk_map_com->id_data['top']['alias'];
        $alias = htmlspecialchars( $alias );
        $link  = $hk_map_com->id_data['top']['link'];
        $html .= '<li><a href="'.$link.'" title="'.$alias.'へ">'.$alias.'</a>';
        // 構造表示
        if ( ! empty( $this->map_order_open ) ) {
            $form = 2;
            $html .= $this->print_site_structure_view( $form );
        }
        $html .= "</ul>\n";
        return $html;
    }

    // 投稿一覧表示制限
    function limit_post_list( $wp_query ) {
        global $hk_map_com;
        // サイトマップセットアップ済みかチェック
        if ( ! $this->hk_sitemap_setup )                return;
        // 検索
        if ( is_search() ) {
            $wp_query->set( 'post_type', array( 'post', 'page' ) );           // 投稿と固定ページに設定
            $wp_query->set( 'post_status', 'publish' );                       // 'publish'以外の非表示
            $wp_query->set( 'post__not_in',     $hk_map_com->ex_s_pages );    // 検索除外固定ページ
            $wp_query->set( 'category__not_in', $hk_map_com->ex_s_cats );     // 検索除外カテゴリ
            return;
        }
        // 投稿のRSS
        if ( is_feed() ) {
            $wp_query->set( 'post_type', array( 'post', 'page' ) );           // 投稿と固定ページに設定
            $wp_query->set( 'post_status', 'publish' );                       // 'publish'以外の非表示
            $wp_query->set( 'post__not_in',     $hk_map_com->ex_pages );      // 除外固定ページ
            $wp_query->set( 'category__not_in', $hk_map_com->ex_cats );       // 除外カテゴリ
            return;
        }
        // カテゴリ(メインクエリ)
        if (( $wp_query->is_main_query() ) && ( $wp_query->is_category )) {
            $wp_query->set( 'post_status', 'publish' );                       // 'publish'以外の非表示
            // ログインしている場合は公開前の確認ができるようにする
            if ( ! is_user_logged_in() )
                $wp_query->set( 'category__not_in', $hk_map_com->ex_cats );   // 除外カテゴリ
            // ソート設定 子カテゴリを除外
            $this->limit_post_list_cat( $wp_query );
            return;
        }
        // カテゴリ(非メインクエリ)
        if (( ! $wp_query->is_main_query() ) && ( $wp_query->is_category )) {
            // 'post_status'を無条件限定しない:序文用
            $wp_query->set( 'category__not_in', $hk_map_com->ex_cats );       // 除外カテゴリ
            return;
        }
        // フロントページ:最新の投稿、固定ページ&投稿ページ
        // カテゴリ以外のアーカイブ
        // 非メインクエリ:WP_Query や query_posts でデータを取得した場合(固定ページも対象)
        if (( $wp_query->is_home ) || ( $wp_query->is_archive )) {
            $wp_query->set( 'post_status', 'publish' );                       // 'publish'以外の非表示
            $wp_query->set( 'category__not_in', $hk_map_com->ex_cats );       // 除外カテゴリ
            $wp_query->set( 'post__not_in',     $hk_map_com->ex_pages );      // 除外固定ページ
            return;
        }
        return;
    }

    // カテゴリ別投稿一覧 メインクエリ
    private function limit_post_list_cat( $wp_query ) {
        // カテゴリID取得
        // cat がセットされている場合
        $cat_id = $wp_query->get('cat');
        if ( $cat_id ) {
            // 数値以外 除外
            if ( ! preg_match( '/^[0-9]+$/', $cat_id ) )    return;
        }
        // category_name がセットされている場合
        else {
            $cat_slug = $wp_query->get('category_name');
            if ( $cat_slug == '' )                          return;
            // 複数セットされている場合、除外(複数カテゴリ)
            if ( preg_match( '/,|\+/', $cat_slug ) )        return;
            // cat_slug のチェック
            $cat_obj = get_category_by_slug( $cat_slug );
            if ( $cat_obj === false )                       return;
            $cat_id = $cat_obj->cat_ID;
        }
        // ソート設定
        $id_str = 'cat_'.$cat_id;
        list( $sort_order, $sort_orderby ) = $this->sort_param( $id_str );
        $wp_query->set( 'order',   $sort_order );
        $wp_query->set( 'orderby', $sort_orderby );
        // 子カテゴリを除外
        $wp_query->set( 'category__in', array( $cat_id ) );
        $wp_query->set( 'cat', '' );
        $wp_query->set( 'category_name', '' );
        return;
    }

    // ローカルナビゲーション(パンくず)
    function local_navi() {
        global $hk_map_com;
        // サイトマップ設定済みかチェック
        if ( ! $this->hk_sitemap_setup )                        return '';
        // トップページの場合表示しない
        // (1) フロントページ=最新の投稿
        // (2) フロントページ=固定ページ && フロントページ:指定有り
        if ( is_front_page() )                                  return '';
        // (3) フロントページ=固定ページ && フロントページ:指定無し && 投稿ページ:指定有り
        if ( is_home() ) {
            $page_on_front = get_option( 'page_on_front', '' );
            if ( $page_on_front == 0 )                          return '';
        }
        // フロントページナビ
        $home_url = $hk_map_com->id_data['top']['link'];
        $alias = $hk_map_com->id_data['top']['alias'];
        $alias = htmlspecialchars( $alias );
        $toppage_html = '<a href="'.$home_url.'" title="'.$alias.'へ">'.$alias.'</a>&nbsp;&gt;&nbsp;';
        // ローカルナビ開始
        $html = $toppage_html;
        // 固定ページ
        if (( is_page() ) || ( is_home() )) {
            // 現在の固定ページの情報
            if ( is_home() )
                    $id = get_option( 'page_for_posts', '' );
            else    $id = get_the_ID();
            $id_str = 'page_'.$id;
            // サイトマップから除外する固定ページ
            if ( in_array( $id, $hk_map_com->ex_pages ) )       return $toppage_html;
            // 'publish'以外
            if ( ! isset( $hk_map_com->id_data[ $id_str ] ) )   return $toppage_html;
            // 再帰処理
            $html .= $this->local_navi_recursive( $id_str );
        }
        // 投稿・カスタム投稿
        else if ( is_single() ) {
            // 現在の投稿の情報
            $id   = get_the_ID();
            $post = get_post( $id );
            // 'publish'以外
            if ( $post->post_status != 'publish' )              return $toppage_html;
            // カスタム投稿
            if ( $post->post_type != 'post' )                   return $toppage_html;
            // 現在の投稿のカテゴリ
            $category   = get_the_category();
            $cat_id     = $category[0]->cat_ID;
            $parent_str = 'cat_'.$cat_id;
            // サイトマップから除外するカテゴリ
            if ( in_array( $cat_id, $hk_map_com->ex_cats ) )    return $toppage_html;
            // カテゴリの別名
            $alias = $hk_map_com->id_data[ $parent_str ]['alias'];
            $alias = htmlspecialchars( $alias );
            // カテゴリのリンク
            $link  = $hk_map_com->id_data[ $parent_str ]['link'];
            // ナビ
            $html_cat = '<a href="'.$link.'" title="'.$alias.'へ">'.$alias.'</a>&nbsp;&gt;&nbsp;';
            // 再帰処理
            $html .= $this->local_navi_recursive( $parent_str ).$html_cat;
        }
        // カテゴリ
        else if ( is_category() ) {
            // 現在のカテゴリ
            $cat_id = get_query_var('cat');
            $id_str = 'cat_'.$cat_id;
            // サイトマップから除外するカテゴリ
            if ( in_array( $cat_id, $hk_map_com->ex_cats ) )    return $toppage_html;
            // 再帰処理
            $html .= $this->local_navi_recursive( $id_str );
        }
        return $html;
    }

    // ローカルナビ表示 再帰処理
    private function local_navi_recursive( $id_str ) {
        global $hk_map_com;
        // 親
        $parent_str = $hk_map_com->id_data[ $id_str ]['parent'];
        if ( $parent_str == 'top' )        return '';
        // 別名
        $alias = $hk_map_com->id_data[ $parent_str ]['alias'];
        $alias = htmlspecialchars( $alias );
        // リンク
        $link  = $hk_map_com->id_data[ $parent_str ]['link'];
        // ナビ
        $html = '<a href="'.$link.'" title="'.$alias.'へ">'.$alias.'</a>&nbsp;&gt;&nbsp;';
        // 再帰処理
        $html = $this->local_navi_recursive( $parent_str ).$html;
        return $html;
    }

    // 投稿ナビゲーション 前後表示
    function post_navi() {
        global $hk_map_com;
        // サイトマップ設定済みかチェック
        if ( ! $this->hk_sitemap_setup )                        return '';
        // 現在の投稿
        $current_id = get_queried_object_id();
        $post = get_post( $current_id );
        // 'publish'以外
        if ( $post->post_status != 'publish' )                  return '';
        // カスタム投稿
        if ( $post->post_type != 'post' )                       return '';
        // 現在の投稿のカテゴリ
        $category   = get_the_category();
        $cat_id     = $category[0]->cat_ID;
        $parent_str = 'cat_'.$cat_id;
        // サイトマップから除外するカテゴリ(新規を含む)
        if ( in_array( $cat_id, $hk_map_com->ex_cats ) )        return '';
        // ソートパラメータ設定
        $id_str = 'cat_'.$cat_id;
        list( $sort_order, $sort_orderby ) = $this->sort_param( $id_str );
        // 投稿取得 (子カテゴリ除外,'publish'以外の非表示)
        $args = array(
            'post_type'      => 'post',
            'post_status'    => 'publish', 
            'category__in'   => $cat_id,
            'orderby'        => $sort_orderby,
            'order'          => $sort_order,
            'posts_per_page' => -1,
        );
        $my_query = new WP_Query( $args );
        // 前後のページ
        $prev_link  = '';
        $prev_title = '';
        $next_link  = '';
        $next_title = '';
        $found = 0;
        if ( $my_query->have_posts() ) {
            while ( $my_query->have_posts() ) {
                $my_query->the_post();
                if ( $found == 1 ) {
                    $next_link  = get_permalink();
                    // post_title
                    $post = get_post();
                    if ( isset( $post->post_title ) )
                            $next_title = $post->post_title;
                    else    $next_title = '';
                    break;
                }
                if ( get_the_ID() == $current_id )
                    $found = 1;
                else {
                    $prev_link  = get_permalink();
                    // post_title
                    $post = get_post();
                    if ( isset( $post->post_title ) )
                            $prev_title = $post->post_title;
                    else    $prev_title = '';
                }
            }
        }
        wp_reset_postdata();
        // 'publish'なし
        if ( $found == 0 )            return '';
        // prevリンク
        $prev_html = '';
        if ( $prev_link ) {
            $prev_title = htmlspecialchars( $prev_title );
            $prev_html  = '<div class="hk_plugin_float_left"><a href="'.$prev_link.'" rel="prev">←前 '.$prev_title.'</a></div>'."\n";
        }
        // nextリンク
        $next_html = '';
        if ( $next_link ) {
            $next_title = htmlspecialchars( $next_title );
            $next_html  = '<div class="hk_plugin_float_right"><a href="'.$next_link.'" rel="next">→次 '.$next_title.'</a></div>'."\n";
        }
        return $prev_html.$next_html;
    }

    // リダイレクト 404
    //   除外する投稿・固定ページ・カテゴリ
    //   'publish'以外の投稿・固定ページ
    //   カスタム投稿
    function template_redirect() {
        global $hk_map_com;
        // ログインしていればOK
        if ( is_user_logged_in() )                              return;
        // サイトマップ設定済みかチェック
        if ( ! $this->hk_sitemap_setup )                        return;
        // フロントページ:固定ページ&フロントページ
        // フロントページ:最新の投稿
        if ( is_front_page() )                                  return;
        // フロントページ:固定ページ&投稿ページ
        if ( is_home() ) {
            // Page_on_front : 0 の場合トップページ
            $page_on_front = get_option( 'page_on_front', '' );
            if ( $page_on_front == 0 )                          return;
        }
        // 固定ページ フロントページ:固定ページ&投稿ページ
        if (( is_page() ) || ( is_home() )) {
            if ( is_home() )
                    $id = get_option( 'page_for_posts', '' );
            else    $id = get_queried_object_id();
            // サイトマップから除外する固定ページ
            if ( in_array( $id, $hk_map_com->ex_pages ) )       $this->redirect_404();
            // 'publish'以外
            $id_str = 'page_'.$id;
            if ( ! isset( $hk_map_com->id_data[ $id_str ] ) )   $this->redirect_404();
        }
        // 投稿・カスタム投稿
        else if ( is_single() ) {
            $id = get_queried_object_id();
            $post = get_post( $id );
            // 'publish'以外
            if ( $post->post_status != 'publish' )              $this->redirect_404();
            // カスタム投稿
            if ( $post->post_type != 'post' )                   $this->redirect_404();
            // カテゴリ
            $category = get_the_category( $id );
            $cat_id   = $category[0]->cat_ID;
            // サイトマップから除外するカテゴリ
            if ( in_array( $cat_id, $hk_map_com->ex_cats ) )    $this->redirect_404();
        }
        // カテゴリアーカイブ
        else if ( is_category() ) {
            $cat_id = get_queried_object_id();
            // サイトマップから除外するカテゴリ
            if ( in_array( $cat_id, $hk_map_com->ex_cats ) )    $this->redirect_404();
        }
        return;
    }

    // リダイレクト 404 サブ
    private function redirect_404() {
        global $wp_query;
        $wp_query->set_404();
        include( TEMPLATEPATH.'/404.php' );
        exit;
    }
}

説明

 注意が必要なのは、投稿一覧表示制限で、“WP版”「変更のプレビュー」を行うと $wp_query->is_home が true になる点です。なぜかわかりませんし、“自作”の「プレビュー」を使用しているので、原因を調べる予定はありません。
 “WP版”「変更のプレビュー」を使い'publish'以外も表示したい場合は、関数 is_preview で判定する必要があります。下書きのプレビューは、実際にはプレビューではなく上書して表示するので関係ありません。

 このプログラムをお使いになる場合は、お使いになる方の自己責任でお願いします。

更新日:2016/01/22
掲載日:2016/01/22