I've run into a little situation that is hopefully possible to solve. My goal is to take an existing XML file from the server, parse it, and then inject it as a list into Wordpress's original WYSIWYG editor so that the site owner has the list readily available when he writes a new post. Right now, I have this code in my wp-admin/edit-form-advanced.php file:
/**
* Fires after the title field.
*
* #since 3.5.0
*
* #param WP_Post $post Post object.
*/
do_action( 'edit_form_after_title', $post );
if ( post_type_supports($post_type, 'editor') ) {
?>
<div id="postdivrich" class="postarea<?php if ( $_wp_editor_expand ) { echo ' wp-editor-expand'; } ?>">
<?php
/** LOAD XML FROM SERVER AND PARSE AS UL INTO EACH NEW WP POST **/
$xml = simplexml_load_file('../my-folder/file.xml');
$product = "<br/><br/><h2 style='text-align:center; color:#003300;'><u>Products Available Now</u></h2><br/><ul style='text-align:center; list-style:none; color:#003300;'>";
foreach( $xml as $value ) {
$product .= "<li>";
$product .= $value->Description .= " $";
$product .= $value->Price .= " / ";
$product .= $value->QtyUnit .= "\n";
$product .= "</li>";
};
?>
<?php wp_editor($product, 'content', array(
'_content_editor_dfw' => $_content_editor_dfw,
'drag_drop_upload' => true,
'tabfocus_elements' => 'content-html,save-post',
'editor_height' => 300,
'tinymce' => array(
'resize' => false,
'wp_autoresize_on' => $_wp_editor_expand,
'add_unload_trigger' => false,
),
) ); ?>
Although it works, this causes a couple issues.
1) It injects the data into every WYSIWYG editor, including pages, which I would like to avoid. The content should only appear in post editors if possible.
2) It causes a pretty serious bug that erases anything but the list whenever that particular admin page is reloaded. I can't save any drafts, or edit posts or pages unless I keep that session open in the browser during the editing process.
Not sure if these issues can be solved, but any and all help is sincerely appreciated!!
You should never modify WP core files. It's advisable that you update or restore the original files.
What you need can be achieved with this little plugin:
<?php
/**
* Plugin Name: Default Post Content
*/
add_action( 'load-post-new.php', 'new_post_so_44123076' );
function new_post_so_44123076() {
# Only load if post type not defined (only occurs for Posts)
if( isset($_GET['post_type']) )
return;
add_filter( 'default_content', 'default_content_so_44123076' );
}
function default_content_so_44123076( $content ) {
# Build your own custom content
$content = "My html content.";
return $content;
}
Make a folder for the plugin, put the code inside a file (custom-content.php) and put the XML on the same folder.
It can be retrieved like this:
$xml = plugins_url( '/file.xml', __FILE__ );
Related
I've built my first WordPress plugin to create a QR Code from a form.
It's just for learning purposes and would not meet standards for commercial release.
However it works perfectly on my local server in WAMP using Twenty Twenty theme.
When i test it on my live site (with a commercial theme) the qr code in .png format is displayed as a atring of characters similar to this.
�PNG IHDR{{n m<�PLTE���U��~ pHYs���+aIDATH���1�� ��P��H�W�]���� �0;>_�n�ζ�X����w����h�
The string is much longer, but i just put a snippet in to show what i mean.
Below is my plugin code and it includes the full untouched phpqrcode library.
<?php
/*
* Plugin Name: QR Code Generator
* Plugin URI: https://www.example.com/qr-code-generator
* Description: A plugin that allows you to easily generate QR codes for use on your website.
* Version: 1.0
* Author: Your Name
* Author URI: https://www.example.com
* License: GPL2
*/
include_once( plugin_dir_path( __FILE__ ) . 'phpqrcode/qrlib.php' );
function qr_code_shortcode( $atts ) {
// Extract the attributes
extract( shortcode_atts( array(
'text' => '',
), $atts ) );
global $post;
// Check if the shortcode is present in the post or page
if ( has_shortcode( $post->post_content, 'qr_code' ) ) {
// Check if the form has been submitted
if ( isset( $_POST['qr_code_text'] ) ) {
$text = sanitize_text_field( $_POST['qr_code_text'] );
// Generate the QR code
QRcode::png( $text );
} else {
// Display the form
ob_start();
echo '<form method="post">';
echo '<label for="qr_code_text">Enter the text for the QR code:</label><br>';
echo '<input type="text" name="qr_code_text" id="qr_code_text"><br>';
echo '<input type="submit" value="Generate QR Code">';
echo '</form>';
return ob_get_clean();
}
}
}
add_shortcode( 'qr_code', 'qr_code_shortcode' );
Any suggestions as to why it would work in one site and not on another ?
I've tried using base64 on the image thinking it was that but to no avail.
So I'm using the new WooCommerce Blocks for the first time. On the homepage of my website I've included the "ProductBestSellers" block and the "ProductOnSale" block. Both of these blocks show a grid styled layout for either best selling products or products on sale.
For the design I needed I had to add some wrappers to the html and therefore I cloned the repository from here; WooCommerce Gutenberg Blocks
The added html does work but now I need to include the product short description within these blocks. I've eddit the AbstractProductGrid.php as follows;
AbstractProductGrid.php
/**
* Render a single products.
* Edited: 24/02/2020
*
* Added wrappers to display content with padding borders and other styling
*
* #param int $id Product ID.
* #return string Rendered product output.
*/
public function render_product( $id ) {
$product = wc_get_product( $id );
if ( ! $product ) {
return '';
}
$data = (object) array(
'permalink' => esc_url( $product->get_permalink() ),
'description' => $this->get_description_html( $product ), <--- Add product short description
'image' => $this->get_image_html( $product ),
'title' => $this->get_title_html( $product ),
'rating' => $this->get_rating_html( $product ),
'price' => $this->get_price_html( $product ),
'badge' => $this->get_sale_badge_html( $product ),
'button' => $this->get_button_html( $product ),
);
return apply_filters(
'woocommerce_blocks_product_grid_item_html',
"<li class=\"wc-block-grid__product\">
<div class=\"wc-block-grid__product__wrapper\">
<div class=\"wc-block-grid__product__items\">
<a href=\"{$data->permalink}\" class=\"wc-block-grid__product-link\">
{$data->image}
{$data->title}
</a>
{$data->badge}
{$data->rating}
{$data->description}
<div class=\"wc-block-grid__product__price-wrapper\">
{$data->price}
{$data->button}
</div>
</div>
</div>
</li>",
$data,
$product
);
}
/**
* Get the product short description.
*
* #param \WC_Product $product Product.
* #return string
*/
protected function get_description_html( $product ) {
if ( empty( $this->attributes['contentVisibility']['description'] ) ) {
return '<p class="purple">The short description is empty</p>';
}
return '<div class="wc-block-grid__description">' . $product->get_short_description() ? $product->get_short_description() : wc_trim_string( $product->get_description(), 400 ) . '</div>';
}
The code above returns an empty attribute, how can I include the short description for the new WooCommerce Blocks?
I found this post when looking for an answer to this, I guess you might have solved it already but here is a suggested solution for anyone coming here.
First, It´s not recommended to change the core files of WooCommerce or the Blocks-plugin, since if you update the plugin your changes will be overwritten.
A better way is utilizing that the plugin is exposing a filter for the rendered output called "woocommerce_blocks_product_grid_item_html".
So if you put this in your functions.php you will get the short description after the product title:
/**
* Add short description to WooCommerce product blocks
*/
add_filter('woocommerce_blocks_product_grid_item_html', 'add_short_desc_woocommerce_blocks_product_grid_item_html', 10 , 3);
function add_short_desc_woocommerce_blocks_product_grid_item_html($content, $data, $product) {
$short_description = '<div class="wc-block-grid__product-short-description">' . $product->get_short_description() . '</div>';
// This will inject the short description after the first link (assumed: the default product link).
$after_link_pos = strpos($content, "</a>");
$before = substr($content, 0, $after_link_pos + 4);
$after = substr($content, $after_link_pos + 4);
$content = $before . $short_description . $after;
return $content;
}
This is very interesting, I tried it on my site, and it works - however my first is after the image, which also is a link.
So for me, the code from #Pierre, ended up outputtin:
Image
Description
Title
Anyone have any suggestions on how to make it output
Image
Title
Description
(Even when images are linked to the product page)
?
I'm customizing my theme right now. The Standard is, that the logged-in Users Avatar is shown in the Menu bar but I want to display a simple Icon there. I already wright the Code and everything works fine but the Code is located in the mains functions.php File. So in order to make the Site upgradeable, I need to embed the code in the child themes function.php. I found no help there so maybe here is someone who could help me!
Thanks a lot
Below is the Code which I need to embed in the functions.php File of my Child Theme:
add_action( 'init', 'gt3_get_page_id_from_menu' );
function gt3_user_avatar_out($avatar_size=80,$show_email=false){
$user_id = get_current_user_id();
$current_user = get_user_by( 'id', $user_id );
echo "<i class='gt3_login_icon gt3_login_icon--avatar'>";
echo '<i class="fa fa-user"></i>';
echo "</i>";
if ($show_email) {
echo "<span class='gt3_login__user_email'>".esc_html( $current_user->user_email )."</span>";
}
}
If a function is declared in the parent's functions.php, declaring a function with the same name in the child theme will cause a fatal error in the child theme itself. I'd suggest doing something like this instead:
parent function .php
// This can become a filter if you'll need to manipulate the current user
function gt3_get_current_user() {
return get_user_by( 'id', get_current_user_id() );
}
add_filter( 'gt3/current_user_avatar', function( string $html = '', bool $show_email = false ) {
$html .= '<i class="gt3_login_icon gt3_login_icon--avatar"><i class="fa fa-user"></i></i>';
if( $show_email ) {
$html .= sprintf( '<span class="gt3_login__user_email">%s</span>', esc_html( gt3_get_current_user()->user_email ) );
}
return $html;
}, 10, 2 );
child theme's function .php
add_filter( 'gt3/current_user_avatar', function( string $html = '', bool $show_email = false ) {
// $html here is the one that returned from the parent's theme. You can manipulate it or replace the whole output inside here.
return $html;
}, 10, 2 );
Example usages:
echo apply_filters( 'gt3/current_user_avatar', '', false ); // This will echo the icon without the email
echo apply_filters( 'gt3/current_user_avatar', '', true ); // This will echo the icon with the email
echo apply_filters( 'gt3/current_user_avatar', '<p>Append</p>', false ); // This will echo the icon without the email and the '<p>Append</p>' html string before everything else
The result will vary depending on where you use this filter. If you are in the child theme and you altered the html adding the said filter, the result will be customized for that theme. Remember that you can use the use statement to bring in external variables ina closure. For example:
$user_name = 'Mike';
add_filter( 'gt3/current_user_avatar', function( string $html = '', bool $show_email = false ) use ( $user_name ) {
$html .= sprintf( '<p>Hello, %s!</p>', $user_name );
return $html;
}, 10, 2 );
// This will cheer the user, and it will be place at the end of the snippet.
your code is not overwritten by adding a new functions.php file in the same folder, but do not copy/paste the code from the parent theme’s file, because it needs to remain separate from any modifications you make to the child theme. Instead, create a blank file or add any new .php functions required for your child theme
I have a Plugin installed on my WordPress site.
I'd like to override a function within the Plugin. Do I override this in my theme's functions.php and if so, how do I do this?
Here's the original function in my plugin:
/**
* sensei_start_course_form function.
*
* #access public
* #param mixed $course_id
* #return void
*/
function sensei_start_course_form( $course_id ) {
$prerequisite_complete = sensei_check_prerequisite_course( $course_id );
if ( $prerequisite_complete ) {
?><form method="POST" action="<?php echo esc_url( get_permalink() ); ?>">
<input type="hidden" name="<?php echo esc_attr( 'woothemes_sensei_start_course_noonce' ); ?>" id="<?php echo esc_attr( 'woothemes_sensei_start_course_noonce' ); ?>" value="<?php echo esc_attr( wp_create_nonce( 'woothemes_sensei_start_course_noonce' ) ); ?>" />
<span><input name="course_start" type="submit" class="course-start" value="<?php echo apply_filters( 'sensei_start_course_text', __( 'Start taking this Course', 'woothemes-sensei' ) ); ?>"/></span>
</form><?php
} // End If Statement
} // End sensei_start_course_form()
You can't really "override" a function. If a function is defined, you can't redefine or change it. Your best option is to create a copy of the plugin and change the function directly. Of course you will have to repeat this everytime the plugin is updated.
Give the plugin a different name to distinguish them in the plugin listing. Disable the original, enable your copy.
You can do it by using add_filter() function.
See wordpress stackexchange: Override plugin with functions.php
Just add the below code in theme's functions.php file.
add_filter('sensei_start_course_form','MyCustomfilter',$priority = 10, $args = 1);
function MyCustomfilter($course_id) {
// Do your logics here
}
I know this is late but in the event that someone else finds this post. A simpler solution is to make a copy of the function if you can to your themes functions file and rename it so that it doesn't conflict with the original function. Then use your new function in place of the original. That way you can update the plugin files without affecting your changes.
A bit late on this (november 2021) but I still found this answer today, so I'll add a solution I didn't see around:
For some historical reasons, WP still has the ability to add "must use" plugins that runs before all other plugins. So this give us the opportunity to add the function you want to override, so it already exists when the original plugin run.
In your case
add a .php file in the folder wp-content/mu-plugins
let say
wp-content/mu-plugins/custom-override.php
add your function in custom-override.php :
if ( ! function_exists( 'sensei_start_course_form' ) ) {
function sensei_start_course_form( $course_id ) {
//your magic here
//...
}
}
be sure that the original plugin also has this conditional "if function doesn't already exists..."
if ( ! function_exists( 'sensei_start_course_form' ) ) { ...
This did the trick for me ;-)
PD: I'm not an expert, please give me some feedback if this is wrong somehow. Thanks
REF: https://wordpress.org/support/article/must-use-plugins/
I also needed to change some code in a WordPress plugin. So I created a function that can be placed in functions.php in your child-theme. Please test before use! It is probably poor written since I'm no PHP expert. But the concept works for me. I tested it first outside WordPress so some variables like $root should/could be modified.
Situation was that I had to change some values in two different files in the plugin Email posts to subscribers.
I needed to change $home_url = home_url('/'); to $home_url = 'custom-redirect-url'; and 'content="10; to 'content="1; in the files optin.php and unsubscribe.php.
Every time the plugin gets updated it runs a function after the update. This is the code I use:
// Function that replaces the code
function replace_text_plugin_email_posts_to_subscribers($pluginTargetFile, $replaceURL) {
$root = $_SERVER['DOCUMENT_ROOT'];
$replaceThis = array("\$home_url = home_url('/');", "content=\"10;");
$withThis = array($replaceURL, "content=\"1;");
$fname = $root . $pluginTargetFile;
$fhandle = fopen($fname,"r");
$content = fread($fhandle,filesize($fname));
$content = str_replace($replaceThis, $withThis, $content);
$fhandle = fopen($fname,"w");
fwrite($fhandle,$content);
fclose($fhandle);
}
//Function that runs every time that email-posts-to-subscribers is updated
function my_upgrade_function( $upgrader_object, $options ) {
$current_plugin_path_name = 'email-posts-to-subscribers/email-posts-to-subscribers.php';
if ($options['action'] == 'update' && $options['type'] == 'plugin' ) {
foreach($options['plugins'] as $each_plugin) {
if ($each_plugin==$current_plugin_path_name) {
replace_text_plugin_email_posts_to_subscribers("/wp-content/plugins/email-posts-to-subscribers/job/optin.php","\$home_url = 'https://example.com/redirect-optin';");
replace_text_plugin_email_posts_to_subscribers("/wp-content/plugins/email-posts-to-subscribers/job/unsubscribe.php","\$home_url = 'https://example.com/redirect-unsubscribe';");
}
}
}
}
add_action( 'upgrader_process_complete', 'my_upgrade_function',10, 2);
I guess this wil only be of use when you have to adjust some minor things. Rewriting complete code is maybe not working with this code, but I didn't test this.
<?php wp_nav_menu(); ?>
So I want to use the above function to spit out my nav links with the class "topnav" and each one with a sequential ID.
Example of what I want:
<a class="topnav" id="1" href="#1">WP Page 1</a>
<a class="topnav" id="2" href="#2">WP Page 2</a>
<a class="topnav" id="3" href="#3">WP Page 3</a>
<a class="topnav" id="4" href="#4">WP Page 4</a>
<a class="topnav" id="5" href="#5">WP Page 5</a>
Is this possible to do? If so, how? Can you do it with arguments?
I suppose the "hard part" is sequentially labeling the IDs as well as the custom link location.
Ultimately I am trying to make something similar to the below code work with Exclude Pages plugin.
<?php
$pagepull = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_type = 'page' AND post_status = 'publish' ORDER BY menu_order", ARRAY_A);
$i = 1;
foreach ($pagepull as $single_page){
echo "<a class=\"topnav\" id=\"nav" . $i . "\" href=\"#" . $i . "\">" . $single_page['post_title'] . "</a>";
$i++;
}
?>
So I need help either modifying the above PHP code or wp_nav_menu(). Any suggestions?
UDPATE !!!!!!!
Better question! How do I return an array of pages using the Exclude Pages plugin? Here's the plugin code:
<?php
/*
Plugin Name: Exclude Pages from Navigation
Plugin URI: http://wordpress.org/extend/plugins/exclude-pages/
Description: Provides a checkbox on the editing page which you can check to exclude pages from the primary navigation. IMPORTANT NOTE: This will remove the pages from any "consumer" side page listings, which may not be limited to your page navigation listings.
Version: 1.9
Author: Simon Wheatley
Author URI: http://simonwheatley.co.uk/wordpress/
Copyright 2007 Simon Wheatley
This script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This script is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Full filesystem path to this dir
define('EP_PLUGIN_DIR', dirname(__FILE__));
// Option name for exclusion data
define('EP_OPTION_NAME', 'ep_exclude_pages');
// Separator for the string of IDs stored in the option value
define('EP_OPTION_SEP', ',');
// The textdomain for the WP i18n gear
define( 'EP_TD', 'exclude-pages' );
// Take the pages array, and return the pages array without the excluded pages
// Doesn't do this when in the admin area
function ep_exclude_pages( $pages ) {
// If the URL includes "wp-admin", just return the unaltered list
// This constant, WP_ADMIN, only came into WP on 2007-12-19 17:56:16 rev 6412, i.e. not something we can rely upon unfortunately.
// May as well check it though.
// Also check the URL... let's hope they haven't got a page called wp-admin (probably not)
// SWTODO: Actually, you can create a page with an address of wp-admin (which is then inaccessible), I consider this a bug in WordPress (which I may file a report for, and patch, another time).
$bail_out = ( ( defined( 'WP_ADMIN' ) && WP_ADMIN == true ) || ( strpos( $_SERVER[ 'PHP_SELF' ], 'wp-admin' ) !== false ) );
$bail_out = apply_filters( 'ep_admin_bail_out', $bail_out );
if ( $bail_out ) return $pages;
$excluded_ids = ep_get_excluded_ids();
$length = count($pages);
// Ensure we catch all descendant pages, so that if a parent
// is hidden, it's children are too.
for ( $i=0; $i<$length; $i++ ) {
$page = & $pages[$i];
// If one of the ancestor pages is excluded, add it to our exclude array
if ( ep_ancestor_excluded( $page, $excluded_ids, $pages ) ) {
// Can't actually delete the pages at the moment,
// it'll screw with our recursive search.
// For the moment, just tag the ID onto our excluded IDs
$excluded_ids[] = $page->ID;
}
}
// Ensure the array only has unique values
$delete_ids = array_unique( $excluded_ids );
// Loop though the $pages array and actually unset/delete stuff
for ( $i=0; $i<$length; $i++ ) {
$page = & $pages[$i];
// If one of the ancestor pages is excluded, add it to our exclude array
if ( in_array( $page->ID, $delete_ids ) ) {
// Finally, delete something(s)
unset( $pages[$i] );
}
}
// Reindex the array, for neatness
// SWFIXME: Is reindexing the array going to create a memory optimisation problem for large arrays of WP post/page objects?
if ( ! is_array( $pages ) ) $pages = (array) $pages;
$pages = array_values( $pages );
return $pages;
}
/**
* Recurse down an ancestor chain, checking if one is excluded
*
* #param
* #return boolean|int The ID of the "nearest" excluded ancestor, otherwise false
* #author Simon Wheatley
**/
function ep_ancestor_excluded( $page, $excluded_ids, $pages ) {
$parent = & ep_get_page( $page->post_parent, $pages );
// Is there a parent?
if ( ! $parent )
return false;
// Is it excluded?
if ( in_array( $parent->ID, $excluded_ids ) )
return (int) $parent->ID;
// Is it the homepage?
if ( $parent->ID == 0 )
return false;
// Otherwise we have another ancestor to check
return ep_ancestor_excluded( $parent, $excluded_ids, $pages );
}
/**
* {no description}
*
* #param int $page_id The ID of the WP page to search for
* #param array $pages An array of WP page objects
* #return boolean|object the page from the $pages array which corresponds to the $page_id
* #author Simon Wheatley
**/
function ep_get_page( $page_id, $pages ) {
// PHP 5 would be much nicer here, we could use foreach by reference, ah well.
$length = count($pages);
for ( $i=0; $i<$length; $i++ ) {
$page = & $pages[$i];
if ( $page->ID == $page_id ) return $page;
}
// Unusual.
return false;
}
// Is this page we're editing (defined by global $post_ID var)
// currently NOT excluded (i.e. included),
// returns true if NOT excluded (i.e. included)
// returns false is it IS excluded.
// (Tricky this upside down flag business.)
function ep_this_page_included() {
global $post_ID;
// New post? Must be included then.
if ( ! $post_ID ) return true;
$excluded_ids = ep_get_excluded_ids();
// If there's no exclusion array, we can return true
if ( empty($excluded_ids) ) return true;
// Check if our page is in the exclusion array
// The bang (!) reverses the polarity [1] of the boolean
return ! in_array( $post_ID, $excluded_ids );
// fn1. (of the neutron flow, ahem)
}
// Check the ancestors for the page we're editing (defined by
// global $post_ID var), return the ID if the nearest one which
// is excluded (if any);
function ep_nearest_excluded_ancestor() {
global $post_ID, $wpdb;
// New post? No problem.
if ( ! $post_ID ) return false;
$excluded_ids = ep_get_excluded_ids();
// Manually get all the pages, to avoid our own filter.
$sql = "SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'";
$pages = $wpdb->get_results( $sql );
// Start recursively checking the ancestors
$parent = ep_get_page( $post_ID, $pages );
return ep_ancestor_excluded( $parent, $excluded_ids, $pages );
}
function ep_get_excluded_ids() {
$exclude_ids_str = get_option( EP_OPTION_NAME );
// No excluded IDs? Return an empty array
if ( empty($exclude_ids_str) ) return array();
// Otherwise, explode the separated string into an array, and return that
return explode( EP_OPTION_SEP, $exclude_ids_str );
}
// This function gets all the exclusions out of the options
// table, updates them, and resaves them in the options table.
// We're avoiding making this a postmeta (custom field) because we
// don't want to have to retrieve meta for every page in order to
// determine if it's to be excluded. Storing all the exclusions in
// one row seems more sensible.
function ep_update_exclusions( $post_ID ) {
// Bang (!) to reverse the polarity of the boolean, turning include into exclude
$exclude_this_page = ! (bool) $_POST['ep_this_page_included'];
// SWTODO: Also check for a hidden var, which confirms that this checkbox was present
// If hidden var not present, then default to including the page in the nav (i.e. bomb out here rather
// than add the page ID to the list of IDs to exclude)
$ctrl_present = (bool) # $_POST['ep_ctrl_present'];
if ( ! $ctrl_present ) return;
$excluded_ids = ep_get_excluded_ids();
// If we need to EXCLUDE the page from the navigation...
if ( $exclude_this_page ) {
// Add the post ID to the array of excluded IDs
array_push( $excluded_ids, $post_ID );
// De-dupe the array, in case it was there already
$excluded_ids = array_unique( $excluded_ids );
}
// If we need to INCLUDE the page in the navigation...
if ( ! $exclude_this_page ) {
// Find the post ID in the array of excluded IDs
$index = array_search( $post_ID, $excluded_ids );
// Delete any index found
if ( $index !== false ) unset( $excluded_ids[$index] );
}
$excluded_ids_str = implode( EP_OPTION_SEP, $excluded_ids );
ep_set_option( EP_OPTION_NAME, $excluded_ids_str, __( "Comma separated list of post and page IDs to exclude when returning pages from the get_pages function.", "exclude-pages" ) );
}
// Take an option, delete it if it exists, then add it.
function ep_set_option( $name, $value, $description ) {
// Delete option
delete_option($name);
// Insert option
add_option($name, $value, $description);
}
/**
* Callback function for the metabox on the page edit screen.
*
* #return void
* #author Simon Wheatley
**/
function ep_admin_sidebar_wp25() {
$nearest_excluded_ancestor = ep_nearest_excluded_ancestor();
echo ' <div id="excludepagediv" class="new-admin-wp25">';
echo ' <div class="outer"><div class="inner">';
echo ' <p><label for="ep_this_page_included" class="selectit">';
echo ' <input ';
echo ' type="checkbox" ';
echo ' name="ep_this_page_included" ';
echo ' id="ep_this_page_included" ';
if ( ep_this_page_included() )
echo 'checked="checked"';
echo ' />';
echo ' '.__( 'Include this page in lists of pages', EP_TD ).'</label>';
echo ' <input type="hidden" name="ep_ctrl_present" value="1" /></p>';
if ( $nearest_excluded_ancestor !== false ) {
echo '<p class="ep_exclude_alert"><em>';
printf( __( 'N.B. An ancestor of this page is excluded, so this page is too (edit ancestor).', EP_TD), "post.php?action=edit&post=$nearest_excluded_ancestor", __( 'edit the excluded ancestor', EP_TD ) );
echo '</em></p>';
}
// If there are custom menus (WP 3.0+) then we need to clear up some
// potential confusion here.
if ( ep_has_menu() ) {
echo '<p id="ep_custom_menu_alert"><em>';
if ( current_user_can( 'edit_theme_options' ) )
printf( __( 'N.B. This page can still appear in explicitly created menus (<a id="ep_toggle_more" href="#ep_explain_more">explain more</a>)', EP_TD),
"nav-menus.php" );
else
_e( 'N.B. This page can still appear in explicitly created menus (<a id="ep_toggle_more" href="#ep_explain_more">explain more</a>)', EP_TD);
echo '</em></p>';
echo '<div id="ep_explain_more"><p>';
if ( current_user_can( 'edit_theme_options' ) )
printf( __( 'WordPress provides a simple function for you to maintain your site menus. If you create a menu which includes this page, the checkbox above will not have any effect on the visibility of that menu item.', EP_TD),
"nav-menus.php" );
else
_e( 'WordPress provides a simple function for you to maintain the site menus, which your site administrator is using. If a menu includes this page, the checkbox above will not have any effect on the visibility of that menu item.', EP_TD);
echo '</p><p>';
echo _e( 'If you think you no longer need the Exclude Pages plugin you should talk to your WordPress administrator about disabling it.', EP_TD );
echo '</p></div>';
}
echo ' </div><!-- .inner --></div><!-- .outer -->';
echo ' </div><!-- #excludepagediv -->';
}
/**
* A conditional function to determine whether there are any menus
* defined in this WordPress installation.
*
* #return bool Indicates the presence or absence of menus
* #author Simon Wheatley
**/
function ep_has_menu() {
if ( ! function_exists( 'wp_get_nav_menus' ) )
return false;
$menus = wp_get_nav_menus();
foreach ( $menus as $menu_maybe ) {
if ( $menu_items = wp_get_nav_menu_items($menu_maybe->term_id) )
return true;
}
}
/**
* Hooks the WordPress admin_head action to inject some CSS.
*
* #return void
* #author Simon Wheatley
**/
function ep_admin_css() {
echo <<<END
<style type="text/css" media="screen">
.ep_exclude_alert { font-size: 11px; }
.new-admin-wp25 { font-size: 11px; background-color: #fff; }
.new-admin-wp25 .inner { padding: 8px 12px; background-color: #EAF3FA; border: 1px solid #EAF3FA; -moz-border-radius: 3px; -khtml-border-bottom-radius: 3px; -webkit-border-bottom-radius: 3px; border-bottom-radius: 3px; }
#ep_admin_meta_box .inner { padding: inherit; background-color: transparent; border: none; }
#ep_admin_meta_box .inner label { background-color: none; }
.new-admin-wp25 .exclude_alert { padding-top: 5px; }
.new-admin-wp25 .exclude_alert em { font-style: normal; }
</style>
END;
}
/**
* Hooks the WordPress admin_head action to inject some JS.
*
* #return void
* #author Simon Wheatley
**/
function ep_admin_js() {
echo <<<END
<script type="text/javascript">
//<![CDATA[
jQuery( '#ep_explain_more' ).hide();
jQuery( '#ep_toggle_more' ).click( function() {
jQuery( '#ep_explain_more' ).toggle();
return false;
} );
//]]>
</script>
END;
}
// Add our ctrl to the list of controls which AREN'T hidden
function ep_hec_show_dbx( $to_show ) {
array_push( $to_show, 'excludepagediv' );
return $to_show;
}
// PAUSE & RESUME FUNCTIONS
function pause_exclude_pages() {
remove_filter('get_pages','ep_exclude_pages');
}
function resume_exclude_pages() {
add_filter('get_pages','ep_exclude_pages');
}
// INIT FUNCTIONS
function ep_init() {
// Call this function on the get_pages filter
// (get_pages filter appears to only be called on the "consumer" side of WP,
// the admin side must use another function to get the pages. So we're safe to
// remove these pages every time.)
add_filter('get_pages','ep_exclude_pages');
// Load up the translation gear
$locale = get_locale();
$folder = rtrim( basename( dirname( __FILE__ ) ), '/' );
$mo_file = trailingslashit( WP_PLUGIN_DIR ) . "$folder/locale/" . EP_TD . "-$locale.mo";
load_textdomain( EP_TD, $mo_file );
}
function ep_admin_init() {
// Add panels into the editing sidebar(s)
global $wp_version;
add_meta_box('ep_admin_meta_box', __( 'Exclude Pages', EP_TD ), 'ep_admin_sidebar_wp25', 'page', 'side', 'low');
// Set the exclusion when the post is saved
add_action('save_post', 'ep_update_exclusions');
// Add the JS & CSS to the admin header
add_action('admin_head', 'ep_admin_css');
add_action('admin_footer', 'ep_admin_js');
// Call this function on our very own hec_show_dbx filter
// This filter is harmless to add, even if we don't have the
// Hide Editor Clutter plugin installed as it's using a custom filter
// which won't be called except by the HEC plugin.
// Uncomment to show the control by default
// add_filter('hec_show_dbx','ep_hec_show_dbx');
}
// HOOK IT UP TO WORDPRESS
add_action( 'init', 'ep_init' );
add_action( 'admin_init', 'ep_admin_init' )
?>
I think this will be much simpler.
You can do that without any plugins. You need to use wp_get_nav_menu_items function. First create menu in admin. You need to replace testmenu (with you custom menu title) in following code to get this to work properly. I presume you want some real url in href attributes, if not replace it with $counter. And number as id is only valid in html5, so use with caution.
<?php
$items = wp_get_nav_menu_items("testmenu");
$counter = 1;
foreach($items as $item): ?>
<a class="topnav" id="<?php echo $counter; ?>" href="<?php echo $item->url; ?>">WP Page <?php echo $counter; ?> :: <?php echo $item->title; ?></a>
<?php
$counter++;
endforeach;
print_r($items);// remove this after successful implementation, it will show you what you can get from $item(s)
?>
I replied to your original question.
The page IDs excluded by the Exclude Pages plugin (as unchecked in the UI) are stored as a comma separated string in an option called 'ep_exclude_pages'. You can get this by using the following code:
$excluded = get_option( 'ep_exclude_pages', '' );
Hope this helps.