1

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.com/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.com/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.com/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;
  • 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? – Mohsin Feb 15 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.com/blog/css3-attribute-selector it solves your issue via CSS to style as per file type? – Mohsin Feb 15 at 13:41
  • Thank you for the effort but the solution proposed is not workable please refer to restrictions within my brief. – Nathan Jones Feb 15 at 14:04
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 );
  • Thank you for the reply im confused by the foreach : ... what goes where the ... is? – Nathan Jones Feb 17 at 21:19
  • That's your existing foreach loop. I just put it there to show that you should add my code after your foreach in save_post function. – Vitauts Stočka Feb 18 at 6:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.