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
1 Answer
Reset to default 0Use 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 );