最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

custom post types - Plugin - Combine Meta Box Input Fields into single saveble record

programmeradmin0浏览0评论

Im a complete novice when it comes to coding. I have managed to build a theme with some custom post types. Within the custom post type i have used a generator tool to create a custom meta box. It almost does everything i need except...

.................................

In the code below you will see a field called 'document-link'. At the front end it has button that allows the use to choose a media library item and then inserts the URL into the 'document-link'field/ e.g. mysite/library/intro.pdf

In my theme the link is being displayed as button using PostTablePro plugin.

Due to a restriction on the plugin, to display the button the plugin requires the saved record to hold the full html for the link as below...

<a class="btn btn-outline-info btn-block" href="mysite/library/intro.pdf" aria-label="Download File"><i class="fa fa-external-link" aria-hidden="true"></i></a>

This is would be easy but.. i would like the buttons colour/icon to change based on the file type (pdf icon, word icon etc).

In the full code below you will see there is selection field called 'document-mime-type' this holds the file type.

What i want to achieve is on saving on the page... the field 'document-link' which holds a plain url is wrapped with the full html formatting and the A class and I class you will see in the code above is changed based on the file type chosen in the filed called 'document-mime-type'.

I think some sort of if then else statement but ive tried to work it out for last few days and i cannot get my brain into a starting position.... can anyone teach me how to start this off with a couple of file types and i can take it from there.... THANK YOU

<?php
    /**
     * Everything from here down is the meta box that doesn't do what i need it to.
     * im not familiar with below i used a generator online change away it confuses me...
     */
class Rational_Meta_Box {
    private $screens = array(
        'library_ims',
    );
    private $fields = array(
        array(
            'id' => 'document-link',
            'label' => 'Document Link',
            'type' => 'media',
        ),
        array(
            'id' => 'ims-reference',
            'label' => 'IMS Reference',
            'type' => 'text',
        ),
        array(
            'id' => 'document-mime-type',
            'label' => 'Document MIME Type',
            'type' => 'select',
            'options' => array(
                'fa fa-file-word-o' => 'MS Word',
                'fa-file-pdf-o' => 'Adobe PDF',
                'fa-file-excel-o' => 'MS Excel',
                'fa-file-powerpoint-o' => 'MS PowerPoint',
                'fa-external-link' => 'External Link',
                'fa-file-video-o' => 'Video File',
                'fa-file-image-o' => 'Image File',
                'fa-file-archive-o' => 'Archive (ZIP) File',
                'fa-file-audio-o' => 'Audio File',
                'fa-globe' => 'Earth (KMZ) File',
            ),
        ),
        array(
            'id' => 'password',
            'label' => 'Password',
            'type' => 'password',
        ),
        array(
            'id' => 'rev',
            'label' => 'Rev',
            'type' => 'text',
        ),
        array(
            'id' => 'annex-sl-ref',
            'label' => 'Annex SL Ref',
            'type' => 'select',
            'options' => array(
                'Not Applicable',
                'Leadership',
                'Planning',
                'Support',
                'Operation',
                'Evaluation',
                'Improvement  ',
            ),
        ),
    );

    /**
     * Class construct method. Adds actions to their respective WordPress hooks.
     */
    public function __construct() {
        add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
        add_action( 'admin_footer', array( $this, 'admin_footer' ) );
        add_action( 'save_post', array( $this, 'save_post' ) );
    }

    /**
     * Hooks into WordPress' add_meta_boxes function.
     * Goes through screens (post types) and adds the meta box.
     */
    public function add_meta_boxes() {
        foreach ( $this->screens as $screen ) {
            add_meta_box(
                'document-overview',
                __( 'Document Overview', 'rational-metabox' ),
                array( $this, 'add_meta_box_callback' ),
                $screen,
                'normal',
                'high'
            );
        }
    }

    /**
     * Generates the HTML for the meta box
     * 
     * @param object $post WordPress post object
     */
    public function add_meta_box_callback( $post ) {
        wp_nonce_field( 'document_overview_data', 'document_overview_nonce' );
        $this->generate_fields( $post );
    }

    /**
     * Hooks into WordPress' admin_footer function.
     * Adds scripts for media uploader.
     */
    public function admin_footer() {
        ?><script>
            // /
            jQuery(document).ready(function($){
                if ( typeof wp.media !== 'undefined' ) {
                    var _custom_media = true,
                    _orig_send_attachment = wp.media.editor.send.attachment;
                    $('.rational-metabox-media').click(function(e) {
                        var send_attachment_bkp = wp.media.editor.send.attachment;
                        var button = $(this);
                        var id = button.attr('id').replace('_button', '');
                        _custom_media = true;
                            wp.media.editor.send.attachment = function(props, attachment){
                            if ( _custom_media ) {
                                $("#"+id).val(attachment.url);
                            } else {
                                return _orig_send_attachment.apply( this, [props, attachment] );
                            };
                        }
                        wp.media.editor.open(button);
                        return false;
                    });
                    $('.add_media').on('click', function(){
                        _custom_media = false;
                    });
                }
            });
        </script><?php
    }

    /**
     * Generates the field's HTML for the meta box.
     */
    public function generate_fields( $post ) {
        $output = '';
        foreach ( $this->fields as $field ) {
            $label = '<label for="' . $field['id'] . '">' . $field['label'] . '</label>';
            $db_value = get_post_meta( $post->ID, 'document_overview_' . $field['id'], true );
            switch ( $field['type'] ) {
                case 'media':
                    $input = sprintf(
                        '<input class="regular-text" id="%s" name="%s" type="text" value="%s"> <input class="button rational-metabox-media" id="%s_button" name="%s_button" type="button" value="Upload/Link" />',
                        $field['id'],
                        $field['id'],
                        $db_value,
                        $field['id'],
                        $field['id']
                    );
                    break;
                case 'select':
                    $input = sprintf(
                        '<select id="%s" name="%s">',
                        $field['id'],
                        $field['id']
                    );
                    foreach ( $field['options'] as $key => $value ) {
                        $field_value = !is_numeric( $key ) ? $key : $value;
                        $input .= sprintf(
                            '<option %s value="%s">%s</option>',
                            $db_value === $field_value ? 'selected' : '',
                            $field_value,
                            $value
                        );
                    }
                    $input .= '</select>';
                    break;
                default:
                    $input = sprintf(
                        '<input %s id="%s" name="%s" type="%s" value="%s">',
                        $field['type'] !== 'color' ? 'class="regular-text"' : '',
                        $field['id'],
                        $field['id'],
                        $field['type'],
                        $db_value
                    );
            }
            $output .= $this->row_format( $label, $input );
        }
        echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
    }

    /**
     * Generates the HTML for table rows.
     */
    public function row_format( $label, $input ) {
        return sprintf(
            '<tr><th scope="row">%s</th><td>%s</td></tr>',
            $label,
            $input
        );
    }
    /**
     * Hooks into WordPress' save_post function
     */
    public function save_post( $post_id ) {
        if ( ! isset( $_POST['document_overview_nonce'] ) )
            return $post_id;

        $nonce = $_POST['document_overview_nonce'];
        if ( !wp_verify_nonce( $nonce, 'document_overview_data' ) )
            return $post_id;

        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            return $post_id;

        foreach ( $this->fields as $field ) {
            if ( isset( $_POST[ $field['id'] ] ) ) {
                switch ( $field['type'] ) {
                    case 'email':
                        $_POST[ $field['id'] ] = sanitize_email( $_POST[ $field['id'] ] );
                        break;
                    case 'text':
                        $_POST[ $field['id'] ] = sanitize_text_field( $_POST[ $field['id'] ] );
                        break;
                }
                update_post_meta( $post_id, 'document_overview_' . $field['id'], $_POST[ $field['id'] ] );
            } else if ( $field['type'] === 'checkbox' ) {
                update_post_meta( $post_id, 'document_overview_' . $field['id'], '0' );
            }
        }
    }
}
new Rational_Meta_Box;

Im a complete novice when it comes to coding. I have managed to build a theme with some custom post types. Within the custom post type i have used a generator tool to create a custom meta box. It almost does everything i need except...

.................................

In the code below you will see a field called 'document-link'. At the front end it has button that allows the use to choose a media library item and then inserts the URL into the 'document-link'field/ e.g. mysite/library/intro.pdf

In my theme the link is being displayed as button using PostTablePro plugin.

Due to a restriction on the plugin, to display the button the plugin requires the saved record to hold the full html for the link as below...

<a class="btn btn-outline-info btn-block" href="mysite/library/intro.pdf" aria-label="Download File"><i class="fa fa-external-link" aria-hidden="true"></i></a>

This is would be easy but.. i would like the buttons colour/icon to change based on the file type (pdf icon, word icon etc).

In the full code below you will see there is selection field called 'document-mime-type' this holds the file type.

What i want to achieve is on saving on the page... the field 'document-link' which holds a plain url is wrapped with the full html formatting and the A class and I class you will see in the code above is changed based on the file type chosen in the filed called 'document-mime-type'.

I think some sort of if then else statement but ive tried to work it out for last few days and i cannot get my brain into a starting position.... can anyone teach me how to start this off with a couple of file types and i can take it from there.... THANK YOU

<?php
    /**
     * Everything from here down is the meta box that doesn't do what i need it to.
     * im not familiar with below i used a generator online change away it confuses me...
     */
class Rational_Meta_Box {
    private $screens = array(
        'library_ims',
    );
    private $fields = array(
        array(
            'id' => 'document-link',
            'label' => 'Document Link',
            'type' => 'media',
        ),
        array(
            'id' => 'ims-reference',
            'label' => 'IMS Reference',
            'type' => 'text',
        ),
        array(
            'id' => 'document-mime-type',
            'label' => 'Document MIME Type',
            'type' => 'select',
            'options' => array(
                'fa fa-file-word-o' => 'MS Word',
                'fa-file-pdf-o' => 'Adobe PDF',
                'fa-file-excel-o' => 'MS Excel',
                'fa-file-powerpoint-o' => 'MS PowerPoint',
                'fa-external-link' => 'External Link',
                'fa-file-video-o' => 'Video File',
                'fa-file-image-o' => 'Image File',
                'fa-file-archive-o' => 'Archive (ZIP) File',
                'fa-file-audio-o' => 'Audio File',
                'fa-globe' => 'Earth (KMZ) File',
            ),
        ),
        array(
            'id' => 'password',
            'label' => 'Password',
            'type' => 'password',
        ),
        array(
            'id' => 'rev',
            'label' => 'Rev',
            'type' => 'text',
        ),
        array(
            'id' => 'annex-sl-ref',
            'label' => 'Annex SL Ref',
            'type' => 'select',
            'options' => array(
                'Not Applicable',
                'Leadership',
                'Planning',
                'Support',
                'Operation',
                'Evaluation',
                'Improvement  ',
            ),
        ),
    );

    /**
     * Class construct method. Adds actions to their respective WordPress hooks.
     */
    public function __construct() {
        add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
        add_action( 'admin_footer', array( $this, 'admin_footer' ) );
        add_action( 'save_post', array( $this, 'save_post' ) );
    }

    /**
     * Hooks into WordPress' add_meta_boxes function.
     * Goes through screens (post types) and adds the meta box.
     */
    public function add_meta_boxes() {
        foreach ( $this->screens as $screen ) {
            add_meta_box(
                'document-overview',
                __( 'Document Overview', 'rational-metabox' ),
                array( $this, 'add_meta_box_callback' ),
                $screen,
                'normal',
                'high'
            );
        }
    }

    /**
     * Generates the HTML for the meta box
     * 
     * @param object $post WordPress post object
     */
    public function add_meta_box_callback( $post ) {
        wp_nonce_field( 'document_overview_data', 'document_overview_nonce' );
        $this->generate_fields( $post );
    }

    /**
     * Hooks into WordPress' admin_footer function.
     * Adds scripts for media uploader.
     */
    public function admin_footer() {
        ?><script>
            // https://codestag/how-to-use-wordpress-3-5-media-uploader-in-theme-options/
            jQuery(document).ready(function($){
                if ( typeof wp.media !== 'undefined' ) {
                    var _custom_media = true,
                    _orig_send_attachment = wp.media.editor.send.attachment;
                    $('.rational-metabox-media').click(function(e) {
                        var send_attachment_bkp = wp.media.editor.send.attachment;
                        var button = $(this);
                        var id = button.attr('id').replace('_button', '');
                        _custom_media = true;
                            wp.media.editor.send.attachment = function(props, attachment){
                            if ( _custom_media ) {
                                $("#"+id).val(attachment.url);
                            } else {
                                return _orig_send_attachment.apply( this, [props, attachment] );
                            };
                        }
                        wp.media.editor.open(button);
                        return false;
                    });
                    $('.add_media').on('click', function(){
                        _custom_media = false;
                    });
                }
            });
        </script><?php
    }

    /**
     * Generates the field's HTML for the meta box.
     */
    public function generate_fields( $post ) {
        $output = '';
        foreach ( $this->fields as $field ) {
            $label = '<label for="' . $field['id'] . '">' . $field['label'] . '</label>';
            $db_value = get_post_meta( $post->ID, 'document_overview_' . $field['id'], true );
            switch ( $field['type'] ) {
                case 'media':
                    $input = sprintf(
                        '<input class="regular-text" id="%s" name="%s" type="text" value="%s"> <input class="button rational-metabox-media" id="%s_button" name="%s_button" type="button" value="Upload/Link" />',
                        $field['id'],
                        $field['id'],
                        $db_value,
                        $field['id'],
                        $field['id']
                    );
                    break;
                case 'select':
                    $input = sprintf(
                        '<select id="%s" name="%s">',
                        $field['id'],
                        $field['id']
                    );
                    foreach ( $field['options'] as $key => $value ) {
                        $field_value = !is_numeric( $key ) ? $key : $value;
                        $input .= sprintf(
                            '<option %s value="%s">%s</option>',
                            $db_value === $field_value ? 'selected' : '',
                            $field_value,
                            $value
                        );
                    }
                    $input .= '</select>';
                    break;
                default:
                    $input = sprintf(
                        '<input %s id="%s" name="%s" type="%s" value="%s">',
                        $field['type'] !== 'color' ? 'class="regular-text"' : '',
                        $field['id'],
                        $field['id'],
                        $field['type'],
                        $db_value
                    );
            }
            $output .= $this->row_format( $label, $input );
        }
        echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
    }

    /**
     * Generates the HTML for table rows.
     */
    public function row_format( $label, $input ) {
        return sprintf(
            '<tr><th scope="row">%s</th><td>%s</td></tr>',
            $label,
            $input
        );
    }
    /**
     * Hooks into WordPress' save_post function
     */
    public function save_post( $post_id ) {
        if ( ! isset( $_POST['document_overview_nonce'] ) )
            return $post_id;

        $nonce = $_POST['document_overview_nonce'];
        if ( !wp_verify_nonce( $nonce, 'document_overview_data' ) )
            return $post_id;

        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            return $post_id;

        foreach ( $this->fields as $field ) {
            if ( isset( $_POST[ $field['id'] ] ) ) {
                switch ( $field['type'] ) {
                    case 'email':
                        $_POST[ $field['id'] ] = sanitize_email( $_POST[ $field['id'] ] );
                        break;
                    case 'text':
                        $_POST[ $field['id'] ] = sanitize_text_field( $_POST[ $field['id'] ] );
                        break;
                }
                update_post_meta( $post_id, 'document_overview_' . $field['id'], $_POST[ $field['id'] ] );
            } else if ( $field['type'] === 'checkbox' ) {
                update_post_meta( $post_id, 'document_overview_' . $field['id'], '0' );
            }
        }
    }
}
new Rational_Meta_Box;
Share Improve this question asked Feb 15, 2020 at 13:00 Nathan JonesNathan Jones 111 bronze badge 3
  • Sorry I have not fully read your code so I might missed the point. But for your question title, I suggest making array from your field values and then saving that as JSON encoded single value if it is what you are looking for? – Muhammad Asad Commented Feb 15, 2020 at 13:39
  • Or maybe you leave it same for all but using CSS try to select the link via file type with something like this [href$=".pdf"]:before { and then style? No need to alter your markup html as via CSS you can target file types for styling? See this detailed article hongkiat/blog/css3-attribute-selector it solves your issue via CSS to style as per file type? – Muhammad Asad Commented Feb 15, 2020 at 13:41
  • Thank you for the effort but the solution proposed is not workable please refer to restrictions within my brief. – Nathan Jones Commented Feb 15, 2020 at 14:04
Add a comment  | 

1 Answer 1

Reset to default 0

Use something like this after you foreach loop. In this example link is saved in new meta field. You can overwrite document_overview_document-link, but then you will get combined html code as link value when open your document in editor.

foreach {
    ...
}

if ( isset( $_POST[ 'document-link' ] ) ) {
    $html = '<a class="btn btn-outline-info btn-block" href="' . esc_url( $_POST[ 'document-link' ] ) .  '" aria-label="Download File"><i class="fa ' . sanitize_text_field( $_POST[ 'document-mime-type' ] ) .  '" aria-hidden="true"></i></a>';
} else {
    $html = '';        
}

update_post_meta( $post_id, 'document_overview_link_html', $html );
发布评论

评论列表(0)

  1. 暂无评论