昔の記事でアイキャッチ画像が設定されていない記事が目について、麦に関する記事だから、確か麦畑の写真があったはず、と思い、サイト内検索したら、出てこない。
ギャラリー内の画像のキャプションに確かに「麦」という語を使っていたはずであった。それが引っかからない。
画像に説明文を付けても検索結果に含まれないのはおかしい。
それで、検索対象に画像キャプションも含めるようにした。
attachment, inherit を検索対象にする
画像キャプションの文字列は、 wp_posts テーブル内の、post_excerpt カラム(行)に格納されている。
post_type は attachmentで、
post_status は、inherit となっている。親の記事の公開状態に依存するということ。
この3点だけ検索対象に含めれば良い。
functions.php に次を追加する。
// inherit attachment function change_search_char( $where, $obj ) { if ( $obj->is_search ) { $where = str_replace("publish", "publish' OR wp_posts.post_status = 'inherit", $where ); $where = str_replace("wp_posts.post_type = 'post'", "wp_posts.post_type IN ('post', 'page', 'attachment')", $where ); } return $where; } add_filter( 'posts_where', 'change_search_char', 10, 2 );
これで画像とキャプションだけの頁が検索結果に表示される。
検索結果にはそのままでは、サムネイル画像は表示され無い。タイトルも画像のファイル名になっていて見栄えが悪い。キャプションも表示されていない。
それで、このアタッチメント画像の元の親記事のサムネイルと画像のキャプションが抜粋文として表示されるようにする。リンク先も親記事にする。
検索結果が表示されるphp に次のように記述する。search.php など。
stork_custom: parts_archive_simple.php
<div class="top-post-list"> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <article <?php post_class('post-list animated fadeIn'); ?> role="article"> <a href="<?php echo get_permalink($post->post_parent); ?>" class="cf"> <?php if ( has_post_thumbnail($post->post_parent)) : ?> <figure class="eyecatch"> <?php echo get_the_post_thumbnail($post->post_parent, 'post-thum'); ?> <span class="wpp-views"><?php the_views(); ?><?php echo get_post_meta($post->post_parent, views, true); ?></span> <?php // SHOW YOAST PRIMARY CATEGORY, OR FIRST CATEGORY $category = get_the_category($post->post_parent); $useCatLink = false; // If post has a category assigned. if ($category){ $category_display = ''; $category_link = ''; if ( class_exists('WPSEO_Primary_Term') ) { // Show the post's 'Primary' category, if this Yoast feature is available, & one is set $wpseo_primary_term = new WPSEO_Primary_Term( 'category', get_the_id() ); $wpseo_primary_term = $wpseo_primary_term->get_primary_term(); $term = get_term( $wpseo_primary_term ); if (is_wp_error($term)) { // Default to first category (not Yoast) if an error is returned $category_display = $category[0]->name; $category_link = get_category_link( $category[0]->term_id ); $now_id = $category[0]->term_id; } else { // Yoast Primary category $category_display = $term->name; $category_link = get_category_link( $term->term_id ); $now_id = $term->term_id; } } else { // Default, display the first category in WP's list of assigned categories $category_display = $category[0]->name; $category_link = get_category_link( $category[0]->term_id ); $now_id = $category[0]->term_id; } // Display category $useCatLink = false or true で切替 if ( !empty($category_display) ){ if ( $useCatLink == true && !empty($category_link) ){ echo '<a href="'.$category_link.'">'.htmlspecialchars($category_display).'</a>'; } else { echo '<span class="cat-name">'.htmlspecialchars($category_display).'</span>'; } } } ?> </figure> <?php else: ?> <figure class="eyecatch noimg"> <img width="175" height="116" src="https://makotoiwasaki.com/wp-content/uploads/2017/02/P1004001-2-175x116.jpg" class="wp-post-image lazyload"> <span class="wpp-views"><?php the_views(); ?><?php echo get_post_meta($post->post_parent, views, true); ?></span> </figure> <?php endif; ?> <section class="entry-content"> <h1 class="h2 entry-title"><?php echo empty( $post->post_parent ) ? get_the_title( $post->ID ) : get_the_title( $post->post_parent ); ?></h1> <p class="byline entry-meta vcard"> <span class="date gf updated"><?php echo get_the_time('Y.m.d', $post->post_parent); ?></span> <span class="writer name author"><span class="fn"><?php the_author(); ?></span></span> </p> <?php if( !is_mobile() ): ?> <div class="description"><?php echo get_kirei_excerpt( get_the_excerpt(), 140) ?></div> <?php endif; ?> </section> </a> </article> <?php endwhile; ?>
以上でアタッチメント頁の親記事のリンクが検索結果に表示される。
スラッグも検索対象にする方法
URLの記事のファイル名はWordpressでは、スラッグと呼ばれている。
この記事のファイル名で検索したら引っかからないので、スラッグも検索対象にする。
functions.php に次を追加する。
/** * サイト内検索の範囲に、カテゴリー名、タグ名、スラッグを含める */ function custom_search($search, $wp_query) { global $wpdb; //サーチページ以外だったら終了 if (!$wp_query->is_search) return $search; if (!isset($wp_query->query_vars)) return $search; // ユーザー名とか、タグ名・カテゴリ名も検索対象に $search_words = explode(' ', isset($wp_query->query_vars['s']) ? $wp_query->query_vars['s'] : ''); if ( count($search_words) > 0 ) { $search = ''; foreach ( $search_words as $word ) { if ( !empty($word) ) { $search_word = $wpdb->escape("%{$word}%"); $search .= " AND ( {$wpdb->posts}.post_title COLLATE utf8mb4_general_ci LIKE '{$search_word}' OR {$wpdb->posts}.post_content COLLATE utf8mb4_general_ci LIKE '{$search_word}' OR {$wpdb->posts}.post_excerpt COLLATE utf8mb4_general_ci LIKE '{$search_word}' OR {$wpdb->posts}.post_name COLLATE utf8mb4_general_ci LIKE '{$search_word}' OR {$wpdb->posts}.post_author IN ( SELECT distinct ID FROM {$wpdb->users} WHERE display_name LIKE '{$search_word}' ) OR {$wpdb->posts}.ID IN ( SELECT distinct r.object_id FROM {$wpdb->term_relationships} AS r INNER JOIN {$wpdb->term_taxonomy} AS tt ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN {$wpdb->terms} AS t ON tt.term_id = t.term_id WHERE t.name LIKE '{$search_word}' OR t.slug LIKE '{$search_word}' OR tt.description LIKE '{$search_word}' ) ) "; } } } return $search; } add_filter('posts_search','custom_search', 10, 2);
クエリログを見る方法
検索した時に、データーベースに対してどういう活動をしているのか、 Mysql、 MariaDB のクエリログを見てみる。
/etc/my.cnf/server.cnf
に次を追記して、再起動する。
[server] general_log=1 general_log_file=/var/log/mysql/general-query.log
SSH でサーバーにログインし、 tail -f でログを見る。
tail -f /var/log/mysql/general-query.log
plugin load filter を使用すると、検索クエリが2回発生する
ログを見ると、検索した時にクエリ問い合わせが2回発生していることに気づいた。
443 Query SHOW FULL COLUMNS FROM `wp_posts` 443 Query SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND (((wp_posts.post_title LIKE '%麦が実る%') OR (wp_posts.post_excerpt LIKE '%麦が実る%') OR (wp_posts.post_content LIKE '%麦が実る%'))) AND (wp_posts.post_password = '') AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish') ORDER BY wp_posts.post_title LIKE '%麦が実る%' DESC, wp_posts.post_date DESC LIMIT 0, 18 443 Query SELECT option_value FROM wp_options WHERE option_name = 'kusanagi-image-optimizer-settings' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = '_transient_timeout_jetpack_idc_allowed' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = '_transient_jetpack_idc_allowed' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'jetpack_sync_error_idc' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'jetpack_excluded_extensions' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'jetpack_edit_links_calypso_redirect' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'lazy_load_responsive_images_native_loading_plugin' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'lazy_load_responsive_images_unveilhooks_plugin' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'lazy_load_responsive_images_enable_for_audios' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'lazy_load_responsive_images_aspectratio_plugin' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'lazy_load_responsive_images_loading_spinner' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'lazy_load_responsive_images_granular_disable_option' LIMIT 1 443 Query SELECT option_value FROM wp_options WHERE option_name = 'uninstall_plugins' LIMIT 1 443 Query SELECT * FROM wp_users WHERE user_login = 'maco' LIMIT 1 443 Query SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (1) ORDER BY umeta_id ASC 443 Query SELECT option_value FROM wp_options WHERE option_name = 'can_compress_scripts' LIMIT 1 443 Query SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND (((wp_posts.post_title COLLATE utf8mb4_general_ci LIKE '%麦が実る%') OR (wp_posts.post_excerpt COLLATE utf8mb4_general_ci LIKE '%麦が実る%') OR (wp_posts.post_content COLLATE utf8mb4_general_ci LIKE '%麦が実る%'))) AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'inherit' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_title LIKE '%麦が実る%' DESC, wp_posts.post_date DESC LIMIT 0, 18 443 Query SELECT FOUND_ROWS()
テーマを変えてみるとクエリは一回のみだったので、何かがおかしい。何かのプラグインが介入しているのだろう。
いくつかプラグインを停止してみると、2回目のクエリがなくなった。
plugin load filter が原因だった。
これをしばらく止めておく。
画像アタッチメント頁 attachment.php の作成
添付画像の頁が検索結果に表示され、それをクリックした時に表示されるテンプレートは、attachment.php。
これがなかったので、次のように作成した。
<?php get_header(); ?> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <!-- Latest compiled and minified JavaScript --> <script defer src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <div class="container"> <div class="row"> <div class="col-lg-6" style="margin-bottom: 40px; padding: 0 50px 0 50px;"> <?php echo wp_get_attachment_link( get_the_ID(), 'medium' ); ?> </div> <div class="col-lg-6"> <div class="panel panel-primary" style="max-width: 500px; border-radius: 0px; margin-top: 0px; border: 3px solid #000;"> <div class="panel-heading" style="background: #000 !important; text-align: left; border-radius: 0px; border-bottom: 0px;"><strong><i class="fa fa-info-circle fa-lg"></i> Attachment information</strong></div> <div class="panel-body" style="background-color: #fff;"> <ul class="fa-ul" style="text-align: left;"> <li><i class="fa-li fa fa-arrow-right"></i><strong>Title </strong>: <?php the_title(); ?></li> <li><?php if ( has_excerpt() ) : ?><div class="entry-caption"><strong>Excerpt </strong>: <?php the_excerpt(); ?></div></li><?php endif; ?> <li><i class="fa-li fa fa-arrow-right"></i><strong>Author name</strong> : <?php the_author(); ?></li> <li><i class="fa-li fa fa-arrow-right"></i><strong>Post name</strong> : <a href="<?php echo get_permalink($post->post_parent); ?>"><?php echo empty( $post->post_parent ) ? get_the_title( $post->ID ) : get_the_title( $post->post_parent ); ?></a></li> <li> <?php $meta = wp_get_attachment_metadata($id); echo "Credit: ".$meta[image_meta][credit]."<br /> "; echo "Camera: ".$meta[image_meta][camera]."<br />"; echo "Focal length: ".$meta[image_meta][focal_length]."<br />"; echo "Aperture: ".$meta[image_meta][aperture]."<br />"; echo "ISO: ".$meta[image_meta][iso]."<br />"; echo "Shutter speed: ".$meta[image_meta][shutter_speed]."<br />"; echo "Time Stamp: ".$meta[image_meta][created_timestamp]."<br />"; echo "Keyword: ".implode(", ", $meta[image_meta][keywords])."<br />"; echo "Copyright: ".$meta[image_meta][copyright]; ?> </li> </ul> </div> </div> <p>Select your image size and download</p> <p class='resolutions'> Downloads: <?php $images = array(); $image_sizes = get_intermediate_image_sizes(); array_unshift( $image_sizes, 'full' ); foreach( $image_sizes as $image_size ) { $image = wp_get_attachment_image_src( get_the_ID(), $image_size ); $name = $image_size . ' (' . $image[1] . 'x' . $image[2] . ')'; $images[] = '<a href="' . $image[0] . '">' . $name . '</a>'; } echo implode( ' | ', $images ); ?> </p> </div> </div></div> <?php get_footer(); ?>
この様に表示される。