Thứ Tư, 21 tháng 12, 2016

Tạo Theme Options, tích hợp khu vực tùy chỉnh theme wordpress cho người dùng

Then use the post body as the schema.org description, for good G+/FB snippeting. -->
Theme Option cho phép người dùng quản lý, thay đổi logo, kiểu header, kiểu footer, màu chữ, ...website của mình trong website viết bằng mã nguồn wordpress.
Bước 1. <a href="https://thachpham.com/wordpress/wordpress-development/lap-trinh-theme-wordpress-them-chuc-nang-theme-options.html">Tích hợp TGM Plugin Activation</a>
Sau đó mở file init.php trong cùng thư mục lên và thêm đoạn này vào:
<?php
        /* Plugin Activation */
        require_once dirname( __FILE__ ) . '/class-tgm-plugin-activation.php';
Sau đó tạo thêm một file tên là plugins.php trong cùng thư mục core và thêm đoạn này vào:
<?php
function thachpham_plugin_activation() {

        // Khai bao plugin can cai dat
        $plugins = array(
                array(
                        'name' => 'Redux Framework',
                        'slug' => 'redux-framework',
                        'required' => true
                )
        );

        // Thiet lap TGM
        $configs = array(
                'menu' => 'tp_plugin_install',
                'has_notice' => true,
                'dismissable' => false,
                'is_automatic' => true
        );
        tgmpa( $plugins, $configs );

}
add_action('tgmpa_register', 'thachpham_plugin_activation');
?>
Và chèn thêm đoạn sau vào file init.php để file plugins.php này được gọi ra.
require_once dirname( __FILE__ ) . '/plugins.php';
Bước 2:
Tuy nhiên chúng ta sẽ không sử dụng cái sample config file của Redux Framework vì nó chứa rất nhiều option fields mà bạn không cần dùng tới, sẽ mất công sửa lại mà chúng ta sẽ tự tạo ra một file option riêng chứa các thiết lập riêng cần thiết.

Nếu bạn muốn tự tìm hiểu về các đoạn code của Redux Framework, hãy mở file sample-config.php trong thư mục plugins Redux Framework để xem hoặc file barebones-config.php để xem cấu trúc một file tạo theme options hoàn chỉnh từ framework này.

Bước 3. Lên kế hoạch tạo Theme Options

Trước khi tiến hành viết code tạo các tùy chọn trong Theme Options, chúng ta cần nên biết rõ sẽ tạo ra những tùy chọn nào để người dùng sử dụng. Trong khuôn khổ bài này, mình sẽ lấy ví dụ các tùy chọn cơ bản trong theme như:

Bật/tắt chức năng sử dụng ảnh làm logo.
Sửa/xóa ảnh làm logo.
Thay đổi màu sắc liên kết trong theme.
Thêm font chữ từ Google Fonts.
Bước 4. Viết code tạo tùy chọn cho Theme Options

4.1) Tạo file chứa code các tùy chọn (options.php)

Bây giờ bạn hãy vào thư mục /themes/thachpham/core/ và tạo một file mang tên options.php. Sau đó mở file init.php ra và chèn đoạn sau vào để kích hoạt file options.php để nó hoạt động:
/* Theme Options */
require_once dirname( __FILE__ ) . '/options.php';
Trong options.php, chúng ta khai báo một class để chứa các options như sau:

<?php
        if ( ! class_exists( 'ThachPham_Theme_Options' ) ) {

                /* class ThachPham_Theme_Options sẽ chứa toàn bộ code tạo options trong theme từ Redux Framework */
      class ThachPham_Theme_Options {

      }
                  /* Kích hoạt class ThachPham_Theme_Options vào Redux Framework */
        global $reduxConfig;
        $reduxConfig = new ThachPham_Theme_Options();
      }
Và từ bây giờ, chúng ta sẽ viết code tạo từng khu vực options và từng options vào bên trong class ThachPham_Theme_Options.

4.2) Khai báo các đoạn code cần thiết vào class ThachPham_Theme_Options.

Tất cả các code dưới đây đều phải viết vào bên trong cặp class ThachPham_Theme_Options {}.

Trước tiên, bạn phải khai báo lại các biến toàn cục mà Redux Framework có sử dụng để chúng ta có thể tái sử dụng lại.
                        /* Tái tạo các biến có trong Redux Framework */
public $args = array();
public $sections = array();
public $theme;
public $ReduxFramework;
Kế tiếp là thêm code để Redux Framework được kích hoạt.
/* Load Redux Framework */
 public function __construct() {

     if ( ! class_exists( 'ReduxFramework' ) ) {
         return;
     }

     // This is needed. Bah WordPress bugs.  <img draggable="false" class="emoji" alt="😉" src="https://s.w.org/images/core/emoji/2.2.1/svg/1f609.svg">
     if ( true == Redux_Helpers::isTheme( __FILE__ ) ) {
         $this->initSettings();
     } else {
         add_action( 'plugins_loaded', array( $this, 'initSettings' ), 10 );
     }

 }
Thêm nữa, trong class ReduxFramework nó có một số phương thức mà nếu bạn muốn sử dụng thì sẽ cần phải khai báo vào một phương thức khác tên là initSettings. Chúng ta có đoạn code khai báo các phương thức cần sử dụng như sau:
/**
Thiết lập các method muốn sử dụng
                        Method nào được khai báo trong này thì cũng phải được sử dụng
                    **/
public function initSettings() {

    // Set the default arguments
    $this->setArguments();

    // Set a few help tabs so you can see how it's done
    $this->setHelpTabs();

    // Create the sections and fields
    $this->setSections();

    if ( ! isset( $this->args['opt_name'] ) ) { // No errors please
        return;
    }

    $this->ReduxFramework = new ReduxFramework( $this->sections, $this->args );
}
Nghĩa là chúng ta sẽ cần sử dụng 3 phương thức là:

setArguments: Phương thức này sẽ thiết lập một số tùy chọn cho cái Theme Options.
setHelpTabs: Phương thức này để tạo mục hướng dẫn ngay bên trong phần hiển thị Theme Options.
setSections: Đây là phương thức quan trọng nhất, dùng để chia phân mục các tùy chọn trong Theme Options, và chúng ta cũng sẽ khai báo các field tùy chọn bên trong phương thức này.
Ok, bây giờ chúng ta sẽ code cho từng phương thức một.

4.3) Viết code cho phương thức initSettings

Như mình đã nói ở trên rằng phương thức này sẽ được dùng để khai báo một số tùy chọn chung chung cho khu vực Theme Options, chúng ta có đoạn code sau (nhớ là đặt bên trong class ThachPham_Theme_Options {}):
/**
Thiết lập cho method setAgruments
Method này sẽ chứa các thiết lập cơ bản cho trang Options Framework như tên menu chẳng hạn
**/
public function setArguments() {
    $theme = wp_get_theme(); // Lưu các đối tượng trả về bởi hàm wp_get_theme() vào biến $theme để làm một số việc tùy thích.
    $this->args = array(
            // Các thiết lập cho trang Options
            'opt_name'  => 'tp_options', // Tên biến trả dữ liệu của từng options, ví dụ: tp_options['field_1']
            'display_name' => $theme->get( 'Name' ), // Thiết lập tên theme hiển thị trong Theme Options
            'menu_type'          => 'menu',
        'allow_sub_menu'     => true,
        'menu_title'         => __( 'TP Theme Options', 'thachpham' ),
        'page_title'         => __( 'TP Theme Options', 'thachpham' ),
        'dev_mode' => false,
        'customizer' => true,
        'menu_icon' => '', // Đường dẫn icon của menu option
        // Chức năng Hint tạo dấu chấm hỏi ở mỗi option để hướng dẫn người dùng */
        'hints'              => array(
            'icon'          => 'icon-question-sign',
            'icon_position' => 'right',
            'icon_color'    => 'lightgray',
            'icon_size'     => 'normal',
            'tip_style'     => array(
                'color'   => 'light',
                'shadow'  => true,
                'rounded' => false,
                'style'   => '',
            ),
            'tip_position'  => array(
                'my' => 'top left',
                'at' => 'bottom right',
            ),
            'tip_effect'    => array(
                'show' => array(
                    'effect'   => 'slide',
                    'duration' => '500',
                    'event'    => 'mouseover',
                ),
                'hide' => array(
                    'effect'   => 'slide',
                    'duration' => '500',
                    'event'    => 'click mouseleave',
                ),
            ),
        ) // end Hints
    );
Ở mỗi đoạn mình đã có viết chú thích rồi nên bạn có thể đọc bên trong đó nhé.

4.4) Viết code cho phương thức setHelpTabs:

Help Tabs là tính năng rất hữu dụng để bạn viết các đoạn hướng dẫn và người đùng có thể nhìn thấy tại nút Help nằm bên phải góc trên trong trang Theme Options:
/**
Thiết lập từng phần trong khu vực Theme Options
mỗi section được xem như là một phân vùng các tùy chọn
Trong mỗi section có thể sẽ chứa nhiều field
**/
public function setSections() {

    // Home Section
    $this->sections[] = array(
        'title'  => __( 'Header', 'thachpham' ),
        'desc'   => __( 'All of settings for header on this theme.', 'thachpham' ),
        'icon'   => 'el-icon-home',
        'fields' => array()
    ); // end section

}
Ngay tại code trên, từ đoạn //Home Section đến // end section là một code tạo một khu vực tùy chọn, trong đó có các tham số sau:

title: Tên của section
desc: Mô tả của section
icon: đường dẫn hoặc tên của icon (trong bộ Elusive Icon http://elusiveicons.com/icons/).
fields: Các đoạn code tạo tùy chọn cho section này
Ngay sau khi xong đoạn code trên, bạn đã có thể vào Dashboard để xem phần Theme Options đã được hiển thị ra rồi.

laptrinhtheme-themeoptions-03

Bây giờ ngay tại tham số fields trong đoạn tạo section trên, chúng ta sẽ tạo ra hai options cho tùy chọn bật chức năng hiển thị logo là ảnh và field upload ảnh làm logo lên. Chúng ta có thêm code như sau vào tham số fields:
'fields' => array(
    // Mỗi array là một field
    array(
        'id'       => 'logo-on',
        'type'     => 'switch',
        'title'    => __( 'Enable Image Logo', 'thachpham' ),
        'compiler' => 'bool', // Trả về giá trị kiểu true/false (boolean)
        'desc'     => __( 'Do you want to use image as a logo?', 'thachpham' ),
        'on' => __( 'Enabled', 'thachpham' ),
        'off' => __('Disabled')
    ),

    array(
        'id'       => 'logo-image',
        'type'     => 'media',
        'title'    => __( 'Logo Image', 'thachpham' ),
        'desc'     => __( 'Image that you want to use as logo', 'thachpham' ),
    ),
)
Ở đoạn trên, rõ ràng mình có hai mảng array bên trong tham số fields, như vậy điều này tương đương với ta có 2 options. Trong code tạo options trên, các tham số này là của từng loại field trong ReduxFramework nên tốt hơn hết bạn xem các tùy chọn của từng loại fields trong ReduxFramework tại đây.

Trong các đoạn code tạo options, bạn lưu ý nhất là tham số id, đó chính là tên của mỗi field để sau này chúng ta có thể sẽ gọi giá trị của nó ra ngoài theme theo kiểu $opt_name['field_id']. Biến $opt_name chính là tham số opt_name trong phương thức setArguments().

Sau khi đặt các đoạn code tạo option kia vào section Header mà ta đã tạo ở trên, khi vào Theme Options ta sẽ thấy như thế này:

laptrinhtheme-themeoptions-04

Bây giờ để có thể mang dữ liệu ra bên ngoài, trước tiên bạn hãy vào Theme Options và thử chọn các tùy chọn bất kỳ để nó gán giá trị vào database, sau đó ấn Save Changes lại để lưu.

Như bạn biết thì trong phương thức setArgrument ta đã sử dụng tham số opt_name để khai báo một biến để chứa các dữ liệu mảng cho mỗi option. Trong bài này thì mình đã gán cho nó với tên là tp_options, vậy thì chúng ta phải đặt biến này thành dạng global ở file mà chúng ta muốn gọi giá trị ra như thế này:
<?php
global $tp_options;
echo '<pre>';
print_r( $tp_options );
echo '</pre>';
?>
Bạn có thể đặt thử đoạn trên vào đầu file header.php để chúng ta xem các giá trị trong options:

laptrinhtheme-themeoptions-05

Dựa theo giá trị debug đó, chúng ta có thể lấy giá trị dựa theo tên của từng key trong mảng đó là được.

Bây giờ bạn mở file functions.php lên, tìm đến hàm thachpham_logo() như thế này:
if (!function_exists('thachpham_header')) {
        function thachpham_header() { ?>
                <div class="site-name">
                        <?php
                                global $tp_options;

                                if( $tp_options['logo-on'] == 0 ) :
                        ?>
                                <?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') );
                                        }
                                ?>

                        <?php
                                else :
                        ?>
                                <img src="<?php echo $tp_options['logo-image']['url']; ?>" />
                <?php endif; ?>
                </div>
                <div class="site-description"><?php bloginfo('description'); ?></div><?php
        }
}
Việc của chúng ta cần làm là thêm đoạn code kiểm tra cái tùy chọn bật logo bằng hình ảnh, sau đó thêm đoạn code hiển thị logo nếu cái tùy chọn Enable Logo Image đang On (giá trị là 1):

/**
@ Thiết lập hàm hiển thị logo
@ thachpham_logo()
**/
if ( ! function_exists( 'thachpham_logo' ) ) {
  function thachpham_logo() {?>
    <?php
      global $tp_options;
    ?>

    <?php if ( $tp_options['logo-on'] == 1 ) : ?>

      <div class="logo">
        <img src="<?php echo $tp_options['logo-image']['url']; ?>">
      </div>

    <?php else : ?>

      <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(
              '<a href="%1$s" title="%2$s">%3$s</a>',
              get_bloginfo( 'url' ),
              get_bloginfo( 'description' ),
              get_bloginfo( 'sitename' )
            );
          } // endif ?>
        </div>
        <div class="site-description"><?php bloginfo( 'description' ); ?></div>

      </div>

      <?php endif;
  }
}
Giờ thì bạn có thể thử vào Theme Options và thiết lập bật chức năng hiển thị logo lên, đồng thời upload ảnh muốn làm logo và ta có kết quả sau khi bật:

laptrinhtheme-themeoptions-06

4.6) Tiếp tục tạo thêm một section cho Theme Options:

Ở phần này, chúng ta sẽ tạo thêm một section mang tên Typography trong phần Theme Options, tại đây chúng ta sẽ cho phép người dùng thiết lập font chữ và màu chữ, màu liên kết:

Ngay tại phương thức setSections, chúng ta sẽ thêm một section mới như sau:
'fields' => array(
    // Main typography
    array(
        'id' => 'typo-main',
        'type' => 'typography',
        'title' => 'Main Typography',
        'output' => array( 'body' ),
        'text-transform' => true,
        'default' => array(
            'font-size' => '14px',
            'font-family' => 'Helvetica Neue, Arial, sans-serif',
            'font-color' => '#333333',
        ),
    ),
)
Đồng thời, bạn phải khai báo thêm Google API Key để cái Google Font có thể làm việc được. Hãy thêm tham số này vào phương thức setArguments:
'google_api_key' => 'XXXXXXXXXXX',
Trong đó, XXX là Google API Key của bạn, bạn hãy xem thêm hướng dẫn lấy API Key tại https://developers.google.com/fonts/docs/developer_api#Auth. Hoặc bạn có thể sử dụng tạm AIzaSyAs0iVWrG4E_1bG244-z4HRKJSkg7JVrVQ để test.
Ngay đoạn fields ở trên, mình có các tham số cơ bản trong một options, tuy nhiên các bạn nên lưu ý tham số ouput. Tham số ouput nghĩa là chúng ta sẽ khai báo vùng chọn để nó tự tạo ra CSS, ví dụ như trên mình khai báo vùng chọn body thì nó sẽ tự tạo ra CSS với kiểu body {....} để hiển thị các giá trị.
Tham số default là chúng ta sẽ khai báo các giá trị mặc định nếu như typography không được chọn. Như vậy, bạn hãy vào file style.css, tìm đến vùng chọn body và xóa các giá trị CSS liên quan đến tham số default để nó khỏi xung đột nhé.
Kết quả sau khi tạo xong option:
laptrinhtheme-themeoptions-08
Hãy thử chọn các tùy chọn mà bạn thích rồi ấn Save lại. Bây giờ khi xem source của website, bạn sẽ thấy các tùy chọn đã được tạo ra như một đoạn CSS với vùng chọn là tham số output.
laptrinhtheme-themeoptions-09
Mình nhắc lại là nếu bạn tạo tùy chọn Typography cho vùng chọn nào thì hãy đảm bảo rằng bạn hãy xóa hết các đoạn CSS liên quan đến vùng chọn đó trong file style.css vì nếu nó vẫn còn thì các CSS trong file style.css sẽ được ưu tiên.
Nguồn: Thachpham.com

Không có nhận xét nào:

Đăng nhận xét