サポート » テーマ » 投稿原稿の中にある最初の画像を選択する方法

  • 解決済 BB7

    (@bb7)


    いつもお世話になります

    現在WordPress2.8.1を使用しています
    投稿原稿の中に毎回イラストを付けているのですが、
    そのイラストを検索一覧などのレイアウト時に
    30%に縮小し、見出しアイコンのように表示したいのです

    普段投稿時には
    ーーーーーーーーー
    <h2>投稿タイトル</h2>
    <p>text-1</p>
    <p>text-2</p>
    <p>img(1)</p>
    <p>text-3</p>
    <p>img(2)</p>
    <p>text-4</p>
    <p>img(3)</p>

    ーーーーーーーーー
    のように投稿している場合原稿があるとします

    しかし検索結果などの一覧表示するときに
    ーーーーーーーーー
    <p>img(1) </p>(30%縮小)
    <h2>投稿タイトル</h2>
    <p>抜粋</p>(投稿時に入力する抜粋)
    ーーーーーーーーー
    投稿原稿の一番はじめの画像を先頭にもってきて投稿タイトル、抜粋、と続けたいのです

    投稿原稿の中から一番最初の画像を指定するにはどのような方法があるのでしょう?
    わかりにくい説明かと思いますがお知恵を拝借させて下さい


    <p>text-1</p>
    <p>text-2</p>
    <p>img(1)</p>

    <p>text-1</p>
    <p>img(1)</p>
    の場合や

    <p>text-1</p>
    <p>text-2</p>
    <p>text-3</p>
    <p>img(1)</p>

    のようにテキストの量がなることもあります

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • カスタムフィールドに URL を入力しておくとか、最初にアップロードしたファイルのサムネイルを取得、という方法で考えた方が運用上は自然かもしれませんが、投稿内の最初の img 要素を取得し、整形し直した img 要素を出力する関数を作ってみてはいかがでしょうか?

    例えば、お使いのテーマの functions.php に以下のコードを追加し、

    if ( !function_exists('the_first_image_in_content') ) {
        function the_first_image_in_content($resize=100, $classname='') {
            global $post;
    
            $resize = intval( str_replace('%', '', $resize) );
    
            $c = apply_filters( 'the_content', $post->post_content );
            if ( empty($c) ) return;
    
            $r = array(
                'e' => '/<img([^>]+?)[\s\/]?>/is',
                's' => '/src=([\'"]?)(s?https?:\/\/[-_.!~*\\()a-zA-Z0-9;\/?:\@&=+\$,%#]+\.(?:gif|jpg|jpeg|png))\1/is',
                'a' => '/alt=([\'"]?)([^\1]+?)\1/is',
                't' => '/title=([\'"]?)([^\1]+?)\1/is',
                'w' => '/width=([\'"]?)([0-9]+%?)\1/',
                'h' => '/height=([\'"]?)([0-9]+%?)\1/',
            );
            $m = array( 'e' => array(), 's' => array(), 'a' => array(), 't' => array(), 'w' => array(), 'h' => array() );
            if ( !preg_match_all($r['e'], $c, $m['e'] ) ) return;
            if ( !preg_match( $r['s'], $m['e'][1][0], $m['s'] ) ) return;
    
            $src = $m['s'][0] . ' ';
            $alt = ( preg_match( $r['a'], $m['e'][1][0], $m['a'] ) ) ? $m['a'][0] . ' ' : '';
            $title = ( preg_match( $r['t'], $m['e'][1][0], $m['t'] ) ) ? $m['t'][0] . ' ' : '';
    
            if ( preg_match( $r['w'], $m['e'][1][0], $m['w'] ) ) {
                if ( empty($resize) || $resize == 100 ) {
                    $width = $m['w'][0] . ' ';
                } elseif ( !preg_match('/^[0-9]+$/', $m['w'][2]) ) {
                    $width = 'width="' . $resize . '%" ';
                } else {
                    $width = 'width="' . round( (int) $m['w'][2] * $resize / 100 ) . '" ';
                }
            }
    
            if ( preg_match( $r['h'], $m['e'][1][0], $m['h'] ) ) {
                if ( empty($resize) || $resize == 100 ) {
                    $height = $m['h'][0] . ' ';
                } elseif ( !preg_match('/^[0-9]+$/', $m['h'][2]) ) {
                    $height = 'height="' . $resize . '%" ';
                } else {
                    $height = 'height="' . round( (int) $m['h'][2] * $resize / 100 ) . '" ';
                }
            }
    
            if ( !empty($classname) ) {
                if ( function_exists('esc_attr') ) { // WP2.8+
                    $class = 'class="' . esc_attr($classname) . '" ';
                } else {
                    $class = 'class="' . attribute_escape($classname) . '" ';
                }
            } else {
                $class = 'class="first-image" ';
            }
    
            echo '<img ' . $src . $alt . $title . $width . $height . $class . '/>';
        }
    }

    検索結果用のテンプレートファイルの該当部分に以下のコードを挿入してみてください。

    <?php
    if (function_exists('the_first_image_in_content'))
        the_first_image_in_content(30); // 30%
    ?>

    ざっくりとは動作確認していますが、上手くいかなかったらごめんなさい。

    トピック投稿者 BB7

    (@bb7)

    mizubeさん丁寧に解説どうもありがとうございます

    functions.phpにコードを追記してみたところ
    なぜかブログのトップや管理画面にコードが表示されてしまいます
    このあたりは勉強不足なのでfunctions.phpの使い方を
    もう一度勉強してからmizubeさんの書いて下さったコードを試してみたいと思います

    それから
    >カスタムフィールドに URL を入力しておくとか、

    とのことですが、こちらの方が自分で何とか出来そうなヒントです
    不勉強な自分にとってはカスタムフィールドにURLを入れるという発想が全くなかったので、(無知な人間には当たり前のことすらわからないのです)
    このヒントをもとに自分で色々やってみようと思います

    ヒントを下さってどうもありがとうございました

    > BB7 さん
    書き漏らしてしまっていましたが、上に書いた PHP コードは <?php ?> の中に記述する必要があります。 <?php ?> の外に記述した場合、コードがそのまま出力されてしまいます。

    カスタムフィールドを使う場合は、キーが「イラストURL」だとすると

    <?php
    $src = esc_url( get_post_meta('イラストURL', $post->ID, true) );
    echo '<img src="' . $src . '" />';
    ?>

    のような感じですね。ただこの方法の場合、イラストのサイズが一定でない場合は、サイズを指定するのが難しいかもしれません。もう少し運用が楽そうな方法を私の方でも考えてみます。

    トピック投稿者 BB7

    (@bb7)

    mizubeさんお久しぶりです
    この一ヶ月mizubeさんが作って下さったコードを使用させていただきました。
    機能的には自分の望んだ「一番はじめの画像を選択し縮小する」
    という機能がシンプルに出来て大変満足しています。

    しかし、色々試してみてこのphpコードが原因と思われる
    不具合がいくつかあったので、
    またお力を貸していただきたいと書き込みさせていただきました。

    現在わかっているのは特定の動作をすると画面が真っ白になってしまうということです。

    ・ダッシュボードで下書きをプレビューしようとして「プレビュー」ボタンを押す
    ・プラグインを複数チェックして「使用する」「停止する」などを選んだとき

    あとページナビゲーションを使用しているのですが

    WP-PageNavi を使わずにナビゲーション表示
    http://www.yuriko.net/arc/2008/07/26/navigation/

    このナビゲーションを使用したとき
    [ 1 ] [ 2 ] [ 3 ] [ 4 ] と並んだページ番号の [ 1 ] をクリックすると
    白画面になってしまいます。

    白画面になった場合はdefaultテーマの名前を自作テーマの名前に変更し
    強制的にdefaultテーマにしてから再度管理画面に入ります

    コード的に回避策があれば教えていただけますでしょうか?

    > BB7 さん
    不具合の報告ありがとうございます。
    かえってご不便をかけてしまい申し訳ありません。
    こちらでも動作を確認してみますね。回答までしばらくお待ちください。

    # 追記: yuriko.net さんのところのページネートリンクをテーマに追加した状態で、上記コードの動作確認をしてみましたが、私のテストした環境では BB7 さんが遭遇されたような不具合は確認できませんでした。 (XAMPP1.7.1: Apache2.2.11 x MySQL5.0.11a x PHP5.2.9; x WordPress2.8.1)

    申し訳ありませんが、もう一度私が提示した一連のコードをすべて削除した状態で、お使いのテーマが正常に動作しているか確認してみてください (原因がこれだと絞り込むため)。

    ちなみに、

    ・ダッシュボードで下書きをプレビューしようとして「プレビュー」ボタンを押す
    ・プラグインを複数チェックして「使用する」「停止する」などを選んだとき

    という場合には、検索用テンプレートに追加したコードは動作しないはずですし、 functions.php のコードもそれ自体は関数の定義で、その関数が呼び出されるとき以外は何の影響も及ぼさないはずですので、 functions.php へのコードの記述方法が間違っていないかも疑ってみてください (<?php … ?> の外側/前後 に余計な改行や空白が混じっていないか、 BOM なしの UTF-8 で保存しているか、などの基本事項)。

    それから、

    <?php
    if (function_exists('the_first_image_in_content'))
        the_first_image_in_content(30); // 30%
    ?>

    を挿入しているテンプレートファイルの名前をすべて挙げて頂けませんか?

    お手数ですが、以上の確認をよろしくお願いします。

    トピック投稿者 BB7

    (@bb7)

    mizubeさん
    お早いお返事ありがとうございます

    ご不便どころか、もの凄く便利で手放せないです
    もう少し理解が出来れば画像の一覧とかにも応用が出来そうですし

    上記の件調べてみます

    お手間をおかけします

    トピック投稿者 BB7

    (@bb7)

    mizubeさん

    おはずかしい!
    functions.php のコードをチェックしたところ

    教えて下さったコードの上に改行が2つと
    コード間にいくつか改行が入っていたようで
    それを取り除くと
    ・プレビュー
    ・ナビゲーション
    ・複数プラグイン
    のすべてが常に動くようになりました
    改行が入っていると誤作動を起こすという事すら知りませんでした
    お騒がせしました

    ありがとうございます
    本当にに感謝します

    > BB7 さん

    解決できたようで何よりです。
    正直なところ、原因が他に思いつかなかったのでほっとしました。

    ざっくり説明しますと、これは誤作動というより、 PHP の仕様に基づくエラーが原因です。

    使用中のテーマの functions.php は、 WordPress の管理ページでも常に読み込まれるようになっています。これにより、functions.php に記述されたそのテーマ専用の設定ページやそのメニュー項目を管理ページに表示させることができます。例えば、 Default テーマを使用していると、ヘッダー色の設定ページがメニューに追加されていますよね? 他には、ログインフォームをテーマ用にカスタマイズしたり、そのようなことを実現するための挙動です。

    しかし気をつけなければいけないこともあって、使用中のテーマの functions.php は管理ページの内容を表示する処理の前、かなり早い段階で読み込まれますので、

    書き漏らしてしまっていましたが、上に書いた PHP コードは <?php ?> の中に記述する必要があります。 <?php ?> の外に記述した場合、コードがそのまま出力されてしまいます。

    と同じことで、 functions.php において、空白文字や改行文字が <?php ?> の外側に含まれていると、このファイルが読み込まれた時点でそれらの文字を text/html としてそのページで出力してしまいます。

    するとページのリダイレクト処理など、WordPress 本体やプラグイン等にて、 functions.php を読み込んだ後に header() 関数などが呼び出される処理があるいくつかの場合に、PHP のエラーが発生してしまうのです。 → エラーメッセージが表示されたり、空白が表示されたり。

    それ以外のテーマファイルについては、既に text/html で出力することが確定した段階で読み込まれるものなので、前後の空白は特に意識しなくて大丈夫ですが、プラグインファイルを作成する場合には同様の注意が必要になります。また、 <?php ?> 内の改行や空白文字 (半角に限る) については、いくつあっても大丈夫です。

    参考:

    覚えておいて頂きたいのは、header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要があることです。 頻出するエラーとして、include() または require() 関数、他のファイルをアクセスする関数に 空白または空行があり、header() の前に出力が 行われてしまうというものがあります。同じ問題は、単一の PHP/HTML ファイルを使用している場合でも存在します。

    # それから、このトピックを解決済みにして頂けると嬉しいです。

    トピック投稿者 BB7

    (@bb7)

    mizubeさん
    最後まで丁寧な説明ありがとうございます
    <?php ?>の外にある改行がエラーにつながるとは
    全く思っていなかったもので・・・。

    おかげさまで無事解決いたしました。
    ありがとうございます。

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • トピック「投稿原稿の中にある最初の画像を選択する方法」には新たに返信することはできません。