フォーラムへの返信

15件の返信を表示中 - 46 - 60件目 (全109件中)
  • LABE

    (@latobeam)

    パーマリンクにカテゴリが含まれる場合にどのカテゴリを使うかを、投稿のカスタムフィールドを使って指定できるようにする方法があります。
    良ければこちらの方法をお試しください。

    トピック: 複数カテゴリーの場合、パーマリンクになるカテゴリーを任意で選べますでしょうか。

    フォーラム: 使い方全般
    返信が含まれるトピック: 子カテゴリーが表示されない。
    LABE

    (@latobeam)

    $query->set( 'cat','30' ); の1行が不要な気がします。

    return の使い方については問題ないと思います。

    フォーラム: 使い方全般
    返信が含まれるトピック: 階層カテゴリーの短縮表示
    LABE

    (@latobeam)

    この投稿のコードを見て、以下の点が気になりました。

    1. $parentcatforeach ループの最後の1回で上書きされ、処理に無駄がある。
    2. $parentcat2 を取得しない(できない)場合にも最後に $permalink に代入しようとしている。

    1. については、どれか一つのカテゴリを reset() などで抽出して使用するのが普通ですが、どの「一つ」を使用するかを決めるためにソートする必要はあります。

    if ( $cats ) {
        usort( $cats );
        $cat = reset( $cats );
        if ( $cat->parent ) {

    2. については、 get_category_parents() では最後のカテゴリの後ろにも区切り文字を付ける仕様なので、祖先のカテゴリが1階層しかなくても $parentcat2 が取得されますが、中身は空文字列になってしまいます。
    よって empty() などでチェックする必要があります。

    以上を踏まえて、以下のコードでいかがでしょうか。

    add_filter( 'post_link', 'remove_children_category_slug', 10, 3 );
    function remove_children_category_slug( $permalink, $post, $leavename ) {
        //カテゴリーのIDを取得
        $cats = get_the_category( $post );
        if ( ! $cats )
            return $permalink;
        //ID順にソート
        usort( $cats, '_usort_terms_by_ID' );
        //一つだけ取り出す
        $cat = reset( $cats );
        //親がない場合はそのまま
        if ( empty( $cat->parent ) )
            return $permalink;
        $parentcats = explode( ' ', get_category_parents( $cat, false, ' ', true ) );
        //配列から最上位のカテゴリーを取得
        $parentcat = $parentcats[0];
        //配列から2階層目のカテゴリーを取得
        if ( ! empty( $parentcats[1] ) )
            $parentcat .= '/'.$parentcats[1];
        //管理画面で設定したパーマリンクの設定に合わせる
        $permalink = home_url( $parentcat.'/id-'.$post->ID ).'/';
        return $permalink;
    }
    フォーラム: 使い方全般
    返信が含まれるトピック: 階層カテゴリーの短縮表示
    LABE

    (@latobeam)

    すみません、勘違いでした。
    category_linkterm_link も、カテゴリアーカイブページのURLを変更するフィルターです。

    パーマリンクを変更するフィルターは post_link です。

    add_filter( 'post_link', 'permalink_change_category' );
    function permalink_change_category( $permalink ) {
        // 省略
    }
    フォーラム: 使い方全般
    返信が含まれるトピック: 【js】prependで挿入したタグがそのまま出力される
    LABE

    (@latobeam)

    .wrap などをお使いなのでjQueryをご利用なのかと思ってそのように提案させていただきましたが、そもそもjQueryをご利用ではなかったのですね。
    ともかく、解決されたようで何よりです。
    外部の掲示板などの紹介は差し控えたいと思います。

    フォーラム: 使い方全般
    返信が含まれるトピック: 階層カテゴリーの短縮表示
    LABE

    (@latobeam)

    フィルター category_link の引数は二つですが、 add_filter() の第4引数(フックする関数がとる引数の数)が3になっていますね。
    ところで、フィルター category_link はWordPress 2.5より非推奨となっているようです。
    これからは term_link を使いましょう。

    add_filter( 'term_link', 'permalink_change_category', 10, 3 );
    function permalink_change_category( $termlink, $term, $taxonomy ) {
        // 省略
    }

    引数が少し変わっています。

    LABE

    (@latobeam)

    まず、 WP_Query の使い方について、いくつか。
    exclude ですが、これは get_posts() でのみ使えるもので、 WP_Query では post__not_in を使います。
    また tax_query における relation は配列の先頭に置くことになっていますし、そもそもタクソノミーの条件が一つだけなら省略できます。

    その上でご質問にお答えしますが、これは一度表示した投稿を記録しておき、以後の WP_Querypost__not_in に指定してしまうことで実現できると思います。

    <?php
    $terms = get_the_terms($post, 'カスタムタクソノミー名');
    $exclude = array($post->ID, 1340, 1341);
    foreach ( $terms as $term ):
        $args = array(
            'post__not_in' => $exclude,
        );
        $my_query = new WP_Query( $args );
        while ( $my_query->have_posts() ):
            $my_query->the_post();
            $exclude[] = $post->ID;
    ?>
    
    <!-- 表示内容 -->
    
    <?php
        endwhile;
        wp_reset_postdata();
    endforeach;
    ?>

    上記は抜粋ですが、ポイントは

    1. foreach の直前で $exclude を初期化。
    2. $argsexclude$exclude を指定。
    3. while 内の the_post() の直後で $exclude に表示中の投稿IDを追加。

    の3点です。
    ところで、投稿IDの1340と1341は除外してよろしかったですね?

    LABE

    (@latobeam)

    もしかして、なのですが、そのアイデアはこの記事が元ネタですか?
    http://labe.wp.xdomain.jp/post/367
    違ったらごめんなさい。ちなみにこの記事を書いたのは俺です。

    ところで、俺がこのトピックの上記で紹介した方法は、その orderby とは全く異なる方法でデータを処理しているため、残念ながらその方法は使えません。
    しかし、タームの「説明」が“PHPの配列のキー名として使用可能な文字”(半角英数字など)のみで記述されており、かつ各ターム間で重複がないなら、少し修正すれば実現可能です。

    <?php
    $post_lists = array();
    // メインループ
    while ( have_posts() ):
        the_post();
        $the_terms = get_the_terms($post, 'taxsonomy-B');
        if ( ! $the_terms ):
            continue;
        endif;
        $the_term = reset($the_terms);
        $the_term_id = (int) $the_term->description;
        if ( empty($post_lists[$the_term_id]) ):
            $post_lists[$the_term_id] = array($the_term->name);
        endif;
        $post_lists[$the_term_id][] = $post;
    endwhile;
    // サブループ
    ksort($post_lists);
    foreach ( $post_lists as $term_id => $post_list ):
        // ターム毎のループ
        foreach ( $post_list as $key => $_post ):
            if ( $key === 0 ): ?>
    <h3><?php echo $_post; ?></h3>
    <?php   else: ?>
    <h4><a href="<?php echo esc_url(get_permalink($_post)); ?>"><?php echo strip_tags(get_the_title($_post)); ?></a></h4>
    <?php   endif;
        endforeach;
    endforeach;
    ?>

    前回のコードから2ヶ所だけ変わっています。
    11行目が変わっているのと、17行目と18行目の間に1行追加しています。

    フォーラム: 使い方全般
    返信が含まれるトピック: 【js】prependで挿入したタグがそのまま出力される
    LABE

    (@latobeam)

    ほとんどWordPressには関係ない事象ですので、あまりこのフォーラムでは適切でないかもしれませんが……

    .prepend.wrap はjQueryのメソッドですが、 $Output_language は生JSのオブジェクトなので、うまく動かないのではないかと。
    偶然か、 .prepend は生JSにも存在するので、文字列の追加だけはできたのでしょう。
    一方、 .wrap は生JSには存在しない関数とみなされたようです。
    var $Output_language = $('#Output_language'); と、jQueryで取得するのではだめでしょうか。

    要素を <span> の中ではなく、直前(外側)に追加するには .prepend ではなく .before を使います。
    しかし、そもそも外側の <div> をHTMLに書いておき、それに id="Output_language" を付け、その内側にJSで <h3><span> を追加するほうがスマートかと思います。
    その場合、 <h3><span>.append で追加していくことになります。

    LABE

    (@latobeam)

    「自分の選んだカテゴリ」とはどのように選ぶのか、によってやり方は変わってきます。
    例えば、投稿のカスタムフィールドに、どのカテゴリをパーマリンクとして使うかを記入する方法が手っ取り早いでしょう。

    function change_post_link_category( $cat, $cats, $post ) {
        $cats_id = array();
        foreach ( $cats as $value ) {
            $cats_id[] = $value->term_id;
        }
        $category = false;
        $post_meta = get_post_meta( $post->ID, 'permalink_cat', true );
        if ( is_numeric( $post_meta ) )
            $category = get_term( absint( $post_meta ), 'category' );
        if ( ! $category )
            $category = get_term_by( 'slug', $post_meta, 'category' );
        if ( $category && in_array( $category->term_id, $cats_id ) )
            return $category;
        return $cat;
    }
    add_filter( 'post_link_category', 'change_post_link_category', 10, 3 );

    以上のコードを functions.php に追加し、投稿のカスタムフィールドに permalink_cat というキーでカテゴリのIDまたはスラッグを保存すると、そのカテゴリをパーマリンクに使うようになる、と思います。
    動作確認はしていないので、参考までに。
    もっとグラフィカルなUIで実現したい場合は、プラグインがいくつかあるようなのでそちらをお使いください。

    • この返信は9年、 2ヶ月前にLABEが編集しました。
    LABE

    (@latobeam)

    任意に、とは具体的にはどのように決めたいのでしょうか。

    パーマリンクにカテゴリを含む場合、 get_permalink() のソースによると、 get_the_categories() で取得したカテゴリをタームIDの昇順に並び替え、最初のもの(つまり、タームIDが最も小さいもの)を使うようです。
    そして、そこにフィルターフックが用意されており、別のカテゴリに変更することは可能なようです。

    function change_post_link_category( $cat, $cats, $post ) {
        // 何か処理
        // $cat : 標準で使われるカテゴリ
        // $cats: その投稿が持つすべてのカテゴリ
        // $post: その投稿の投稿オブジェクト
    }
    add_filter( 'post_link_category', 'change_post_link_category', 10, 3 );
    LABE

    (@latobeam)

    タームの(スラッグではなく)名前は <label> の中にあるもののことだと思いますが、これをJSの for ループで一緒に取得することで実現できるでしょう。
    とはいえ、現状では <label> の中に <input> も入っているので、これを分離すれば楽になります。
    <label>for 属性を使えば、 <label><input> を入れ込まなくても両者を関連付けることができます。

    <input id="checkbox1" ...><label for="checkbox1">ターム名</label>

    このように <input> に id を付け、それと同じ値を <label>for 属性に指定します。
    id は重複さえなければ適当でいいですが、連番で付ければいいでしょう。
    幸いにも foreach の中ですので、 foreach ( $taxonomys as $key => $taxonomy ) { とすれば $key が連番っぽくなります。
    さらに <label> に class を付け、JSで <input> と同じように取得すればよいと思います。

    // 追加: <label> を取得
    var $post_tag_language_label = document.getElementsByClassName("post_tag_language_label");
    // 中略...
    // 置換: for ループ
    for(var $i = 0; $i<$post_tag_language.length; $i++) {
        if($post_tag_language[$i].checked) {
            document.getElementById("Output_lang").innerHTML += $post_tag_language_label[$i].textContent + ' ';
        }
    }

    なお、本来ならばJSにおいて <input><label> の対応を確実にしておくべきなのですが、今回は <input><label> は過不足なく1:1対応であろうことを念頭に置いています。

    • この返信は9年、 2ヶ月前にLABEが編集しました。理由: 一部訂正
    LABE

    (@latobeam)

    お見事です。
    実は長々と返信を書いていたのですが、その間に解決されたようなので、ちょっと考えたのですが、せっかく書いたので参考程度に書き残すことにします。

    ところで、「解決済み」になっていますが、以下は解決しましたか?

    選択されているタクソノミーのスラッグを拾ってきてしまうのですが、これを名前を拾うようにするにはどう書き換えればいいですか?

    ====================

    俺の回答に対するご返信についてですが、

    name="post_tag_language[]"[] の中に何か記入する必要があるということでしょうか?

    その通りだったのですが、この中身を省略しても良いというのは俺の理解不足でした。
    (そのリンク先は最初にお示しいただきたかったです)
    PHP側の foreach ループで name="post_tag_language[]" を繰り返し生成しているので、HTMLソース内の順番で0から連番として扱われる、ということだと思います。
    一方JS側では for ループで0から順番にチェックボックスを取得しています。
    そこで、トピックの最初の投稿にあるエラーですが、

    Uncaught TypeError: Cannot read property ‘length’ of undefined
    at getValue (search_output.js:21)

    $formObject.post_tag_languagelength というプロパティはない、という意味です。
    このあたり、あまり詳しくないので恐縮ですが、HTMLの name 属性が配列であっても、JSにおいては特別扱いされないのではなかろうかと思います。
    HTMLに post_tag_language という name 属性値はありません。あるのは post_tag_language[] です。
    ですから、JS側では $formObject.post_tag_language[].length とでもしなければならないのでしょうが、これはこれでエラーが出るのではないでしょうか。

    search_output.js:21 Uncaught SyntaxError: Unexpected token ]

    ] はJSでも配列のキーを示す特別な文字なので、JSのコード内にそのまま書くと問題がある、とでもいうのでしょうか。

    • この返信は9年、 2ヶ月前にLABEが編集しました。
    LABE

    (@latobeam)

    コードが長くて把握しきれていませんが、すぐに思いついた点を。
    (HTMLとJSで分けていただけると多少は読みやすくなるかと)

    <input> 要素の name 属性の値における [] は、GETパラメータを多次元配列の形にするのに使われます。
    そしてその中身は配列のキー名にあたります。
    たとえばHTMLが

    <input type="checkbox" name="aaa[bbb]" value="ccc">

    だと、PHPでは以下のようになります。

    $_GET['aaa']['bbb'] = 'ccc';

    この [] 内が空だと当然うまくいかないと思います。
    それぞれの要素ごとに適当な名前を与えてみてください。
    JSでは for ループ内の i という変数をキーとして取得しているようなので、HTMLのキー名はこれと合わせなければなりませんが。

    LABE

    (@latobeam)

    get_post_type() は引数を指定しない場合、グローバル変数の $post のデータから投稿タイプを取得します。
    これにはアーカイブページの場合、おそらくそのページで表示される最初の投稿のデータが含まれます。
    よって、アーカイブページであっても get_post_type() が有効となり、その if 文にひっかかってしまうのです。
    これを回避するには、個別投稿ページの判別に is_singular() などを併用したり、 is_post_type_archive()get_post_type() より先に書くといった方法が考えられます。

15件の返信を表示中 - 46 - 60件目 (全109件中)