WooCommerce Registration Shortcode - Error messages problems - wordpress

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 );
}

Related

Visual Composer Grid with do_action shortcode is not working

I have visual composer which is packed with total theme. When I put the following grid short code in my page in the editor it works correctly.
[vc_basic_grid post_type="post_type" max_items="10" item="masonryGrid_SlideFromLeft" grid_id="vc_gid:1458178666639-80ebf3775500c87d35de078c3422fe96-10" taxonomies="555"]
However, when I call the exact same code using do_action it gives the following javascript error. I checked the html output and it is the same using do_action like putting the short code in editor.
Error: Syntax error, unrecognized expression: {'status':'Nothing found'}
s
Any help is greatly appreciated.
Well, you can't output contents directly in your templates by using core shortcodes of VC like that.
1. Problem:
For security, besides nonce, VC uses page_id and shortcode_id to check AJAX request/respond data.
The shortcode_id is automatically generated by VC, you can not harcode it.
For example, this is the shortcode you see on admin editor screen:
[vc_basic_grid post_type="post_type" max_items="10" item="masonryGrid_SlideFromLeft" grid_id="vc_gid:1458178666639-80ebf3775500c87d35de078c3422fe96-10" taxonomies="555"]
Let say the page ID is 4269, this is the generated HTML code on front-end:
<!-- vc_grid start -->
<div class="vc_grid-container-wrapper vc_clearfix">
<div class="vc_grid-container vc_clearfix wpb_content_element vc_masonry_grid" data-initial-loading-animation="zoomIn" data-vc-grid-settings="{"page_id":4269,"style":"all-masonry","action":"vc_get_vc_grid_data","shortcode_id":"1458178666639-80ebf3775500c87d35de078c3422fe96-10","tag":"vc_masonry_grid"}" data-vc-request="http://example.com/wp-admin/admin-ajax.php" data-vc-post-id="4269" data-vc-public-nonce="0641473b09">
</div>
</div>
<!-- vc_grid end -->
Now, if page_id and shortcode_id don't match each other, {'status':'Nothing found - $shorcode_id'} will be throw out and no contents will be displayed.
You can find out more inside vc_grid.min.js file.
2. Solution:
Generate a fake page with VC, then copy generated html code to your template file.
Create a template with VC directly.
Use Shorcode Mapper to create your own shorcode.
First you build a new page and add a grid post on it,
then we get
_vc_post_settings
post meta , and try to build a new one
then update post meta data
now we can by pass VC Ajax security check
in the following code "1513628284966-37b8c3ca-d8ec-1" is VC generated guid
you should change it to yours .
$meta = get_post_meta(1365,'_vc_post_settings');
$settings = array();
#$settings['vc_grid_id'] = $meta[0]['vc_grid_id'];
$key = random_int(1513628284966,9513628284966);
$settings['vc_grid_id']['shortcodes'][''.$key.'-37b8c3ca-d8ec-1'] = $meta[0]['vc_grid_id']['shortcodes']['1513628284966-37b8c3ca-d8ec-1'];
$settings['vc_grid_id']['shortcodes'][''.$key.'-37b8c3ca-d8ec-1']['atts']['custom_query'] = "tag=shop";
$settings['vc_grid_id']['shortcodes'][''.$key.'-37b8c3ca-d8ec-1']['atts']['grid_id'] = ''.$key.'-37b8c3ca-d8ec-1';
$n = add_post_meta(1365,'_vc_post_settings',$settings);
return do_shortcode("[vc_basic_grid post_type=\"custom\" show_filter=\"yes\" filter_style=\"dropdown\" item=\"5959\" grid_id=\"vc_gid:".$key."-37b8c3ca-d8ec-1\" filter_source=\"post_tag\" custom_query='tag=".$tag."']");
I've solved.
I had the same problems, with the Visual Composer Editor offered by WpBakery
https://wpbakery.com/
and after understanding the connection between the IDs of the block, and the ID of the Post, I put more attention to the settings of the Block.
There is infact one field called "Element ID", and here we have to put our ID of the Post we are editing.
In my case the Block was a block containing some Posts.
After saving, and viewing the page without the Editor, I was finally able to see the block, and not the message
{"status":"Nothing found"}
I found a solution to this problem.
I modified the woocommerce category template and linked to the woocommerce_archive_description hook to add additional descriptions from some pages, for this I got their id, and then display the content.
echo do_shortcode($post->post_content);
The gallery(media grid) didn't work because there was a mismatch between the page id and the shortcode id. Therefore, the logical solution was to redefine the global variable $post to the $post of the page from which I get the content.
global $post;
$post = get_post( $id );
And it turns out that the post id matches.
After that, don't forget to return the normal $post value;
wp_reset_postdata();
By the way - use this option to load custom styles for wpbakery elements.
echo '<style type="text/css" data-type="vc_shortcodes-custom-css">' . get_post_meta( $id, '_wpb_shortcodes_custom_css', true ) . '</style>';
The whole code
function extra_product_category_desc(){
if( is_product_category() ){
$id = get_term_meta (get_queried_object()->term_id, 'pageId', true);
if($id !== ''){
global $post;
$post = get_post( $id );
echo do_shortcode($post->post_content);
echo '<style type="text/css" data-type="vc_shortcodes-custom-css">' . get_post_meta( $id, '_wpb_shortcodes_custom_css', true ) . '</style>';
wp_reset_postdata();
}
}
}
add_action( 'woocommerce_archive_description', 'extra_product_category_desc', 11 );
You may also try with do_shortcode('');
Like
do_shortcode('[vc_basic_grid post_type="post_type" max_items="10" item="masonryGrid_SlideFromLeft" grid_id="vc_gid:1458178666639-80ebf3775500c87d35de078c3422fe96-10" taxonomies="555"]');
Best Regards,

Wordpress Plugin: Show html only on standard page and not in admin area

I'm writing a plugin and I need to display a piece of text in the WP page, but not in the admin area. How can I do so?
I tried this in the construct:
add_action( 'init', array( $this, 'initPage' ) )
and then:
public function initPage() {
echo 'hello';
}
but the text is displayed also in the admin area. Is there a way to do this? It would be the opposite of the action admin_init I assume.
Proper way to handle it: is_admin()
http://codex.wordpress.org/Function_Reference/is_admin
if(is_admin()) { // do nothing } else {
// function you want to execute.
}
I solved this by adding it to a shortcode action. Like this:
add_shortcode( 'myPlugin', array( $this, 'shortcode' ) );
and:
public function shortcode( $atts ) {
return 'hello';
}
With the above code, 'hello' will only display on the front-end. Not sure if that's the cleaner way to do it, but does the job.
There is no "front-end-only" version of init, however you probably don't want to be doing any output at the init action anyway.
What exactly are you trying to do? Usually, you use an action hook for specific types of things, and causing output very early at something like "init" is rare and weird.

How to edit a post dynamically in wordpress plugin

I have created a small wordpress plugin that displays a list of people in a page via shortcode.
When the user clicks on one of the names from the list, a query_var gets set and my plugin catches the $_GET with the specific id of the person the user just clicked. All very well until now.
My problem is that now I want to display a page with the details (for the clicked element) but I dont seem to be able to edit the content or post that gets to the page and it returns me to the page with the list of people.
My question is how do I edit the post? I have tried adding a add_filter('the_content','my_func') to this, but this does not work since this hook is probably already passed.
I can access the post directly via get_content() or get_post(), but I dont seem to be able to make the page populated new data.
In other words... this does nore seem to work
$fid = $_GET['fid'];
global $wpdb;
$sql = "select * from fighters where fighter_id = {$fid} limit 1";
$fighter = $wpdb->get_row($sql);
$html = $this->_getFighterPageLayout($fighter);
$post = get_post();
$post->post_content = $html;
$post->title = 'test';
$post->private = false;
// or even just global $content = $html;
What am I doing wrong and what ways do I have to edit/update the content/post?
You have to use the hooks of Wordpress to update the content. This works with the add_filter function
Try something like this, it should works
function mytheme_content_filter( $content ) {
// Do stuff to $content, which contains the_content()
// Then return it
return $content;
}
add_filter( 'the_content', 'mytheme_content_filter' );

Redirect from add_menu_page

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();

Custom post type functions.php if statement on action

I am using developing a child theme for Woothemes' Canvas.
I am trying to use functions.php in the child theme to only use actions on my custom post type.
This code doesn't seem to be working:
add_action( 'woo_post_inside_after', 'my_geo_mashup' );
function my_geo_mashup() {
echo GeoMashup::map();
if ($post->post_type == 'listings') {
//My function
}
}
add_action( 'woo_post_inside_before', 'listings_nivo' );
function listings_nivo() {
echo do_shortcode('[nivo source="current-post" ]');
if ($post->post_type == 'listings') {
//My function
}
}
So, I'm unsure how to get the above to work properly and only show these items on the custom post type, or only for the custom post type template single-listings.php (as I only want the map and slider to show on the actual post, not on the blog page (archive.php)
Rather than making the entire $post object global, you can just make $post_type global instead. Ex below.
I'm not exactly sure where that function is being loaded, but make sure you hook somewhere within the post. If the action is before, as far as I know and from experience, the post variable will be null.
Just as a test, try running the action in wp_footer Ex. add_action( 'wp_footer', 'listings_nivo' );
See if that yeilds any results.
if echoing var_dump($post) is still null, well, not sure where to go from there.
So you can try running the below, then run the action in the appropriate place if it works:
function listings_nivo() {
echo do_shortcode('[nivo source="current-post" ]');
global $post_type;
// Diagnostic purposes
echo var_dump($post_type);
if ($post_type == 'listings') {
//My function
}
}
add_action( 'wp_footer', 'listings_nivo' );
Check your error log or turn wp_debug to true in your wp-config.php file if nothing else to see if anything else is going on.
Best of luck!
Inside your function, try adding global $post;. Then to see what you are getting with $post->post_type echo it out to the screen. As long as this gives you "listings", your code should work. If not, there's probably another issue at play.

Resources