I've set up Custom Fields that accept a URL to a social media site, I would like to then check and see if the field contains http:// and if it does not, add it before saving to the db.
// Add Social Media Meta Boxes
function add_social_box()
{
add_meta_box( 'social-media',
__( 'Social Media'), 'social_meta_box_callback', 'page', 'advanced', 'high');
}
add_action( 'add_meta_boxes', 'add_social_box' );
function social_meta_box_callback( $post ) {
// Add a nonce field so we can check for it later.
wp_nonce_field( 'social_save', 'social_meta_box_nonce' ); ?>
<div id="meta-inner">
<?php
/*
* Use get_post_meta() to retrieve an existing value
* from the database and use the value for the form.
*/
$accounts = get_post_meta( $post->ID, 'accounts', true);
// foreach ($accounts as $account) {
// $parsed = parse_url($account);
// if (empty($parsed['scheme'])) {
// $account = 'http://' . ltrim($account, '/');
// }
// var_dump($account);
// }
?>
<div>
<label for="facebook">Facebook</label>
<input type="text" id="facebook" name="accounts[facebook]" value="<?php echo esc_attr( $accounts["facebook"] ) ?>" />
</div>
<div>
<label for="twitter">Twitter</label>
<input type="text" id="twitter" name="accounts[twitter]" value="<?php echo esc_attr( $accounts["twitter"] ) ?>" />
</div>
</div>
<?php }
When I var_dump($account)it gives me the correctly adjusted urls here.
function social_save_postdata( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
// if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
// return;
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
// if ( !isset( $_POST['menu_meta_box_nonce'] ) )
// return;
// if ( !wp_verify_nonce( $_POST['social_meta_box_nonce'], 'social_save' ) )
// return;
$accounts = $_POST["accounts"];
foreach ($accounts as $account) {
$parsed = parse_url($account);
if (empty($parsed['scheme'])) {
$account = 'http://' . ltrim($account, '/');
}
update_post_meta($post_id,'accounts',$accounts);
}
}
add_action( 'save_post', 'social_save_postdata' );
And using the same logic that works in the callback function above, this does not save the adjusted url in the db. My guess is that the data structure that I retrieve from $_POST["accounts"] is not the same as the serialized data I fetch from the callback function. Unfortunately I am not sure how to get a look at that data to determine the correct structure to parse the URL.
In your loop you are doing
$account = 'http://' . ltrim($account, '/');
This does not update the original value in array :)
As Hanky Panky has noted above, I forgot to update the value of the array. For completeness, here is what the functional foreach loop looks like:
$accounts = $_POST["accounts"];
foreach ($accounts as &$account) {
$parsed = parse_url($account);
if (empty($parsed['scheme'])) {
$account = 'http://' . ltrim($account, '/');
}
}
update_post_meta($post_id,'accounts',$accounts);
Please notice the subtle change of the added & in the foreach loop:
foreach ($accounts as &$account) {
Explained: http://php.net/manual/en/language.references.pass.php
Related
I have a large set of pages (page1/) that need to show a certain navigation bar and a second large set of pages (page2/) that need to show a different navigation bar in its place.
I have tried various jQuery to identify if the URL contains a certain word and, if it does, show the corresponding navigation bar - but with no success.
Below is the jQuery I've tried.
<script>
if(strpos($url ,'page1/') !== FALSE) {
echo '#page1-navigation-bar';
}
if(strpos($url ,'page2/') !== FALSE){
echo '#page2-navigation-bar';
}
</script>
This has no effect and I'm not sure whether this is because the coding is wrong, I've inputted it in the wrong place, I need to do something else as well as this coding or a combination of everything plus more.
Also not sure if this will hide one when showing the other?
Please help by stating any code needed and where exactly this needs inputting.
Thanks,
Michael
Maybe try like this in PHP:
<?php
$page = array("page1/" /*, "page2/", "page3/", "all other pages" */ );
if(in_array(strpos($url, $page))
{echo '#page1-navigation-bar';}
else
{echo '#page2-navigation-bar';}
?>
There are a couple ways you can go about this. You can do as WebSon has suggested but with a different approach, you can do it via page templates, or you can do it with custom post metas. Now note, while you're doing something with "ID's," I suggest you change the navigation displayed using wp_nav_menu().
One method with a suggested conditional, instead of ID's.
<?php
$first_array = [ 'page1', 'page3', 'page5' ];
$second_array = [ 'page2', 'page4', 'page6' ];
$wp_nav_args = [ //your default args ];
if ( is_page($first_array ) ) {
// Change the entire array or parts of it.
$wp_nav_args = [];
}
elseif ( is_page($second_array) ) {
// Change the entire array or parts of it.
$wp_nav_args = [];
}
wp_nav_menu($wp_nav_args);
Page Templates
<?php
$wp_nav_args = [ //your default args ];
if ( is_page_template('template-menu-a') ) {
// Change the entire array or parts of it.
$wp_nav_args = [];
}
elseif ( is_page_template('template-menu-b') {
// Change the entire array or parts of it.
$wp_nav_args = [];
}
wp_nav_menu($wp_nav_args);
More complicated way, which doesn't include templates, yet is extendable.
Just wanted to share this way, as you can use this for a few other things as well, by creating custom post metas. This example shows a checkbox in the Update/Publish box.
<?php
function add_custom_meta_field() {
$post_id = get_the_ID();
if ( get_post_type( $post_id ) !== 'page' ) {
return;
}
$value = get_post_meta( $post_id, '_navigation_b', true );
?>
<div class="misc-pub-section misc-pub-section-last">
<input type="checkbox" value="1" <?php checked( $value, true, true ); ?> name="_navigation_b" id="_navigation_b" /><label for="_navigation_b"><?php _e( 'Add To Your Calendar Icons', 'navy' ); ?></label>
</div>
<?php
}
add_action( 'post_submitbox_misc_actions', 'add_custom_meta_field' );
function save_custom_meta_field() {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( isset( $_POST['_navigation_b'] ) ) {
update_post_meta( $post_id, '_navigation_b', $_POST['_navigation_b'] );
} else {
delete_post_meta( $post_id, '_navigation_b' );
}
}
add_action( 'save_post', 'save_custom_meta_field' );
As the title explains, I am trying to add infinite custom fields for two things:
1.Name
2.Bio
Now i tried adding 1000 custom fields and upon update it showed me just 471, There's no way it exceeds and i tried this on my local environment as well as the online but same results
// Adding the metaboxes
add_action( 'add_meta_boxes', 'add_employee_meta' );
/* Saving the data */
add_action( 'save_post', 'employee_meta_save' );
/* Adding the main meta box container to the post editor screen */
function add_employee_meta() {
add_meta_box(
'employee-details',
'Employee Details',
'employee_details_init',
'post');
}
/*Printing the box content */
function employee_details_init() {
global $post;
// Use nonce for verification
wp_nonce_field( plugin_basename( __FILE__ ), 'employee_nonce' );
?>
<div id="employee_meta_item">
<?php
//Obtaining the linked employeedetails meta values
$employeeDetails = get_post_meta($post->ID,'employeeDetails',true);
$c = 0;
if ( count( $employeeDetails ) > 0 && is_array($employeeDetails)) {
foreach( $employeeDetails as $employeeDetail ) {
if ( isset( $employeeDetail['name'] ) || isset( $employeeDetail['bio'] ) ) {
printf( '<p>Name<input type="text" name="employeeDetails[%1$s][name]" value="%2$s" /> Package : <textarea name="employeeDetails[%1$s][bio]" rows="4" cols="50" >%3$s</textarea>%4$s</p>', $c, $employeeDetail['name'], $employeeDetail['bio'], 'Remove' );
$c = $c +1;
}
}
}
?>
<span id="output-package"></span>
<?php _e('Add Employee Details'); ?>
<script>
var $ =jQuery.noConflict();
$(document).ready(function() {
var count = <?php echo $c; ?>;
$(".add_package").click(function() {
count = count + 1;
$('#output-package').append('<p> Name <input type="text" name="employeeDetails['+count+'][name]" value="" /> bio : <textarea name="employeeDetails['+count+'][bio]" rows="4" cols="50" ></textarea><?php echo "Remove"; ?></p>' );
return false;
});
$(document.body).on('click','.remove-package',function() {
$(this).parent().remove();
});
});
</script>
</div><?php
}
/* Save function for the entered data */
function employee_meta_save( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
// Verifying the nonce
if ( !isset( $_POST['employee_nonce'] ) )
return;
if ( !wp_verify_nonce( $_POST['employee_nonce'], plugin_basename( __FILE__ ) ) )
return;
// Updating the employeeDetails meta data
$employeeDetails = $_POST['employeeDetails'];
update_post_meta($post_id,'employeeDetails',$employeeDetails);
}
Have anyone tried adding a lot of custom fields and was there such limit as of what i am facing right now ?
Is there any way we can actually use any number of custom fields without this sort of restriction that i am having right now ?
You can hard code it without a plugin by adding this to you functions.
add_filter( 'postmeta_form_limit' , 'customfield_limit_increase' );
function customfield_limit_increase( $limit ) {
$limit = 1000;
return $limit;
}
I would think you could possibly end up with a performance issue going overboard with this.
Also you could run into a php limitation even with the ACF plugin mentioned above. (in PHP 5.3.9) If that is the case you can add this to your .htaccess file...
php_value max_input_vars 3000
I'm trying to save a post meta data on the database, using custom post type. The problem is I can't store the meta_key, the only one storing is the meta-value. I have two textbox there, one for event date and one for event name.. I'm trying to store the date on the meta key and the event on the value. the problem is that it only store on the meta value, and i'm not sure on the meta-key. Also how do you store multiple meta-keys and meta-values on the same post? Any idea which part of this syntax is wrong? thanks :)
function add_calendar_metaboxes() {
add_meta_box('wpt_calendar_location', 'Event Date', 'wpt_calendar_location', 'calendar_holiday', 'normal', 'default');
}
// The Event Location Metabox
function wpt_calendar_location() {
global $post;
echo "<form method=\"POST\">";
// Noncename needed to verify where the data originated
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
// Get the location data if its already been entered
$event_name = get_post_meta($post->ID, '_event_name', true);
$event_date = get_post_meta($post->ID, '_event_date', true);
echo '<label>Event Date</label><input type="text" name="_event_date" value="' . $event_date . '" />';
echo '<label>Event Name</label><input type="text" name="_event_name" value="' . $event_name . '" />';
echo '<input type="submit" name="Submit">';
echo '</form>';
}
// Save the Metabox Data
function wpt_save_events_meta($post_id, $post) {
if ( !wp_verify_nonce( $_POST['eventmeta_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
$events_meta[] = array($_POST['_event_date'] => $_POST['_event_name']);
foreach ($events_meta as $key => $value)
{
if( $post->post_type == 'revision' ) return;
$value = implode(',', (array)$value);
if(get_post_meta($post->ID, $key, FALSE))
{
update_post_meta($post->ID, $key, $value);
}
else
{
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key);
}
}
add_action('save_post', 'wpt_save_events_meta', 1, 2);
Why do you treat it like array ??
Try this simple function first
function wpt_save_events_meta() {
global $post;
update_post_meta($post->ID, "_event_date", $_POST["_event_date"]);
update_post_meta($post->ID, "_event_name", $_POST["_event_name"]);
}
If this is working for you, then you can put all your validation stuff .
( IF you still find a problem, try $post_id instead of $post->ID )
EDIT I after comment
When you do update_post_meta($post->ID, $_POST["_event_date"], $_POST["_event_name"] );
You are actually saving the _event_date as KEY and the _event_name as VALUE.
Unless you specifically know what you are doing - this is wrong
The point is to save 2 fields.
One named "_event_date" to hold the dates
One named "_event_name" to hold the names
In the case you wrote in the comments you will have something like ( I do not know the real data structure ..)
( post_id=1 ) 2014.03.04 => my_event_name
( post_id=2 ) 2014.03.05 => my_event_name2
( post_id=3 ) 2014.03.06 => my_event_name3
In the correct code you will have
( post_id=1 ) _event_date => 2014.03.04
_event_name => my_event_name
( post_id=2 ) _event_date => 2014.03.05
_event_name => my_event_name2
( post_id=3 ) _event_date => 2014.03.06
_event_name => my_event_name3
You can see that in the first code , it will be really hard to actually use the data in a search for example as in the second code - it has a structure .
You should treat each form field ( meatbox field ) as an independent set of key % value - each by it´s own.. Just try the code posted above .
I'm debugging my wordpress theme and I keep getting this notification in my functions.php file:
Undefined variable: post in (myfolders)/functions.php on line 961
This is line 961
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
The code is for a custom tinymce for my custom post type(Portfolio) project description.
What is causing variable to be undefined? Here is the code in it's entirety:
add_action( 'add_meta_boxes', 'mpc_add_description_meta_box' );
// Add the projects Meta Box
function mpc_add_description_meta_box() {
add_meta_box('mpc_add_description_meta_box', 'Project Description', 'mpc_add_description_meta_box_callback', 'portfolio', 'normal', 'high');
}
// the description output
function mpc_add_description_meta_box_callback() {
global $post;
// Noncename needed to verify where the data originated
echo '<input type="hidden" name="mpc_projects_description_noncename" id="mpc_projects_description_noncename" value="'.wp_create_nonce(plugin_basename(__FILE__)).'" />';
// Get the location data if its already been entered
$input = get_post_meta($post->ID, 'mpc_projects_description', true);
// echo '<input type="text" name="mpc_projects_description" value="' . $input . '" " />';
wp_editor($input, 'mpc_projects_description', array('textarea_name' => 'mpc_projects_description', 'editor_css' => '<style>#wp-mpc_projects_description-editor-container{background-color:white;style="width:100%;}</style>'));
echo '<table id="post-status-info" cellspacing="0"><tbody><tr><td id="wp-word-count">Word count: <span class="word-count_2">';
$words = strip_tags($input);
$count = str_word_count($words, 0);
echo $count;
echo '</span></td>
<td class="autosave-info">
<span class="autosave-message"> </span>
</td>
</tr></tbody></table>';
}
//save the data
add_action('save_post', 'mpc_save_description_meta', 1, 2); // save the custom fields
function mpc_save_description_meta($post_id, $post) {
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['mpc_projects_description_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
// OK, we're authenticated: we need to find and save the data
// We'll put it into an array to make it easier to loop though.
$mpc_description_meta['mpc_projects_description'] = $_POST['mpc_projects_description'];
// Add values of $mpc_description_meta as custom fields
foreach ($mpc_description_meta as $key => $value) { // Cycle through the $mpc_description_meta array!
if( $post->post_type == 'revision' ) return; // Don't store custom data twice
$value = implode(',', (array)$value); // If $value is an array, make it a CSV (unlikely)
if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
update_post_meta($post->ID, $key, $value);
} else { // If the custom field doesn't have a value
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key); // Delete if blank
}
}
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
The post global is available inside the functions but you haven't set it outside.
Change:
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
To:
global $post;
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
This could also depend on where you use this code. If you fire the code before the post object is set then you'll get this error.
If it's just in functions.php then change it to:
function wpse_post_test() {
global $post;
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
}
add_action( 'wp', 'wpse_post_test' );
After reviewing your question again it appears you are attempting to output this inside functions.php. What are you trying to achieve?
I´m woring on a costum meta-box for wordpress. Trouble is wordpress only seems to retain/save some of the values I enter in the fields.. I can´t really find a pattern either.. so here's the code:
<?php
function add_products_metaboxes() {
add_meta_box('sra_product_info', 'Product Information', 'sra_products_info', 'product', 'side', 'default');
}
// The Productinfo Metabox
function sra_products_info() {
//get access to the post object
global $post;
// Noncename needed to verify where the data originated
echo '<input type="hidden" name="productmeta_noncename" id="productmeta_noncename" value="' .
wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
// Get the data from the field if its already been entered
$name = get_post_meta($post->ID, '_name', true);
$price = get_post_meta($post->ID, '_price', true);
$includes = get_post_meta($post->ID, '_includes', true);
$supports = get_post_meta($post->ID, '_supports', true);
$version = get_post_meta($post->ID, '_version' , true);
$extrainfo = get_post_meta($post->ID, '_extrainfo', true);
// Echo out the form
echo '<form>';
echo '<label for="_name">Name</label>' . '<input type="text" name="_name" value="' . $name . '"/>';
echo '<label for="_price">Price</label>' . '<input type="text" name="_price" value="' . $price . '"/>';
echo '<label for="_includes">Includes</label> <textarea name="_includes" rows="4" cols="10">' . $includes . '</textarea>';
echo '<label for="_supports">Supports</label> <input type="text" name="_supports" value="' . $supports . '"/>';
echo '<label for="_version">Version</label>' . '<input type="text" name="_version" value="' . $version . '"/>';
echo '<label for="_extrainfo">Extras</label> <textarea name="_extrainfo" rows="4" cols="10">' . $extrainfo . '</textarea>';
echo '</form>';
}
// Save the Metabox Data
function sra_save_product_meta($post_id, $post) {
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['productmeta_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
// OK, we're authenticated: we need to find and save the data
// check if the field exists in the posts array - if it does, then put cintent in $product_meta.
// this code needs to be refactored!
if (isset($_POST['_name'])) {
$product_meta['_name'] = $_POST['_name'];
}
if (isset($_POST['_price'])) {
$product_meta['_price'] = $_POST['_price'];
}
if (isset($_POST['_includes'])) {
$product_meta['_includes'] = $_POST['_includes'];
}
if (isset($_POST['_supports'])) {
$product_meta['_supports'] = $_POST['_supports'];
}
if (isset($_POST['_version'])) {
$product_meta['_version'] = $_POST['_version'];
}
if (isset($_POST['_extrainfo'])) {
$product_meta['_extrainfo'] = $_POST['_extrainfo'];
}
// Add values of $prpduct_meta as custom fields
foreach ($product_meta as $key => $value) { // Cycle through the $product_meta array!
if( $post->post_type == 'revision' ) return; // Don't store custom data twice
$value = implode(',', (array)$value); // If $value is an array, make it a CSL (unlikely)
if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
update_post_meta($post->ID, $key, $value);
} else { // If the custom field doesn't have a value
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key); // Delete if blank
}
}
add_action('save_post', 'sra_save_product_meta', 1, 2); // save the custom fields
Do you see any obvious mistakes? I think I've become a bit blind to my own mistakes in this code..
In general, I would advise to use prefixes for your field names. Values like _name have too much chances getting in conflict with other values with the same name elsewhere. Use things like _product_name, etc. Can you try that? If your code works with pages, it should have an impact.
And why not adding the 4th parameter with 'true' to add_post_meta() and previous value for update_post_meta()? See WordPress codex about these functions: http://codex.wordpress.org/Function_Reference/add_post_meta. So it would go:
if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
update_post_meta($post->ID, $key, $value, /***OLDVALUE***/ ); // See http://codex.wordpress.org/Function_Reference/update_post_meta for old value
} else { // If the custom field doesn't have a value
add_post_meta($post->ID, $key, $value, true);
}
I think it is clear you have a conflict with a metakey with the same name. Not in pages, but in posts. So try to use this 4th parameter to ensure you are referencing a unique key (and my advice, still, use clear prefixes to differenciate from anything else, be it plugins, core, etc.)