12/08/2018, 13:54

Tìm hiểu CMS Wordpress P3 - Lập trình theme WordPress - Viết các template, ghép các template vào để hình thành theme.

Ở phần hai của bài tìm hiểu về WP chúng ta đã tìm hiểu và tạo được cấu trúc theme cùng với các template, template tag. Ở phần tiếp theo này chúng ta sẽ áp dụng vào để viết một theme đơn giản cho website WordPress của chúng ta. Trước khi bắt tay vào viết code cho các template của trang web chúng ...

Ở phần hai của bài tìm hiểu về WP chúng ta đã tìm hiểu và tạo được cấu trúc theme cùng với các template, template tag. Ở phần tiếp theo này chúng ta sẽ áp dụng vào để viết một theme đơn giản cho website WordPress của chúng ta.

Trước khi bắt tay vào viết code cho các template của trang web chúng ta sẽ tiến hành thiết lập các tham số, các hằng dữ liệu cho theme mà chúng ta sắp sửa viết bằng cách khai báo, viết các hàm cần thiết trong tệp functions.php

1.Thiết lập các tham số cho theme trong functions.php

    <?php
      /**
      @ Thiết lập các hằng dữ liệu quan trọng
      @ THEME_URL = get_stylesheet_directory() - đường dẫn tới thư mục theme
      @ CORE = thư mục /core của theme, chứa các file nguồn quan trọng.
      **/
      define( 'THEME_URL', get_stylesheet_directory() );
      define( 'CORE', THEME_URL . '/core' );

      /**
      @ Load file /core/init.php
      @ Đây là file cấu hình ban đầu của theme mà sẽ không nên được thay đổi sau này.
      **/

      require_once( CORE . '/init.php' );

      /**
      @ Thiết lập $content_awidth để khai báo kích thước chiều rộng của nội dung
      **/
      if ( ! isset( $content_awidth ) ) {
            /*
             * Nếu biến $content_awidth chưa có dữ liệu thì gán giá trị cho nó
             */
            $content_awidth = 620;
       }

      /**
      @ Thiết lập các chức năng sẽ được theme hỗ trợ
      **/
      if ( ! function_exists( 'setting_up_theme' ) ) {
            /*
             * Nếu chưa có hàm setting_up_theme() thì sẽ tạo mới hàm đó
             */
            function setting_up_theme() {
                    /*
                     * Thiết lập theme có thể chuyển đổi ngôn ngữ được
                     */
                    $language_folder = THEME_URL . '/languages';
                    load_theme_textdomain( 'expamle', $language_folder );

                    /*
                     * Tự chèn RSS Feed links trong <head>
                     */
                    add_theme_support( 'automatic-feed-links' );

                    /*
                     * Thêm chức năng post thumbnail - hình ảnh đại diện cho bài post.
                     */
                    add_theme_support( 'post-thumbnails' );

                    /*
                     * Thêm chức năng title-tag để tự thêm <title>
                     */
                    add_theme_support( 'title-tag' );

                    /*
                     * Thêm chức năng post format nếu ta muốn tạo ra nhiều post có format khác nhau để thuận tiện cho phân loại sau này.
                     */
                    add_theme_support( 'post-formats',
                            array(
                                    'video',
                                    'image',
                                    'audio',
                                    'gallery'
                            )
                     );

                    /*
                     * Thêm chức năng custom background
                     */
                    $default_background = array(
                            'default-color' => '#e8e8e8',
                    );
                    add_theme_support( 'custom-background', $default_background );

                    /*
                     * Tạo menu cho theme
                     */
                     register_nav_menu ( 'primary-menu', __('Primary Menu', 'example') );

                    /*
                     * Tạo sidebar cho theme
                     */
                     $sidebar = array(
                        'name' => __('Main Sidebar', 'example'),
                        'id' => 'main-sidebar',
                        'description' => 'Main sidebar for example theme',
                        'class' => 'main-sidebar',
                        'before_title' => '<h3 class="widgettitle">',
                        'after_sidebar' => '</h3>'
                     );
                     register_sidebar( $sidebar );
            }
            add_action ( 'init', 'setting_up_theme' );
      }
    ?>

Ở cấu trúc theme chúng ta sẽ phải tạo thêm thư mục core trong đó chứa file init.php. Tệp này giúp chúng ta bổ sung các tham số khởi tạo, tùy biến cho thêm sau đó có thể thay đổi một cách dễ dàng.

2.Viết code cho phần template header.php

Tại file này, chúng ta sẽ khai báo các thẻ HTML cần thiết mà trong một tài liệu HTML chuẩn đều có như <html>, <head>, <body>,….và nhất là phần thẻ <head> là phần quan trọng nhất. Chúng ta cũng sẽ viết thêm code hiển thị tên website và menu để vào file header.php này vì các thành phần đó chúng ta đều muốn nó hiển thị trong tất cả mọi trang.

<!DOCTYPE html>
 
 

<head>
        <meta charset="<?php bloginfo( 'charset' ); ?>" />
        <link rel="profile" href="http://gmgp.org/xfn/11" />
        <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />

        <?php wp_head(); ?>
</head>

<body <?php body_class(); ?> >  
        <div id="container">
              <header id="header">
                   <?php example_logo(); ?>
                   <?php example_menu( 'primary-menu' ); ?>
              </header>

Ở trên ta có sử dụng wp_head(), đây là cái hook để giúp WordPress hiểu được đây là khu vực thẻ <head> của theme, để nó có thể tự thêm các thành phần cần thiết lên, cũng như các plugin khác có muốn can thiệp vào khu vực này thì cũng sẽ dò qua hook wp_head(). Ở trên chúng ta có định nghĩa hai hàm để thêm logo và menu cho phần body của website. Hai hàm này sẽ được đặt trong tệp functions.php. Như vậy tệp functions.php của thêm ngoài định nghĩa các tham số cho theme nó còn dùng để ta định nghĩa các hàm, sử dụng các hàm đó để sinh ra các thành phần html cho theme mà không cần viết trực tiếp code hmtl hoặc lặp đi lặp lại code đó nhiều lần.

/**
@ Thiết lập hàm hiển thị logo
@ example_logo()
**/
if ( ! function_exists( 'example_logo' ) ) {
    function example_logo() {?>
    <div class="logo">

        <div class="site-name">
            <?php if ( is_home() ) {
                printf(
                    '<h1><a href="%1$s" title="%2$s">%3$s</a></h1>',
                    get_bloginfo( 'url' ),
                    get_bloginfo( 'description' ),
                    get_bloginfo( 'sitename' )
                    );
            } else {
                printf(
                    '</p><a href="%1$s" title="%2$s">%3$s</a></p>',
                    get_bloginfo( 'url' ),
                    get_bloginfo( 'description' ),
                    get_bloginfo( 'sitename' )
                    );
                } // endif ?>
            </div>
            <div class="site-description"><?php bloginfo( 'description' ); ?></div>

        </div>
        <?php }
    }

/**
@ Thiết lập hàm hiển thị menu
@ example_menu( $slug )
**/
if ( ! function_exists( 'example_menu' ) ) {
    function example_menu( $slug ) {
        $menu = array(
            'theme_location' => $slug,
            'container' => 'nav',
            'container_class' => $slug,
            );
        wp_nav_menu( $menu );
    }
}

Khi định nghĩa xong hàm example_menu trên, ta đã có thể thêm menu cho theme của chúng ta bằng cách vào Appearance -> Menus.

3.Viết code cho template footer.php

Ở file header.php mới chỉ có thẻ mở mà chưa đóng thì nó sẽ được đóng ở file footer.php. Chẳng hạn như trong file header.php, chúng ta có mở thẻ <body>, <html> và thẻ <div class=”container”> đều chưa được đóng, vậy thì bây giờ chúng ta sẽ viết thẻ đóng cho nó ở file footer.php kèm cái hook wp_footer() Cũng giống như wp_head(), hook wp_footer() là giúp cho WordPress nhận ra đâu là phần footer của trang web để một số plugin có thể hook vào và làm được những việc nó muốn.

<footer id="footer">
                <div class="copyright">
                        © <?php echo date('Y'); ?> <?php bloginfo( 'sitename' ); ?>. <?php _e('All rights reserved', 'example'); ?>. <?php _e('This website is proundly to use WordPress', 'example'); ?>
                </div>
        </footer>
        </div>  
        <?php wp_footer(); ?>
</body>  
</html>  

4.Viết code cho template index.php

Tiếp tục phần này, chúng ta sẽ viết code cho file index.php. Đây là file mà nó sẽ làm trang chủ mặc định cho WordPress và thường là ở phần này chúng ta sẽ viết code hiển thị danh sách các post mới nhất đã được tạo trên website. Bây giờ hãy mở file index.php ra, chúng ta sẽ chèn header và footer vào trang index bằng cách sử dụng hai template tag get_header() và get_footer().

<?php get_header(); ?>
 <div class="content">

        <section id="main-content">
            <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
                <?php get_template_part( 'content', get_post_format() ); ?>
            <?php endwhile; ?>
            <?php example_pagination(); ?>
            <?php else : ?>
                <?php get_template_part( 'content', 'none' ); ?>
            <?php endif; ?>
        </section>
        <section id="sidebar">
            //template tag để hiển thị side bar mà chúng ta đã khai báo ở functions.php
            <?php get_sidebar(); ?>
        </section>
</div>
<?php get_footer(); ?>

Đoạn code trên chúng ta chia body website làm hai phần một phần hiển thị nội dung các bài post (main-content). Một phần là side bar hiển thị các thành phần side bar mà chúng ta tùy biến. Ở phần main-content, ta sử dụng template tag get_template_part() để chèn template hiển thị nội dung của bài post trong vòng lặp. Ngoài ra ta cũng định nghĩa một hàm giúp hiển thị phân trang (đối với website có nhiều post chúng ta không thể hiển thị hết các post trong một trang được), hàm này được định nghĩa trong functions.php

/**
@ Tạo hàm phân trang cho index, archive.
@ Hàm này sẽ hiển thị liên kết phân trang theo dạng chữ: Newer Posts & Older Posts
@ example_pagination()
**/
if ( ! function_exists( 'example_pagination' ) ) {
    function example_pagination() {
        /*
         * Không hiển thị phân trang nếu trang đó có ít hơn 2 trang
         */
        if ( $GLOBALS['wp_query']->max_num_pages < 2 ) {
            return ';
        }
        ?>

        <nav class="pagination" role="navigation">
            <?php if ( get_next_post_link() ) : ?>
                <div class="prev"><?php next_posts_link( __('Older Posts', 'example') ); ?></div>
            <?php endif; ?>

            <?php if ( get_previous_post_link() ) : ?>
                <div class="next"><?php previous_posts_link( __('Newer Posts', 'example') ); ?></div>
            <?php endif; ?>

        </nav><?php
    }
}

5.Viết code hiển cho template content.php

Template này dùng đẻ hiển thị nội dung bài post.

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <div class="entry-thumbnail">
                <?php example_thumbnail('thumbnail'); ?>
        </div>
        <header class="entry-header">
                <?php example_entry_header(); ?>
                <?php example_entry_meta() ?>
        </header>
        <div class="entry-content">
                <?php example_entry_content(); ?>
                <?php ( is_single() ? example_entry_tag() : ' ); ?>
        </div>
</article>

Ở trên ta có sử dụng các hàm example_thumbnail để hiển thị ảnh đại diện cho post nếu post đó được người dùng upload ảnh đại diện. Hàm example_entry_header(), example_entry_meta(), example_entry_content(), example_entry_tag() để hiện thị các thông tin về post như tác giả, nội dung, các tag được gắn cho bài post. Tất nhiên các hàm này phải được khai báo trong functions.php

/**
@ Hàm hiển thị ảnh thumbnail của post.
@ Ảnh thumbnail sẽ không được hiển thị trong trang single
@ Nhưng sẽ hiển thị trong single nếu post đó có format là Image
@ example_thumbnail( $size )
**/
if ( ! function_exists( 'example_thumbnail' ) ) {
  function example_thumbnail( $size ) {
    // Chỉ hiển thumbnail với post không có mật khẩu
    if ( ! is_single() &&  has_post_thumbnail()  && ! post_password_required() || has_post_format( 'image' ) ) : ?>
      <figure class="post-thumbnail"><?php the_post_thumbnail( $size ); ?></figure><?php
    endif;
  }
}

/**
@ Hàm hiển thị tiêu đề của post trong .entry-header
@ Tiêu đề của post sẽ là nằm trong thẻ <h1> ở trang single
@ Còn ở trang chủ và trang lưu trữ, nó sẽ là thẻ <h2>
@ example_entry_header()
**/
if ( ! function_exists( 'example_entry_header' ) ) {
  function example_entry_header() {
    if ( is_single() ) : ?>

      <h1 class="entry-title">
        <a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php the_title_attribute(); ?>">
          <?php the_title(); ?>
        </a>
      </h1>
    <?php else : ?>
      <h2 class="entry-title">
        <a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php the_title_attribute(); ?>">
          <?php the_title(); ?>
        </a>
      </h2><?php

    endif;
  }
}

/**
@ Hàm hiển thị thông tin của post (Post Meta)
@ example_entry_meta()
**/
if( ! function_exists( 'example_entry_meta' ) ) {
  function example_entry_meta() {
    if ( ! is_page() ) :
      echo '<div class="entry-meta">';

        // Hiển thị tên tác giả, tên category và ngày tháng đăng bài
        printf( __('<span class="author">Posted by %1$s</span>', 'example'),
          get_the_author() );

        printf( __('<span class="date-published"> at %1$s</span>', 'example'),
          get_the_date() );

        printf( __('<span class="category"> in %1$s</span>', 'example'),
          get_the_category_list( ', ' ) );

        // Hiển thị số đếm lượt bình luận
        if ( comments_open() ) :
          echo ' <span class="meta-reply">';
            comments_popup_link(
              __('Leave a comment', 'example'),
              __('One comment', 'example'),
              __('% comments', 'example'),
              __('Read all comments', 'example')
             );
          echo '</span>';
        endif;
      echo '</div>';
    endif;
  }
}

/*
 * Thêm chữ Read More vào excerpt
 */
function example_readmore() {
  return '...<a class="read-more" href="'. get_permalink( get_the_ID() ) . '">' . __('Read More', 'example') . '</a>';
}
add_filter( 'excerpt_more', 'example_readmore' );

  /**
  @ Hàm hiển thị nội dung của post type
  @ Hàm này sẽ hiển thị đoạn rút gọn của post ngoài trang chủ (the_excerpt)
  @ Nhưng nó sẽ hiển thị toàn bộ nội dung của post ở trang single (the_content)
  @ example_entry_content()
  **/
  if ( ! function_exists( 'example_entry_content' ) ) {
    function example_entry_content() {

      if ( ! is_single() ) :
        the_excerpt();
      else :
        the_content();

        /*
         * Code hiển thị phân trang trong post type
         */
        $link_pages = array(
          'before' => __('<p>Page:', 'example'),
          'after' => '</p>',
          'nextpagelink'     => __( 'Next page', 'example' ),
          'previouspagelink' => __( 'Previous page', 'example' )
        );
        wp_link_pages( $link_pages );
      endif;

    }
  }

  /**
@ Hàm hiển thị tag của post
@ example_entry_tag()
**/
if ( ! function_exists( 'example_entry_tag' ) ) {
  function example_entry_tag() {
    if ( has_tag() ) :
      echo '<div class="entry-tag">';
      printf( __('Tagged in %1$s', 'example'), get_the_tag_list( ', ', ' ) );
      echo '</div>';
    endif;
  }
}

6.Viết code cho template single.php và page.php

Hai template này được dùng để hiển thị nội dung chi tiết cho post (single.php) và page (page.php). Hai template này sẽ tương tự như index.php, tuy nhiên nó sẽ không sử dụng hàm hiển thị phân trang example_pagination (vì nó chỉ hiển thị nội dung của một post hoặc page mà thôi) và ngoài ra nó còn có sử phần hiển thị comment về post hoặc page bằng việc sử dụng template tag comments_template().

Như vậy chúng ta viết code được cơ bản các template cần thiết để hiển thị các post và page của theme. Phần sau của bài báo cáo chúng ta sẽ chèn css vào để theme chúng ta được đẹp hơn, ngoài ra ta cũng bổ sung theme side bar, các code cho các template về phân loại (archive.php), lưu trữ (category.php) và 404 (404.php).

1.https://codex.wordpress.org

2.http://thachpham.com/

0