Thêm thuộc tính trang Metabox và mẫu trang vào trang chỉnh sửa bài viết?


14

( Lưu ý của người kiểm duyệt: Tiêu đề ban đầu là "Làm cách nào tôi có thể thêm bộ chọn" Thuộc tính trang "và / hoặc" Thuộc tính trang> Mẫu "vào trình chỉnh sửa POSTS")

WP hiện chỉ cho phép gán "mẫu" cho Trang (tức là post_type=='page') Tôi cũng muốn mở rộng chức năng này cho Bài viết (ví dụ post_type=='post'.)

Làm cách nào tôi có thể thêm hộp meta "Thuộc tính trang" và cụ thể hơn là trình chuyển đổi mẫu vào trình chỉnh sửa bài viết?

Tôi giả sử đây là mã tôi sẽ đặt trong functions.phpchủ đề của mình.

CẬP NHẬT: Tôi đã quản lý để thêm trình đơn kéo xuống mẫu mã hóa cứng vào trình chỉnh sửa bài đăng của mình, chỉ bằng cách thêm hộp chọn html vào hộp tùy chọn meta tùy chỉnh hiện có của tôi. Đây là mã tôi đang sử dụng cho ...

add_meta_box('categorydiv2', __('Post Options'), 'post_categories_meta_box_modified', 'post', 'side', 'high');

Và đây là chức năng ghi ra các tùy chọn và hộp chọn mẫu ...

//adds the custom categories box
function post_categories_meta_box_modified() {
    global $post;
    if( get_post_meta($post->ID, '_noindex', true) ) $noindexChecked = " checked='checked'";
    if( get_post_meta($post->ID, '_nofollow', true) ) $nofollowChecked = " checked='checked'";
?>
<div id="categories-all" class="ui-tabs-panel">
    <ul id="categorychecklist" class="list:category categorychecklist form-no-clear">
        <li id='noIndex' class="popular-category"><label class="selectit"><input value="noIndex" type="checkbox" name="chk_noIndex" id="chk_noIndex"<?php echo $noindexChecked ?> /> noindex</label></li> 
        <li id='noFollow' class="popular-category"><label class="selectit"><input value="noFollow" type="checkbox" name="chk_noFollow" id="chk_noFollow"<?php echo $nofollowChecked ?> /> nofollow</label></li>
    </ul>

    <p><strong>Template</strong></p> 
    <label class="screen-reader-text" for="page_template">Post Template</label><select name="page_template" id="page_template"> 
    <option value='default'>Default Template</option> 
    <option value='template-wide.php' >No Sidebar</option>
    <option value='template-salespage.php' >Salespage</option>
    </select>
</div>
<?php
}

Và cuối cùng, mã để nắm bắt các giá trị đã chọn khi lưu ...

function save_post_categories_meta($post_id) {
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
    $noIndex = $_POST['chk_noIndex'];
    $noFollow = $_POST['chk_noFollow'];
    update_post_meta( $post_id, '_noindex', $noIndex );
    update_post_meta( $post_id, '_nofollow', $noFollow );
    return $post_id;
}

Bây giờ, tôi tin rằng tất cả những gì còn lại là (1) chụp mẫu đã chọn và thêm nó vào meta bài đăng cho bài đăng này và (2) sửa đổi index.php và single.php để nó sử dụng mẫu đã chọn.


@Scott B : Vâng, tôi đã viết toàn bộ câu trả lời của mình trước khi tôi thấy rằng bạn cũng đang làm việc với nó, và có vẻ như bạn đã đưa nó theo một hướng khác biệt mà câu hỏi ban đầu của bạn không có theo dõi và không có tùy chọn chỉ mục. Hy vọng những gì tôi đã làm vẫn có giá trị cho bạn. Nếu không, có lẽ nó sẽ giúp người khác.
MikeSchinkel

Đúng, bạn đã trả lời câu hỏi. Tôi đã thực hiện một chút khác biệt khi tôi nhận ra rằng tôi không cần phân tích thư mục và có thể mã hóa các giá trị cho các mẫu cụ thể của mình. Tôi vẫn có thể cần mượn một số mã của bạn để thực sự có được WP để sử dụng đúng mẫu được gán cho bài đăng.
Scott B

Câu trả lời:


12

Ghét phải là người mang tin xấu nhưng WordPress đã mã hóa chức năng Mẫu trang thành loại bài đăng "trang" , ít nhất là trong phiên bản 3.0 (có thể thay đổi trong các phiên bản trong tương lai nhưng không có sáng kiến ​​cụ thể nào tôi biết để thay đổi nó Tuy nhiên, đây là một trong số rất ít lần tôi đấu tranh để tìm ra cách khắc phục thứ gì đó mà không hack lõi.)

Giải pháp tôi đã đưa ra là về cơ bản sao chép mã có liên quan từ lõi WordPress và sửa đổi nó theo nhu cầu của chúng tôi. Dưới đây là các bước (số dòng từ v3.0.1):

  1. Sao chép page_attributes_meta_box()chức năng từ dòng 535 /wp-admin/includes/meta-boxes.phpvà sửa đổi cho phù hợp.

  2. Mã hóa một add_meta_boxescái móc để thêm metabox được tạo trong # 1.

  3. Sao chép get_page_templates()chức năng từ dòng 166 /wp-admin/includes/theme.php và sửa đổi cho phù hợp.

  4. Sao chép page_template_dropdown()chức năng từ dòng 2550 /wp-admin/includes/template.phpvà sửa đổi cho phù hợp.

  5. Thêm một mẫu bài viết vào chủ đề của bạn.

  6. Mã một save_posthook để cho phép lưu trữ tên tệp bài đăng khi lưu.

  7. Mã một single_templatehook để cho phép tải mẫu bài đăng cho các bài đăng liên quan.

Bây giờ với nó!


1. Sao chép page_attributes_meta_box()chức năng

Là bước đầu tiên của chúng tôi, bạn cần sao chép page_attributes_meta_box()chức năng từ dòng 535 /wp-admin/includes/meta-boxes.phpvà tôi đã chọn đổi tên nó post_template_meta_box(). Vì bạn chỉ yêu cầu các mẫu trang, tôi đã bỏ qua mã để chỉ định một bài đăng gốc và để chỉ định thứ tự làm cho mã đơn giản hơn nhiều. Tôi cũng đã chọn sử dụng postmeta cho việc này thay vì cố gắng sử dụng lại thuộc tính page_templateđối tượng để tránh và sự không tương thích tiềm ẩn gây ra bởi khớp nối không chủ ý. Vì vậy, đây là mã:

function post_template_meta_box($post) {
  if ( 'post' == $post->post_type && 0 != count( get_post_templates() ) ) {
    $template = get_post_meta($post->ID,'_post_template',true);
    ?>
<label class="screen-reader-text" for="post_template"><?php _e('Post Template') ?></label><select name="post_template" id="post_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php post_template_dropdown($template); ?>
</select>
<?php
  } ?>
<?php
}

2. Mã một add_meta_boxescái móc

Bước tiếp theo là thêm metabox bằng add_meta_boxeshook:

add_action('add_meta_boxes','add_post_template_metabox');
function add_post_template_metabox() {
    add_meta_box('postparentdiv', __('Post Template'), 'post_template_meta_box', 'post', 'side', 'core');
}

3. Sao chép get_page_templates()chức năng

Tôi giả định rằng sẽ chỉ có ý nghĩa để phân biệt giữa các mẫu trang và mẫu bài do đó cần một get_post_templates()chức năng dựa trên get_page_templates()dòng 166 của /wp-admin/includes/theme.php. Nhưng thay vì sử dụng Template Name:điểm đánh dấu, mẫu trang nào sử dụng chức năng này sử dụng Post Template:điểm đánh dấu thay vì bạn có thể thấy bên dưới.

Tôi cũng đã lọc ra kiểm tra functions.php (không chắc bao get_page_templates()giờ hoạt động chính xác mà không có điều đó, nhưng bất cứ điều gì!) Và điều duy nhất còn lại là thay đổi các tham chiếu đến từ pageđể postbảo trì dễ đọc trên đường:

function get_post_templates() {
  $themes = get_themes();
  $theme = get_current_theme();
  $templates = $themes[$theme]['Template Files'];
  $post_templates = array();

  if ( is_array( $templates ) ) {
    $base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) );

    foreach ( $templates as $template ) {
      $basename = str_replace($base, '', $template);
      if ($basename != 'functions.php') {
        // don't allow template files in subdirectories
        if ( false !== strpos($basename, '/') )
          continue;

        $template_data = implode( '', file( $template ));

        $name = '';
        if ( preg_match( '|Post Template:(.*)$|mi', $template_data, $name ) )
          $name = _cleanup_header_comment($name[1]);

        if ( !empty( $name ) ) {
          $post_templates[trim( $name )] = $basename;
        }
      }
    }
  }

  return $post_templates;
}

4. Sao chép page_template_dropdown()chức năng

Tương tự sao chép page_template_dropdown()từ dòng 2550 của /wp-admin/includes/template.phpđể tạo post_template_dropdown()và chỉ cần thay đổi nó để gọi get_post_templates()thay thế:

function post_template_dropdown( $default = '' ) {
  $templates = get_post_templates();
  ksort( $templates );
  foreach (array_keys( $templates ) as $template )
    : if ( $default == $templates[$template] )
      $selected = " selected='selected'";
    else
      $selected = '';
  echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>";
  endforeach;
}

5. Thêm một mẫu bài

Bước tiếp theo là thêm một mẫu bài đăng để thử nghiệm. Sử dụng Post Template:điểm đánh dấu được đề cập trong bước 3 sao chép single.phptừ chủ đề của bạn vào single-test.phpvà thêm tiêu đề nhận xét sau ( hãy chắc chắn sửa đổi một cái gì đó single-test.phpđể bạn có thể biết nó đang tải thay vì single.php) :

/**
 * Post Template: My Test Template
 */

Khi bạn đã thực hiện các bước # 1 đến # 5, bạn có thể thấy metabox "Bài mẫu" xuất hiện trên trang biên tập bài đăng của mình:

Metabox trông như thế nào khi được thêm vào WordPress 3.0
(nguồn: mikechinkel.com )

6. Mã một save_postcái móc

Bây giờ bạn đã có trình soạn thảo bình phương, bạn cần phải thực sự lưu tên tệp mẫu trang của mình vào postmeta khi người dùng nhấp vào "Xuất bản". Đây là mã cho điều đó:

add_action('save_post','save_post_template',10,2);
function save_post_template($post_id,$post) {
  if ($post->post_type=='post' && !empty($_POST['post_template']))
    update_post_meta($post->ID,'_post_template',$_POST['post_template']);
}

7. Mã một single_templatecái móc

Và cuối cùng, bạn cần phải thực sự có được WordPress để sử dụng các mẫu bài đăng mới của bạn. Bạn làm điều đó bằng cách móc single_templatevà trả lại tên mẫu mong muốn của bạn cho những bài đăng đã được gán:

add_filter('single_template','get_post_template_for_template_loader');
function get_post_template_for_template_loader($template) {
  global $wp_query;
  $post = $wp_query->get_queried_object();
  if ($post) {
    $post_template = get_post_meta($post->ID,'_post_template',true);
    if (!empty($post_template) && $post_template!='default')
      $template = get_stylesheet_directory() . "/{$post_template}";
  }
  return $template;
}

Và đó là về nó!

LƯU Ý rằng tôi đã không xem xét các loại bài tùy chỉnh , chỉ post_type=='post'. Theo ý kiến ​​của tôi, việc giải quyết các loại bài đăng tùy chỉnh sẽ yêu cầu phân biệt giữa các loại bài đăng khác nhau và trong khi không quá khó khăn, tôi đã không thử điều đó ở đây.


Tuyệt quá! Tôi đã đi ngủ với một mã gần như hoàn chỉnh trong trình soạn thảo của mình với cùng một cách tiếp cận sao chép các chức năng mặc định của WordPress (nó đã hoàn tất, nhưng tôi sẽ không đăng nó vì tôi đã không kiểm tra). :)
sorich87

@ sorich87 - Bạn biết câu nói cũ, "Bạn đang ngủ, bạn thả lỏng!" Nghiêm túc mà nói, CHỈ đùa. Thực sự chỉ có một cách hợp lý để làm cho nó hoạt động nên không có gì lạ khi mã của bạn sẽ giống nhau!
MikeSchinkel

Mike, bạn tiếp tục ngạc nhiên. Cảm ơn rất nhiều vì đã dành thời gian để đập nó ra.
Scott B

@ sorich87 - Cảm ơn bạn đã làm việc trên nó. Tôi thực sự đánh giá cao những nỗ lực.
Scott B

1
@Scott B : Không vấn đề gì, rất vui vì tôi có thể giúp đỡ. Tôi tìm kiếm những câu hỏi hợp lý chung có khả năng giúp ích cho nhiều người và cố gắng trả lời chúng không chỉ cho người đặt câu hỏi mà còn cho những người có thể đến sau.
MikeSchinkel

0

Wordpress cho phép bạn thêm Meta vào Danh mục bằng cách sử dụng plugin:

Để làm điều này, bạn cần thêm một trong các tiện ích mở rộng khác nhau để thêm meta vào danh mục (bắt chước những trang nào thoát ra khỏi hộp), Simple Term Meta thực hiện công việc độc đáo.

NB WordPress 3.x là cần thiết để mở rộng Danh mục.

Sau đó, bạn có thể sử dụng:

  • add_term_meta
  • update_term_meta
  • get_term_meta

Sử dụng Hàm.php để thêm phương thức để làm những gì bạn muốn, vd

add_action('category_add_form_fields', 'category_metabox_add', 10, 1);

function category_metabox_add($tag) { ?>
    <div class="form-field">
        <label for="image-url"><?php _e('Image URL') ?></label>
        <input name="image-url" id="image-url" type="text" value="" size="40" aria-required="true" />
        <p class="description"><?php _e('This image will be the thumbnail shown on the category page.'); ?></p>
    </div>
<?php } 

add_action('created_category', 'save_category_metadata', 10, 1);

function save_category_metadata($term_id)
{
    if (isset($_POST['image-url'])) 
        update_term_meta( $term_id, 'image-url', $_POST['image-url']);                  
}

Gọi các lĩnh vực mới trong các chủ đề rất dễ dàng:

<?php echo get_term_meta(get_query_var('cat'), 'image-url', true); ?>

Thêm chi tiết và ví dụ: http://www.wphub.com/adding-metadata-taxonomy-terms/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.