Redirect from add_menu_page - wordpress

I have added a menu using add_menu_page which all works correctly, but when clicked I want this menu page to open the post editor for a particular post id.
As a proof of concept i have tried echoing a javascript redirect out into the do function like so...
// Load up the menu page
function register_availability_custom_menu_page() {
add_menu_page('custom menu title', 'Availability', 'add_users', 'options', 'options_do_page');
}
function options_do_page() {
echo "<script type=\"text/javascript\">";
echo "window.location = '/whatever_page.php';";
echo "</script>";
}
This approach does work but I was wondering if it is the best approach, is there a better way to redirect to the page I am after?
UPDATE
I have now also tried using wp_redirect with this code...
add_action( 'admin_menu' , 'admin_menu_new_items' );
function admin_menu_new_items() {
wp_redirect( home_url() );
exit;
}
This gives me a Headers already sent error, can anyone suggest where I am going wrong?

If I'm understanding this correctly, you don't need the redirect. Instead of using a $menu_slug in the function add_menu_page, put the address of the target page, e.g.:
$the_post_title = 'The Portfolio';
add_action( 'admin_menu', 'wpse_59050_add_menu' );
function wpse_59050_add_menu()
{
global $the_post_title;
$our_page = get_page_by_title( $the_post_title );
$settings_page = add_menu_page(
'Edit '.$our_page->post_title,
'Edit '.$our_page->post_title,
'add_users',
'/post.php?post='.$our_page->ID.'&action=edit',
'',
'',
2
);
}
This function is from the following WordPress Answer: Highlighting a Menu Item by Post Name. You'll need some jQuery to do the correct highlighting of this top level menu, check both my and TheDeadMedic answers in that Q.
This other one is useful too: Add highlighting to new Admin Dashboard Menu Item.

Recently did this for pootle page builder, and this AFAIK is the best way,
/**
* Redirecting from Page Builder > Add New page
* #since 0.1.0
*/
function add_new() {
global $pagenow;
if ( 'admin.php' == $pagenow && 'page_builder_add' == filter_input( INPUT_GET, 'page' ) ) {
header( 'Location: ' . admin_url( 'whatever-page.php' ) );
die();
}
}
add_action( 'admin_init', 'add_new' );
Replace page_builder_add with your page slug and admin_url( 'whatever-page.php' ) with url you wanna redirect to.
We always use scrutinizer-ci for best code practices and maintain code score greater than 9.5/10, so all code (Including this) is secure and optimized ;)
Lemme know how it works for ya.
Cheers

I found a 2-step solution that doesn't use JS/JQ.
Step 1:
Near the top of your script, put the following PHP to display CSS that hides your first page:
add_action('admin_head', 'hide_my_first_page');
function hide_my_first_page(){
echo '<style>
a[href="admin.php?page=admin_menu_slug"] + ul > li.wp-first-item{
display: none;
}
</style>';
}
Where admin_menu_slug is the 4th argument passed to add_menu_page();.
Step 2:
Take the function of the page you want to run and pass it as the 5th argument in add_menu_page();

Related

How to set a WooCommerce email template as default for all emails

I’m looking for a way to send all WordPress emails using a custom WooCommerce template so all emails will look the same.
The path to the template would be:
woocommerce/emails/my-custom-woocommerce-template.php
Does it have to all be templatized in a single file? If not, a combination of these entry points can probably get you the standardization you're looking for:
email-header.php lets you customize the start of the email including the header image (if you need to do more than change its URL). It opens the layout tags for the rest of the email content
email-footer.php lets you customize the footer, and closes the layout tags started in the header.
email-styles.php or the woocommerce_email_styles filter let you customize the CSS (see some gotchas in my article here).
Various actions/filters are scattered throughout the emails for customizing individual parts.
You can use the below function. It is working
function myplugin_woocommerce_locate_template( $template, $template_name, $template_path ) {
global $woocommerce;
// List of all templates that should be replaced with custom template
$woo_templates = array(
'emails/admin-new-order.php',
'emails/admin-failed-order.php',
'emails/admin-cancelled-order.php',
'emails/customer-completed-order.php',
'emails/customer-new-account.php',
'emails/customer-note.php',
'emails/customer-on-hold-order.php',
'emails/customer-processing-order.php',
'emails/customer-refunded-order.php',
'emails/customer-reset-password.php',
);
//Check whether template is in replacable template array
if( in_array( $template_name, $woo_templates ) ){
// Set your custom template path
$template = your_template_path.'emails/my-custom-woocommerce-template';
}
// Return what we found
return $template;
}
add_filter( 'woocommerce_locate_template', 'myplugin_woocommerce_locate_template', 10, 3 );
add_filter( 'wp_mail', 'your_wp_mail_action' ); // $args = compact( 'to', 'subject', 'message', 'headers', 'attachments' )
function your_wp_mail_action( $args ) {
global $your_prefix_your_email_args; // the args you could use in my-custom-woocommerce-template file
$your_prefix_your_email_args = $args;
ob_clean();
get_template_part( 'woocommerce/emails/my-custom-woocommerce-template' );
$args['message'] = ob_get_clean();
// ... your logic
return $args;
}
To view and update email settings, log into your website dashboard. In the left-hand menu, click on WooCommerce → Settings.
There, you’ll find several options tabs at the top. Click Emails to view the following templates
you can custom all as you want

Where exactly is the "Before Header Content hook" in Wordpress?

I want to add a little code to the "Before Header Content hook" but I don't know where that is... Can you please help me?
Try:
add_action('init', 'process_post');
function process_post()
{
echo "test";
}
this is a modified version of #ajay 's solution
if you are going to use this, then you have to make sure that the current user is not an admin using is_admin() function.. and only display it if he is not an admin ...
why !?
because if you didn't, it may mess up the wp-admin of your website..
add_action('init', 'process_post');
function process_post()
{
if (!is_admin()) {
echo "test";
}
}
This could be tricky simply because every theme differs with how the loop is displayed, however you could create a plugin to use the loop_start action, which is called before the first post of the standard WP loop:
add_action( 'loop_start', 'test_loop_start' );
function test_loop_start( $query ){
echo 'this is my inserted text';
}
Now using this would display it every single time the loop is called (whether on a page, a post, category page, search page, etc.), which you may not want.
add_action( 'loop_start', 'test_loop_start' );
function test_loop_start( $query ){
if(is_category() OR is_singular()) {
echo 'this is my inserted text';
}
}

Change Wordpress logo click redirection

I would like to change the logo redirection when clicked. Right now when you click on the logo, the user is redirected to the homepage but I want it to redirect to another site. How do I do this?
I agree with Stu Mileham. Another way to implement what you are asking for would be to use JavaScript / jQuery.
Save the following code to a .js file (eg. pageRedirect.js, let's say placed in a js folder inside your theme's root folder):
(function($) {
$(document).ready(function() {
$('#pageLogo').on( "click", function(event) {
event.preventDefault();
window.location.assign("http://www.google.com/");
});
});
})(jQuery);
To make the previous code work, you would have to select somehow the page logo via jQuery.
On the previous code this is achived via $('#pageLogo') since I have made the assumption that your logo has an id with the value pageLogo.
Of course, to enable your theme to use this pageRedirect.js file, you have to enqueue it by placing the following code to your theme's functions.php file:
/**
* Enqueue pageRedirect script.
*/
function pageRedirect_scripts() {
wp_enqueue_script( 'page-redirect-js', get_template_directory_uri() . '/js/pageRedirect.js', array('jquery'), '20150528', true );
}
add_action( 'wp_enqueue_scripts', 'pageRedirect_scripts' );
Code Explanation:
//-jQuery selects html element with id='pageLogo'
//-when it is clicked, it calls a function in which it passes the event
$('#pageLogo').on( "click", function(event) {
//prevents page from redirecting to homepage
event.preventDefault();
//redirects to your desired webpage
window.location.assign("http://www.google.com/");
});
If you don't have the option to change the link from admin then you will have to edit your theme's header.php file (most likely, depends on how the theme is built though).
Many themes have a tag similar to the following:
<img src="logo.jpg">
You would need to change this to:
<img src="logo.jpg">
I've added the target tag to open the site in a new window, this is my personal preference when re-directing to a different site but it's optional.
Your theme files might look very different to this, it's impossible to know for sure without seeing some code, but this should give you an idea.
Also be aware that your changes could be overwritten by a theme update. This can be avoided by creating a child theme.
https://codex.wordpress.org/Child_Themes
Depends on your theme
Some theme creators gives you the possibility to change the link from admin
Some theme creators just believe that clicking the logo you need to go on homepage - so you need to edit the theme
Depending upon the theme you are using, you can try one of the following options.
Explore the admin options and see if the theme provides a direct way to change the link on the logo.
If not found in admin options, try looking for the code in header.php. Do an inspect element on your logo and see the html code surrounding the logo file, If the code is directly present in header.php, your task is simple. Just change the code to update the URL, instead of reading it from home_url(). Something like <a href="<?php echo home_url();?>"> will need to be replaced with <a href="https://www.example.com">
The other option to look for is get_custom_logo. Some themes get the logo code from this function. You can apply a filter to change the home_url just before this method is called in your theme and then remove filter afterwards. Or else you can copy the code from wordpress and update it with a differently named function say get_custom_link_logo in functions.php then where'ver your theme is using get_custom_logo you can use get_custom_link_logo instead of that.
function get_custom_link_logo ( $blog_id = 0 ) {
$html = "";
$switched_blog = false;
if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
switch_to_blog( $blog_id );
$switched_blog = true;
}
$custom_logo_id = get_theme_mod( 'custom_logo' );
// We have a logo. Logo is go.
if ( $custom_logo_id ) {
$custom_logo_attr = array(
'class' => 'custom-logo',
'itemprop' => 'logo',
);
/*
* If the logo alt attribute is empty, get the site title and explicitly
* pass it to the attributes used by wp_get_attachment_image().
*/
$image_alt = get_post_meta( $custom_logo_id, '_wp_attachment_image_alt', true );
if ( empty( $image_alt ) ) {
$custom_logo_attr['alt'] = get_bloginfo( 'name', 'display' );
}
/*
* If the alt attribute is not empty, there's no need to explicitly pass
* it because wp_get_attachment_image() already adds the alt attribute.
*/
$html = sprintf( '%2$s',
esc_url( "https://www.example.com" ),
wp_get_attachment_image( $custom_logo_id, 'full', false, $custom_logo_attr )
);
}
// If no logo is set but we're in the Customizer, leave a placeholder (needed for the live preview).
elseif ( is_customize_preview() ) {
$html = sprintf( '<img class="custom-logo"/>',
esc_url( "https://www.example.com" )
);
}
if ( $switched_blog ) {
restore_current_blog();
}
/**
* Filters the custom logo output.
*
* #since 4.5.0
* #since 4.6.0 Added the `$blog_id` parameter.
*
* #param string $html Custom logo HTML output.
* #param int $blog_id ID of the blog to get the custom logo for.
*/
return apply_filters( 'get_custom_logo', $html, $blog_id ); }
This might not cover all the use cases, but you get the idea. Depending upon the theme you'll have a similar solution for your case. The important thing to figure out which case you fall under will be to identify the code where html for your logo is getting added. header.php is a good starting point.
Use this javascript in the header or footer of your theme:
<script>
document.getElementsByClassName("site-logo")[0].getElementsByTagName('a')[0].href="https://www.test.com";
</script>
i am assuming that site-logo is the class name of your LOGO.

WooCommerce Registration Shortcode - Error messages problems

I am currently creating a widget to display the registration form on a WordPress website that uses WooCommerce. For now, I only have 3 basic fields which are email, password, repeat password. I'm looking forward to add more WooCommerce fields, but want to solve that problem before jumping to the next step.
I'm having some problems with the messages output (wrong password, account already exists, etc).
I searched on the web and there was no shortcode already built for WooCommerce registration, beside their registration page. So I went ahead and created a shortcode, with a template part.
function custom_register_shortcode( $atts, $content ){
global $woocommerce;
$form = load_template_part('framework/views/register-form');
return $form;
}
add_shortcode( 'register', 'custom_register_shortcode' );
This is a snippet I use to get the template part inside a variable, since the default function would "echo" the content instead of "returning" it.
function load_template_part($template_name, $part_name=null) {
ob_start();
get_template_part($template_name, $part_name);
$var = ob_get_contents();
ob_end_clean();
return $var;
}
So, the problem is, when I call woocommerce_show_messages or $woocommerce->show_messages(); from my template part, nothing is showing, or if it is, it shows at the top of the page.
I did try to put the calls inside my shortcode function:
function custom_register_shortcode( $atts, $content ){
global $woocommerce;
$woocommerce->show_messages();
$form = load_template_part('framework/views/register-form');
return $form;
}
add_shortcode( 'register', 'custom_register_shortcode' );
Doing so, the message output inside the <head> tag, which is not what I want.
I tried to do the same trick with ob_start(), ob_get_contents() and ob_clean() but nothing would show. The variable would be empty.
I also did try to hook the woocommerce_show_messages to an action as saw in the core:
add_action( 'woocommerce_before_shop_loop', 'woocommerce_show_messages', 10 );
For something like:
add_action( 'before_registration_form', 'woocommerce_show_messages');
And I added this in my template-part:
<?php do_action('before_registration_form'); ?>
But I still can't manage to get the error messages show inside the box. It would always be inserted in the <head>
I will share final solution when everything is done.
Thanks for your time,
Julien
I finally got this working by hooking a custom function to an action which is called in my header.php
I guess hooking functions inside template part does not work as intended.
In header.php, I got this:
do_action('theme_after_header');
And here's the hooked function. Works perfectly.
function theme_show_messages(){
woocommerce_show_messages();
}
add_action('theme_after_header', 'theme_show_messages');
However, I will look into 'unhooking' the original show message function since it might show twice. Need to test some more ;)
You can also just use the [woocommerce_messages] shortcode in your template where you want it displayed
Replying to a bit of an old question, but you can also try the following:
$message = apply_filters( 'woocommerce_my_account_message', '' );
if ( ! empty( $message ) ) {
wc_add_notice( $message );
}

Translate product category|tag title for JigoShop with qTranslate

qTranslate creates additional language fields for products pages in JigoShop but not also for category|tags product as it does for posts.
If I put in the title of a menu item <!--:en-->title<!--:--><!--:fr-->title<!--:--> i'll get the translation I want. But when creting a new category|tag title the <!--:--> is striped out. How can I enable comments tags for cat|tag title?
Another option is to use [:en]Title[:fr]Titre in the same title field when creating a new category|tag product. On the admin panel I see the proper text for the language selected but for end user i see [:en]Title[:fr]Titre.
I found this link https://wordpress.stackexchange.com/questions/28165/translating-a-custom-taxonomy and according to this answer http://www.qianqin.de/qtranslate/forum/viewtopic.php? f=4&t=2045&start=0#p7380 I addet in functions.php
add_action('jigoshop_add_form', 'qtrans_modifyTermFormFor');
add_action('jigoshop_edit_form', 'qtrans_modifyTermFormFor');
Did not work. I don't see aditional translations fields for categories|tags in JigoShop.
The basic question is:
How do I translate product categories|tags in JigoShop using qTranslate?
I was having very similar problem. I found a solution here: http://www.qianqin.de/qtranslate/forum/viewtopic.php?f=3&t=4064&start=10#p12940
Basically, all you have to do is to rename all the categories as suggested in the answer above, then add to your theme's functions.php file:
function p_filter_categories( $categories ) {
if ( is_array( $categories ) ) {
foreach ( $categories as $i => $cat ) {
$categories[ $i ]->name = __( $cat->name );
}
} else {
$categories->name = __( $categories->name );
}
return $categories;
}
add_filter( 'get_the_categories', 'p_filter_categories', 10 );
add_filter( 'get_the_terms', 'p_filter_categories', 10 );
add_filter( 'get_term', 'p_filter_categories', 10 );
Hope that helps!
Not the ideal solution but works.
In JigoShop/edit product category/name:
[:en] Big [:fr] Grand
In functions.php
function translate_q ($echo) {
if (function_exists('qtrans_split')) {
$selectLanguage = qtrans_split($echo);
return $selectLanguage[qtrans_getLanguage()];
} else {
return $echo;
}
}
qtrans_split and qtrans_getLanguage are functions created by qTranslate.
From JigoShop plugin directory I opened jigoshop_template_functions.php, I grabbed from jigoshop_breadcrumb() function all the echos in $echo variable and at the end I have:
echo function_exists('translate_q') ? translate_q($echo) : $echo;
You will have to do the same thing in other places in JigoShop. I posted here to be a starting point.

Resources