web-dev-qa-db-ja.com

このページでHTML5プリフェッチを有効にするにはどうすればよいですか?

サイトの例: http://www.ianstuart-bride.com

私は現在header.phpにこのコードのビットを持っていますが、それは望みどおりに動作しません:

<?php if (is_archive() && ($paged > 1) && ($paged < $wp_query->max_num_pages)) { ?>
    <link rel="prefetch" href="<?php echo get_next_posts_page_link(); ?>">
    <link rel="prerender" href="<?php echo get_next_posts_page_link(); ?>">
<?php } elseif (is_singular()) { ?>
    <link rel="prefetch" href="<?php bloginfo('home'); ?>">
    <link rel="prerender" href="<?php bloginfo('home'); ?>">
<?php } ?>

ホームページのプリフェッチが、存在しないページを指しています。ホームページで先読みを無効にしたいのですが。

私はこれらのページでプリフェッチ を有効にしたい 、 'Next'ドレスのために。

これはシングルドレスページのコードです。

これを試しましたが、次のページではなく現在のページにリンクしました。

    <link rel="prefetch" href="<?php echo get_permalink($next_dress) ?>">
    <link rel="prerender" href="<?php echo get_permalink($next_dress) ?>">
2
paradroid

正しく理解すれば、そのコードをheader.phpに入れていることになります。これはget_header()を使用してファイルsingle-dress.phpで必要であり、同じファイルでafter about 2数十行、使用した変数を定義します2ダース行before

そのため、サーバーにタイムマシンが組み込まれているか、コードが機能しません。

あなたがしなければならないことは、それらを使用する前に変数を定義するだけです。

おそらく、コードを台無しにして、ヘッダーを一連のif/elseifで埋める代わりに、テンプレートからロジックを分離できます。

プリフェッチを処理する簡単なクラスを作成します。別のファイルに保存して、functions.phpから要求することができます。

詳細については、インラインコメントをお読みください。

<?php
class My_Theme_Prefetcher {

    public $next_url;
    public $prev_url;

    function setup() {
        global $wp_query;
        // for empty query there is nothing to prefetch 
        if ( ! $wp_query instanceof WP_Query || $wp_query->found_posts <= 0  ) return;
        if ( $wp_query->is_archive() ) {
            // next page URL for archives, that is empty if there is no next page URL
            $this->next_url = get_next_posts_page_link();
        } elseif ( $wp_query->is_singular( 'dress' ) ) {
            // if on a single page view for dress CPT, run a query for dress posts
            $this->set_dress_query( $wp_query->get_queried_object_id() );
        }
        // A filter to easily get class instance and access to instance methods and vars
        add_filter( 'my_theme_prefetcher', function() { return $this; } );
        // output the prefetch strings on wp_head
        add_action( 'wp_head', array( $this, 'output' ) );
    }

    /**
    * Perform a query to get all dresses in same collection,
    * save adjacent post URLs into instance properties
    */
    function set_dress_query( $dressid ) {
        $args =  static::dress_query_args( $dressid );
        if ( empty( $args ) ) return;
        $dress_query = new WP_Query( $args );
        if ( $dress_query->found_posts > 0 ) {
            // some dresses found, discover and save adjacent URLs
            $adjacents = static::get_adjacents( $dressid, $dress_query->posts );
            if ( $adjacents['next'] ) 
                $this->next_url = get_permalink( $adjacents['next'] );
            if ( $adjacents['prev'] ) 
                $this->prev_url = get_permalink( $adjacents['prev'] );
        }
    }

    /**
    * Given a current ID and a set of posts, discover adjacent posts
    */
    static function get_adjacents( $current, Array $all ) {
        $adjacents = array( 'prev' => FALSE, 'next' => FALSE );
        if ( is_numeric( $current ) && ! empty( $all ) ) {
            $ids = wp_list_pluck( $all, 'ID' );
            $this_posts = array_search( $current, $ids );
            if ( $this_posts !== FALSE ) {
                $prev_i = $this_posts > 0 ? $this_posts -1 : FALSE;
                $next_i = $this_posts < count( $ids ) - 1 ? $this_posts + 1 : FALSE;
                $previous = $prev_i !== FALSE ? $all[ $prev_i ] : FALSE;
                $next = $next_i !== FALSE ? $all[ $next_i ] : FALSE;
                $adjacents = array( 'prev' => $previous, 'next' => $next );
            }
        }
        return $adjacents;
    }

    /**
    * Output prefetch string on wp_head. Do nothing if no, or invalid, URL is set
    */
    function output() {
        if (
            empty( $this->next_url ) ||
            ! filter_var( $this->next_url, FILTER_VALIDATE_URL )
        ) return;
        $format = '<link rel="prefetch" href="%1$s"><link rel="prerender" href="%1$s">';
        printf( $format, esc_url( $this->next_url ) );
    }

    /**
    * Returns the args for dress query for a given dress id.
    */
    static function dress_query_args( $dressid ) {
        $collections = get_the_terms( $dressid, 'collections' );
        if ( is_wp_error( $collections ) || empty( $collections ) ) return;
        $term = array_shift( $collections );
        $args = array(
            'post_type' => 'dress',
            'posts_per_page' => -1,
            'tax_query' => array(
                array( 'taxonomy' => 'collections', 'terms' => array( $term->term_id ) )
            ),
            'order' => 'ASC',
            'orderby' => 'title'
        );
        return $args;
    }

}

すべてのロジックはクラス内にあります。setup()メソッドが呼び出されると、クラスは現在のクエリを調べ、それがアーカイブの場合、次のURLを次のアーカイブページに設定します。ページが単一のドレスビュー用である場合、クエリを実行して同じコレクション内のすべてのドレスを取得し、見つかった場合、隣接する投稿URLをインスタンス変数に保存します。

ここでlaunchクラス、つまり、起動されたフックでsetup()メソッドを呼び出す必要がありますafterメインクエリは設定されていますが、before = wp_head()が呼び出されます:'template_include'は完璧です。

ここでtemplate_redirectを使用せずに、必要に応じて(追加のクエリをトリガーせずに)高速リダイレクトを許可します。ただし、'template_include'はフィルターであるため、現在のテンプレートを返す必要があります。 functions.phpに追加:

add_filter( 'template_include', function( $template ) {
    $prefetcher = new My_Theme_Prefetcher;
    $prefetcher->setup();
    return $template;
} );

これで、header.phpwp_head()呼び出しがあり、プリフェッチリンクがクラスによって追加されることを確認するだけです。

別のタスクがあります。テンプレートファイル(single-dress.php)では、隣接する投稿リンクを表示する必要がありますが、別のクエリを実行する必要はありません。隣接する投稿のURLはMy_Theme_Prefetcherでインスタンス化された'template_include'

そのため、そのインスタンスと、スコープ用に作成されたカスタムフィルタ'my_theme_prefetcher'にアクセスする必要があります。

そのため、テンプレートでは次のことができます。

<figure class="pinboard">
    <?php

    // here goes your thumbnail image stuff, I will not copy it...

    // get the prefetcher instance and check it
    $prefetcher = apply_filters( 'my_theme_prefetcher', NULL );

    if ( $prefetcher instanceof My_Theme_Prefetcher ) { 
        // we got prefetcher instance, get the urls
        $prev_url = $prefetcher->prev_url ? : FALSE;
        $next_url = $prefetcher->next_url ? : FALSE;
    } else {
        // something goes wrong, try to run the query
        // function that returns arguments is static, so we can access it
        $args = My_Theme_Prefetcher::dress_query_args( $post->ID );
        $dress_by_tax = ! empty( $args ) ? new WP_Query( $args ) : FALSE;
        if ( $dress_by_tax instanceof WP_Query && ! empty( $dress_by_tax->posts ) ) {
            // function that returns adjacent posts is static, so we can access it
            $adjacents = My_Theme_Prefetcher::get_adjacents( $post->ID, $dress_by_tax->posts );
            $next_url = $adjacents['next'] ? get_permalink( $adjacents['next'] ) : FALSE;
            $prev_url = $adjacents['prev'] ? get_permalink( $adjacents['prev'] ) : FALSE;
        } else {
            $next_url = $prev_url = FALSE;
        }
    }
    ?>

    <?php if ( $next_url ) : ?>
        <div class="nav-next arrow block button spaced ribbon">
            <a href="<?php echo $next_url ?>">Next</a>
        </div>
    <?php endif; ?>

    <?php if ( $prev_url ) : ?>
        <div class="nav-prev arrow-left block button spaced ribbon2 left">
            <a href="<?php echo $prev_url ?>">Previous</a>
        </div>
    <?php endif; ?>

    <div class="mask"><span>Click for larger size</span></div>

</figure>
6
gmazzap