วิธีใช้การก่ออิฐเพื่อเพิ่มตารางโพสต์สไตล์ Pinterest ใน WordPress


นี่คือโพสต์รับเชิญโดย Josh Pollock

การแสดงโพสต์แบบตารางเหมือน Pinterest ได้รับการออกแบบยอดนิยมสำหรับหน้าดัชนีบล็อก WordPress มาระยะหนึ่งแล้ว มันได้รับความนิยมไม่เพียงเพราะมันเลียนแบบรูปลักษณ์ของเว็บไซต์โซเชียลมีเดียยอดนิยมเท่านั้น แต่ยังเพราะมันใช้พื้นที่บนหน้าจอให้เกิดประโยชน์สูงสุดอีกด้วย ในดัชนีบล็อก WordPress จะช่วยให้แต่ละตัวอย่างโพสต์มีขนาดตามที่ต้องการตามธรรมชาติ โดยไม่เหลือพื้นที่เพิ่มเติม

ในบทช่วยสอนนี้ ฉันจะแสดงให้คุณเห็นถึงวิธีการใช้ไลบรารี Masonry JavaScript ยอดนิยมเพื่อสร้างเค้าโครงตารางแบบเรียงซ้อนสำหรับดัชนีบล็อกของคุณ รวมถึงหน้าเก็บถาวรสำหรับธีมของคุณ ฉันจะกล่าวถึงปัญหาบางประการที่คุณต้องพิจารณาในการเพิ่มประสิทธิภาพอุปกรณ์เคลื่อนที่และวิธีแก้ไข

หมายเหตุ: นี่คือบทช่วยสอนระดับสูงสำหรับผู้ที่รู้สึกสบายใจในการแก้ไขธีม WordPress และมีความรู้ HTML/CSS เพียงพอ

ขั้นตอนที่ 1: เพิ่มไลบรารีที่จำเป็นให้กับธีมของคุณ

อัปเดต: ขณะนี้ WordPress 3.9 มี Masonry เวอร์ชันล่าสุดแล้ว

ขั้นแรก คุณต้องโหลด Masonry ลงในธีมของคุณ โดยใช้โค้ดนี้:

if (! function_exists('slug_scripts_masonry') ) :
if ( ! is_admin() ) :
function slug_scripts_masonry() {
    wp_enqueue_script('masonry');
    wp_enqueue_style('masonry’, get_template_directory_uri().'/css/’);
}
add_action( 'wp_enqueue_scripts', 'slug_scripts_masonry' );
endif; //! is_admin()
endif; //! slug_scripts_masonry exists

โค้ดนี้โหลดแบบก่ออิฐและทำให้ใช้ได้กับไฟล์เทมเพลตของธีมของคุณ (ดูคำแนะนำของเราเกี่ยวกับวิธีเพิ่ม JavaScript และสไตล์ใน WordPress อย่างถูกต้อง) โปรดทราบว่าเราไม่ได้เพิ่ม jQuery เป็นการพึ่งพาสำหรับสิ่งใดสิ่งหนึ่ง ข้อดีอย่างหนึ่งของ Masonry 3 คือมันไม่ต้องใช้ jQuery แต่สามารถใช้ได้กับมัน จากประสบการณ์ของฉัน การเริ่มต้น Masonry โดยไม่มี jQuery มีความน่าเชื่อถือมากกว่า และเปิดโอกาสให้ข้ามการโหลด jQuery ซึ่งสามารถช่วยทั้งเวลาในการโหลดหน้าเว็บและปัญหาความเข้ากันได้

ขั้นตอนที่ 2: เริ่มต้น Javascript

ฟังก์ชันต่อไปนี้จะตั้งค่า Masonry กำหนดคอนเทนเนอร์ที่จะใช้กับฟังก์ชันนี้ และยังช่วยให้แน่ใจว่าทุกอย่างเกิดขึ้นในลำดับที่ถูกต้องอีกด้วย การก่ออิฐจำเป็นต้องคำนวณขนาดของแต่ละรายการบนหน้าเพื่อจัดวางตารางแบบไดนามิก ปัญหาที่ฉันพบเกี่ยวกับ Masonry ในเบราว์เซอร์หลายๆ ตัวก็คือ Masonry จะคำนวณความสูงของรายการที่มีรูปภาพโหลดช้า ส่งผลให้รายการทับซ้อนกัน วิธีแก้ไขคือใช้ imageLoaded เพื่อป้องกันไม่ให้ Masonry คำนวณเลย์เอาต์จนกว่าจะโหลดรูปภาพทั้งหมด สิ่งนี้ทำให้มั่นใจได้ถึงขนาดที่เหมาะสม

นี่คือฟังก์ชันและการดำเนินการที่จะส่งออกสคริปต์การเริ่มต้นในส่วนท้ายของหน้า:

if ( ! function_exists( 'slug_masonry_init' )) :
function slug_masonry_init() { ?>
<script>
    //set the container that Masonry will be inside of in a var
    var container = document.querySelector('#masonry-loop');
    //create empty var msnry
    var msnry;
    // initialize Masonry after all images have loaded
    imagesLoaded( container, function() {
        msnry = new Masonry( container, {
            itemSelector: '.masonry-entry'
        });
    });
</script>
<?php }
//add to wp_footer
add_action( 'wp_footer', 'slug_masonry_init' );
endif; // ! slug_masonry_init exists

ฟังก์ชั่นนี้จะอธิบายทีละขั้นตอนพร้อมความคิดเห็นแบบอินไลน์ สิ่งที่ฟังก์ชัน Javascript ทำคือบอกให้ Masonry มองภายในคอนเทนเนอร์ที่มีรหัส “masonry-loop” สำหรับรายการที่มีคลาส “masonry-entry” และให้คำนวณตารางหลังจากโหลดรูปภาพแล้วเท่านั้น เราตั้งค่าคอนเทนเนอร์ด้านนอกด้วย querySelector และคอนเทนเนอร์ด้านในด้วย itemSelector

ขั้นตอนที่ 2: สร้าง Masonry Loop

แทนที่จะเพิ่มมาร์กอัป HTML สำหรับ Masonry ลงในเทมเพลตโดยตรง เราจะสร้างส่วนเทมเพลตแยกต่างหากสำหรับมัน สร้างไฟล์ใหม่ชื่อ “content-masonry.php ” และเพิ่มลงในธีมของคุณ ซึ่งจะทำให้คุณสามารถเพิ่ม Masonry loop ลงในเทมเพลตต่างๆ ได้มากเท่าที่คุณต้องการ

ในไฟล์ใหม่ของคุณ คุณจะต้องเพิ่มโค้ดที่แสดงด้านล่าง มาร์กอัปจะคล้ายกับสิ่งที่คุณเห็นตามปกติสำหรับการแสดงตัวอย่างเนื้อหา คุณสามารถแก้ไขมันได้ทุกเมื่อที่ต้องการ เพียงแค่ต้องแน่ใจว่าองค์ประกอบด้านนอกสุดมีคลาส "รายการก่ออิฐ" ที่เราตั้งค่าเป็น itemSelector ในขั้นตอนสุดท้าย

<article class="masonry-entry" id="post-<?php the_ID(); ?>" <?php post_class(); ?> >
<?php if ( has_post_thumbnail() ) : ?>
    <div class="masonry-thumbnail">
        <a href="<?php the_permalink(' ') ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail('masonry-thumb'); ?></a>
    </div><!--.masonry-thumbnail-->
<?php endif; ?>
    <div class="masonry-details">
        <h5><a href="<?php the_permalink(' ') ?>" title="<?php the_title(); ?>"><span class="masonry-post-title"> <?php the_title(); ?></span></a></h5>
        <div class="masonry-post-excerpt">
            <?php the_excerpt(); ?>
        </div><!--.masonry-post-excerpt-->
    </div><!--/.masonry-entry-details -->  
</article><!--/.masonry-entry-->

มาร์กอัปนี้มีคลาสสำหรับแต่ละส่วน ดังนั้นคุณสามารถเพิ่มมาร์กอัปให้ตรงกับธีมของคุณได้ ฉันชอบเพิ่มเส้นขอบที่สวยงามและโค้งมนเล็กน้อยให้กับ .masonry-entry ตัวเลือกที่ดีอีกตัวหนึ่งคือไม่มีเส้นขอบสำหรับ .masonry-entry แต่ให้เงาเล็กน้อย ซึ่งดูดีเป็นพิเศษเมื่อภาพขนาดย่อของโพสต์ขยายไปจนสุดขอบของคอนเทนเนอร์ ซึ่งสามารถทำได้โดยให้ระยะขอบภาพขนาดย่อของ .masonry และช่องว่างภายในเป็น 0 ในทุกทิศทาง คุณจะต้องเพิ่มสไตล์เหล่านี้ทั้งหมดในไฟล์ชื่อ masonry.css ในไดเร็กทอรี css ของธีมของคุณ

ขั้นตอนที่ 3: เพิ่ม Masonry Loop ไปยังเทมเพลต

ตอนนี้เรามีส่วนเทมเพลตแล้ว คุณสามารถใช้มันในเทมเพลตใดก็ได้ในธีมของคุณที่คุณต้องการ คุณอาจเพิ่มลงใน index.php แต่ไม่ใช่ category.php หากคุณไม่ต้องการใช้สำหรับการเก็บถาวรหมวดหมู่ หากคุณต้องการให้มันใช้กับหน้าแรกของธีมของคุณเท่านั้น เมื่อตั้งค่าให้แสดงโพสต์ในบล็อก คุณจะต้องใช้มันใน home.php ไม่ว่าคุณจะเลือกที่ใดก็ตาม สิ่งที่คุณต้องทำคือพันลูปของคุณในคอนเทนเนอร์ด้วยรหัส “masonry-loop ” และเพิ่มส่วนเทมเพลตลงในลูปโดยใช้ get_template_part() ต้องแน่ใจว่าได้เริ่มคอนเทนเนอร์ลูปการก่ออิฐก่อน while (have_posts() )

ตัวอย่างเช่น นี่คือลูปหลักจาก index.php ของ 23thirteen:

<?php if ( have_posts() ) : ?>

    <?php /* The loop */ ?>
    <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'content', get_post_format() ); ?>
    <?php endwhile; ?>

    <?php twentythirteen_paging_nav(); ?>

<?php else : ?>
    <?php get_template_part( 'content', 'none' ); ?>
<?php endif; ?>

และนี่คือการแก้ไขเพื่อใช้ Masonry loop ของเรา:

<?php if ( have_posts() ) : ?>
<div id="masonry-loop">
    <?php /* The loop */ ?>
    <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'content', 'masonry' ?>
    <?php endwhile; ?>
</div><!--/#masonry-loop-->
    <?php twentythirteen_paging_nav(); ?>

<?php else : ?>
    <?php get_template_part( 'content', 'none' ); ?>
<?php endif; ?>

ขั้นตอนที่ 4: ตั้งค่าความกว้างที่ตอบสนองของรายการก่ออิฐ

มีหลายวิธีที่คุณสามารถกำหนดความกว้างของสินค้าก่ออิฐแต่ละรายการได้ คุณสามารถตั้งค่าความกว้างได้โดยใช้จำนวนพิกเซลเมื่อคุณเริ่มต้นการก่ออิฐ ฉันไม่ชอบการทำเช่นนั้นเนื่องจากฉันใช้ธีมแบบตอบสนองและต้องใช้คำสั่งสื่อที่ซับซ้อนเพื่อจัดการสิ่งต่าง ๆ บนหน้าจอขนาดเล็ก สำหรับการออกแบบที่ปรับเปลี่ยนตามอุปกรณ์ ฉันพบว่าสิ่งที่ดีที่สุดที่ต้องทำคือตั้งค่าความกว้างสำหรับ .masonry-entry ด้วยเปอร์เซ็นต์ โดยขึ้นอยู่กับจำนวนรายการที่คุณต้องการในแถว แล้วปล่อยให้ Masonry คำนวณส่วนที่เหลือให้คุณ

ทั้งหมดนี้ต้องการคือการหาร 100 ด้วยจำนวนรายการที่คุณต้องการกำหนดเปอร์เซ็นต์ในรายการง่ายๆ ใน style.css ของธีมของคุณ ตัวอย่างเช่น หากคุณต้องการสี่รายการในแต่ละแถว คุณสามารถทำได้ในไฟล์ masonry.css:

.รายการก่ออิฐ{width:25%}

ขั้นตอนที่ 5: การเพิ่มประสิทธิภาพมือถือ

เราอาจหยุดอยู่แค่นี้ แต่ฉันไม่คิดว่าผลลัพธ์สุดท้ายจะได้ผลดีอย่างเหลือเชื่อบนหน้าจอโทรศัพท์ขนาดเล็ก เมื่อคุณพอใจกับรูปลักษณ์ของธีมที่มีตาราง Masonry ใหม่บนเดสก์ท็อปแล้ว ให้ลองดูบนโทรศัพท์ของคุณ หากคุณไม่พอใจกับรูปลักษณ์บนโทรศัพท์ของคุณ คุณจะต้องทำงานเพียงเล็กน้อย

ฉันไม่คิดว่าจะมีพื้นที่เพียงพอบนหน้าจอโทรศัพท์สำหรับทุกสิ่งที่เราเพิ่มลงในส่วนเทมเพลตการก่ออิฐเนื้อหาของเรา วิธีแก้ปัญหาที่ดีสองประการสำหรับคุณคือย่อข้อความที่ตัดตอนมาสำหรับโทรศัพท์ให้สั้นลงหรือข้ามไปทั้งหมด นี่คือฟังก์ชันพิเศษที่คุณสามารถเพิ่มลงใน Functions.php ของธีมของคุณได้ เนื่องจากฉันไม่คิดว่าปัญหาเหล่านี้เป็นปัญหาบนแท็บเล็ต ฉันจึงใช้ปลั๊กอิน Mobble ที่ยอดเยี่ยมในตัวอย่างทั้งหมดในส่วนนี้เพื่อทำการเปลี่ยนแปลงบนโทรศัพท์เท่านั้น ไม่ใช่แท็บเล็ต ฉันยังตรวจสอบเพื่อดูว่า Mobble ทำงานอยู่หรือไม่ก่อนใช้งาน และหากจำเป็นให้กลับไปใช้ฟังก์ชันการตรวจจับอุปกรณ์เคลื่อนที่ทั่วไป wp_is_mobile ซึ่งสร้างไว้ใน WordPress

if (! function_exists('slug_custom_excerpt_length') ) :
function slug_custom_excerpt_length( $length ) {
    //set the shorter length once
    $short = 10;
    //set long length once
    $long = 55;
    //if we can only set short excerpt for phones, else short for all mobile devices
    if (function_exists( 'is_phone') {
        if ( is_phone() ) {
            return $short;
        }
        else {
            return $long;
        }        
    }
    else {
        if ( wp_is_mobile() ) {
            return $short;
        }
        else {
            return $long;
        }
    }
}
add_filter( 'excerpt_length', 'slug_custom_excerpt_length', 999 );
endif; // ! slug_custom_excerpt_length exists

ดังที่คุณเห็นว่าเราเริ่มต้นด้วยการจัดเก็บความยาวข้อความที่ตัดตอนมาแบบยาวและความยาวข้อความที่ตัดตอนมาแบบสั้นไว้ในตัวแปร เนื่องจากเราจะใช้ค่าเหล่านั้นสองครั้ง และเราต้องการที่จะเปลี่ยนค่าเหล่านั้นจากที่เดียวได้หากต้องการในภายหลัง จากนั้นเราจะทดสอบว่าเราสามารถใช้ is_phone() ของ Mobble ได้หรือไม่ หากเป็นเช่นนั้น เราจะตั้งค่าข้อความที่ตัดตอนสั้นสำหรับโทรศัพท์ และข้อความที่ตัดตอนยาวหากเราไม่ได้กำหนด หลังจากนั้นเราก็ทำสิ่งพื้นฐานเดียวกัน แต่ใช้ wp_is_mobile ซึ่งจะส่งผลต่ออุปกรณ์มือถือทั้งหมด ถ้า is_phone() ไม่สามารถใช้งานได้ หวังว่าส่วนอื่นของฟังก์ชันนี้จะไม่มีวันถูกนำมาใช้ แต่เป็นการดีที่จะมีการสำรองข้อมูลไว้เผื่อไว้ เมื่อตั้งค่าลอจิกความยาวข้อความที่ตัดตอนมาแล้ว มันก็ลงมาเพื่อเชื่อมต่อฟังก์ชันกับตัวกรอง excerpt_length

การตัดข้อความที่ตัดตอนมาให้สั้นลงก็เป็นทางเลือกหนึ่ง แต่เราก็สามารถกำจัดมันทั้งหมดได้ด้วยกระบวนการง่ายๆ เช่นกัน นี่คือเวอร์ชันใหม่ของการก่ออิฐที่มีเนื้อหาบางส่วนที่ตัดตอนมาทั้งหมดบนโทรศัพท์:

<article class="masonry-entry" id="post-<?php the_ID(); ?>" <?php post_class(); ?> >
<?php if ( has_post_thumbnail() ) : ?>
    <div class="masonry-thumbnail">
        <a href="<?php the_permalink(' ') ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail('masonry-thumb'); ?></a>
    </div><!--.masonry-thumbnail-->
<?php endif; ?>
    <div class="masonry-details">
        <h5><a href="<?php the_permalink(' ') ?>" title="<?php the_title(); ?>"><span class="masonry-post-title"> <?php the_title(); ?></span></a></h5>
        <?php 
            //put the excerpt markup in variable so we don't have to repeat it multiple times.
            $excerpt = '<div class="masonry-post-excerpt">';
            $excerpt .= the_excerpt();
            $excerpt .= '</div><!--.masonry-post-excerpt-->';
//if we can only skip for phones, else skip for all mobile devices
            if (function_exists( 'is_phone') {
                if ( ! is_phone() ) {
                    echo $excerpt;
                }
            }
            else {
                if ( ! wp_is_mobile() ) {
                    echo $excerpt;
                }
            }
        ?>
    </div><!--/.masonry-entry-details -->  
</article><!--/.masonry-entry-->

ครั้งนี้เรากำลังทดสอบเพื่อดูว่าเราไม่ได้อยู่บนโทรศัพท์/อุปกรณ์เคลื่อนที่หรือไม่ และหากเป็นเช่นนั้น เราจะส่งคืนส่วนที่ตัดตอนมาจากลูปของเรา หากเราใช้โทรศัพท์/อุปกรณ์เคลื่อนที่ เราจะไม่ทำอะไรเลย

อีกสิ่งหนึ่งที่คุณอาจต้องการทำคือเพิ่มความกว้างของรายการก่ออิฐ ซึ่งจะลดจำนวนติดต่อกันบนอุปกรณ์เคลื่อนที่ ในการดำเนินการนี้ เราจะเพิ่มสไตล์อินไลน์อื่นให้กับส่วนหัวตามการตรวจจับอุปกรณ์ เนื่องจากฟังก์ชันนี้ใช้ wp_add_inline_styles จึงขึ้นอยู่กับสไตล์ชีตเฉพาะ ในกรณีนี้ ฉันกำลังใช้ masonry.css ซึ่งคุณอาจต้องการ เพื่อแยกสไตล์การก่ออิฐของคุณออกจากกัน หากคุณไม่ได้ใช้สิ่งนั้น คุณสามารถใช้ตัวจัดการจากสไตล์ชีตอื่นที่ได้ลงทะเบียนไว้แล้ว

if ( ! function_exists ( 'slug_masonry_styles' ) ) :
function slug_masonry_styles() {
    //set the wide width
    $wide = '25%';
    //set narrow width
    $narrow = '50%';
    /**Determine value for $width**/
    //if we can only set narrow for phones, else narrow for all mobile devices
    if (function_exists( 'is_phone') {
        if ( is_phone() ) {
            $width = $narrow;
        }
        else {
            $width = $wide;
        }        
    }
    else {
        if ( wp_is_mobile() ) {
            $width = $narrow;
        }
        else {
            $width = $wide;
        }
    }
    /**Output CSS for .masonry-entry with proper width**/
    $custom_css = ".masonry-entry{width: {$width};}";
    //You must use the handle of an already enqueued stylesheet here.
    wp_add_inline_style( 'masonry', $custom_css );
}
add_action( 'wp_enqueue_scripts', 'slug_masonry_styles' );
endif; // ! slug_masonry_styles exists

ฟังก์ชันนี้จะจัดวางสไตล์ชีตแบบกำหนดเอง จากนั้นตั้งค่าความกว้างโดยใช้ตรรกะที่ควรคุ้นเคยในตอนนี้ หลังจากนั้นเราสร้างตัวแปร $custom_css โดยส่งค่าความกว้างไปยัง CSS ที่ดูปกติด้วย {$width} หลังจากนั้นเราใช้ wp_add_inline_style เพื่อบอกให้ WordPress พิมพ์สไตล์อินไลน์ของเราในส่วนหัวเมื่อใดก็ตามที่มีการใช้สไตล์ชีทของ Masonry จากนั้นเราจะเชื่อมต่อฟังก์ชันทั้งหมดเข้ากับ wp_enqueue_scripts เท่านี้ก็เสร็จเรียบร้อย

หากคุณเลือกที่จะรวมสไตล์ Masonry ของคุณเข้ากับสไตล์ชีตที่มีอยู่ ตรวจสอบให้แน่ใจว่าใช้หมายเลขอ้างอิงของสไตล์ชีตนั้นด้วย wp_add_inline_style ไม่เช่นนั้นสไตล์อินไลน์ของคุณจะไม่ถูกรวมไว้ ฉันชอบใช้ wp_add_inline_style เพราะโดยทั่วไปแล้วฉันจะรวม action hook เพื่อจัดคิว Masonry ไว้ในเงื่อนไข ดังนั้นมันจะถูกเพิ่มเมื่อจำเป็นเท่านั้น ตัวอย่างเช่น หากฉันใช้ Masonry เฉพาะในดัชนีบล็อกและหน้าเก็บถาวร ฉันจะทำสิ่งนี้:

if ( is_home() || is_archive() ) {
    add_action( 'wp_enqueue_scripts', 'slug_scripts_masonry' );
}

ตัวอย่างสุดท้ายเหล่านี้ควรเปิดความคิดอื่นๆ ในสมองของคุณ ตัวอย่างเช่น คุณสามารถใช้ตรรกะที่คล้ายกันเพื่อข้าม Masonry ไปเลยบนอุปกรณ์เคลื่อนที่ นอกจากนี้ wp_add_inline_style() ยังเป็นฟังก์ชันที่ใช้น้อยแต่มีประโยชน์มาก เนื่องจากช่วยให้คุณสามารถตั้งค่าสไตล์ที่แตกต่างกันโดยทางโปรแกรมตามเงื่อนไขประเภทใดก็ได้ ช่วยให้คุณสามารถเปลี่ยนสไตล์ขององค์ประกอบใดๆ ได้อย่างมาก ไม่เพียงแต่ขึ้นอยู่กับการตรวจจับอุปกรณ์เท่านั้น แต่การเปลี่ยนแปลงยังอาจขึ้นอยู่กับเทมเพลตที่ใช้งานอยู่ หรือแม้แต่ผู้ใช้จะเข้าสู่ระบบหรือไม่ก็ตาม

ฉันหวังว่าคุณจะเห็นการเปลี่ยนแปลงต่างๆ ที่ฉันกำลังทำอยู่เพื่อเป็นโอกาสในการสร้างสรรค์ การก่ออิฐและระบบกริดแบบเรียงซ้อนที่คล้ายกันได้รับความนิยมมาระยะหนึ่งแล้ว ดังนั้นจึงถึงเวลาสำหรับการเปลี่ยนแปลงแนวคิดยอดนิยมนี้ แสดงให้เราเห็นว่าคุณคิดอย่างไรในการใช้ Masonry ในธีม WordPress

Josh Pollock ชายหนุ่ม WordPress อเนกประสงค์ เขียนเกี่ยวกับ WordPress พัฒนาธีม ทำหน้าที่เป็นผู้จัดการชุมชนสำหรับ Pods Framework และสนับสนุนโซลูชันโอเพ่นซอร์สเพื่อการออกแบบที่ยั่งยืน