I have a client site running on WordPress. It uses WooThemes Canvas as its base theme (with a customized child theme), and utilizes the Time.ly All-in-one-Event Calendar. It can be viewed here.
The design I came up with required me to move the page/post titles outside the main content area. I followed the instructions on this WooThemes customization document, and made modifications based on the comments so that it would also work for posts and the Time.ly event postings. The entries in my functions.php file looked like this:
add_filter( 'the_title', 'woo_custom_hide_single_post_title', 10 );
function woo_custom_hide_single_post_title ( $title ) {
if ( is_singular( array( 'post', 'ai1ec_event' ) ) && in_the_loop() ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_post_title()
add_filter( 'the_title', 'woo_custom_hide_single_page_title', 10 );
function woo_custom_hide_single_page_title ( $title ) {
if ( is_page() && in_the_loop() ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_page_title()
// Add Titles above Content Area on all Posts & Pages
add_action( 'woo_content_before_singular-post', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-ai1ec_event', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-page', 'woo_custom_add_title', 10 );
function woo_custom_add_title () {
if ( ! is_page_template(array('template-biz.php', 'template-brewpub.php')) ) {
global $post;
$title = '<h1 class="page-title">' . get_the_title( $post->ID ) . '</h1>' . "";
echo '<div id="title_container"><header class="col-full">';
echo $title;
woo_post_meta();
echo '</header></div>';
}
} // End woo_custom_add_post_title()
This produced some undesirable results, which can be seen on the DEV site I setup for this post (dev.thebrewworks.com):
Since the Time.ly event calendar also uses the_title to display it's events, in the three instances I used the calendar inside a page loop (the homepage and the two restaurant location pages), the event titles don't show up. This was confirmed by creating a Test Page (dev.thebrewworks.com/test-page), where you can see two instances of the calendar inside the loop, and one outside (in the sidebar). The two instances in the Loop have no titles, while the sidebar does.
Supressing the_title in the Loop didn't suppress the Post Meta, which still shows up in the main content area, but I want it under the title in the new DIV, so reposting woo_post_meta outside the Loop leaves me with two instances of the Post Meta.
In order to get the site live I had to make some concessions in my functions.php file:
// Hide Titles on All Posts & Pages
add_filter( 'the_title', 'woo_custom_hide_single_post_title', 10 );
function woo_custom_hide_single_post_title ( $title ) {
if ( is_singular( array( 'post', 'ai1ec_event' ) ) && in_the_loop() ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_post_title()
add_filter( 'the_title', 'woo_custom_hide_single_page_title', 10 );
function woo_custom_hide_single_page_title ( $title ) {
if ( is_page() && in_the_loop() && is_page_template( array('page.php', 'template-contact.php' ) ) ) { $title = ''; }
return $title;
} // End woo_custom_hide_single_page_title()
// Add Titles above Content Area on all Posts & Pages
add_action( 'woo_content_before_singular-post', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-ai1ec_event', 'woo_custom_add_title', 10 );
add_action( 'woo_content_before_singular-page', 'woo_custom_add_title', 10 );
function woo_custom_add_title () {
if ( ! is_page_template(array('template-biz.php', 'template-brewpub.php')) ) {
global $post;
$title = '<h1 class="page-title">' . get_the_title( $post->ID ) . '</h1>' . "";
echo '<div id="title_container"><header class="col-full">';
echo $title;
woo_post_meta();
echo '</header></div>';
}
} // End woo_custom_add_post_title()
// Disable Post Meta
function woo_post_meta() {}
?>
Note the changes:
I disabled the post_meta completely. Not exactly what I was looking for, but better than having it show up twice.
I modified the function that disables the page title so that it only works on pages that use certain templates (the three instances I mentioned above use the Business Template in Canvas that already suppresses the page title). This would require me to go in and add each new page template that I want to suppress the title on, though...and on top of that, it's not working. Take a look at the live site. The page title is showing up twice on static pages. Once inside the white content area and once outside in the yellow header.
I'm no PHP-developer...I'm more of an Design/HTML/CSS person. I know enough to be dangerous...how to modify existing code, etc., but not necessarily how to write my own from scratch. I have no idea if the way I came up with things is even the best/most elegant way to go about it. Now that you have all the facts, here are my questions:
In an ideal world, the Post Meta would ONLY show up on the blog entries (not on the calendar entries...no need for them there, really), and OUTSIDE the main content area underneath the page title that I moved. How can I achieve this? I'm guessing it's going to be some sort of conditional statement that removes the woo_post_meta from all instances inside the loop, and adds it to the woo_custom_add_title ONLY if it's a standard post, but how to get there I have no idea.
How can I suppress the_title that shows up at the top of the content area on ALL static pages, regardless of template, but have it not affect instances of the_title that appear elsewhere in the loop (like the calendar syndication). In my head there has to be a way to indicate that you ONLY want to disable the_title if it's in a certain div/id, etc., but again...only enough to be dangerous, unless I see it done elsewhere, I can't come up with the solution on my own.
Thanks in advance for your input.
Related
Followed through on this post for manipulating woocommerce menu.
This plugin code:
function product_subcategories( $args = array() ) {
$parentid = get_queried_object_id();
$args = array(
'parent' => $parentid
);
$terms = get_terms( 'product_cat', $args );
if ( $terms ) {
echo '<ul class="product-cats">';
foreach ( $terms as $term ) {
echo '<li class="category">';
woocommerce_subcategory_thumbnail( $term );
echo '<h2>';
echo '<a href="' . esc_url( get_term_link( $term ) ) . '" class="' . $term->slug . '">';
echo $term->name;
echo '</a>';
echo '</h2>';
echo '</li>';
}
echo '</ul>';
}
}
add_action( 'woocommerce_before_shop_loop', 'product_subcategories', 50 );
Fires twice.
Why is that??
Thanx
EDIT
Original post link: Display WooCommerce Categories, Subcategories, and Products in Separate Lists
Woocommerce does allow you to register two events with the same tag source. Thus, if the file is loaded twice (e.g. if you use include/require instead of include_once/require_once) it can cause this problem: check it anyhow(!).
The hook itself is called twice in woocommerce, so technically it is possible that the hook is called twice. I do however not know if both templates are loaded in the same call... You might however have registered the call twice w/o knowing: thus check your code for another call to this function, perhaps with a different tag (other than woocommerce_before_shop_loop).
Update:
With your code you are just doing what WooCommerce is already doing, that's why you are seeing duplicated category/subcategory menu items and you say that it's "fired twice".
Anyway, if you keep your code, and then you want to remove that WooCommerce generated category/subcategory items, you can use this hooked function:
add_filter('woocommerce_product_subcategories_args', function( $args ){
$args['taxonomy']= '';
return $args;
});
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This will remove the WooCommerce duplicated items…
Original answer:
The woocommerce_before_shop_loop hook:
has no arguments (no need to add $args = array() )
is called many times, but only fired once. Check it replacing your code by this:
add_action( 'woocommerce_before_shop_loop', function(){
wc_print_notice('test message', 'notice');
}, 50 );
Kindly, as your question is not very explicit and detailed, we don't really know what is your problem and can't help you further than that…
While the previous answers are no doubt accurate, I don't think they are truly the reason for multiple calls. I believe the true reason is that you're simply receiving multiple HTTP requests when, to your eyes, it seems like there should only be one. Remember, your plugin is going to load upon every interaction with WP, not just the ones for your application. So /wp-cron.php links, for example, will trigger your plugin "invisibly", as will many other requests like Ajax or JSON calls. Please see https://wordpress.stackexchange.com/questions/170768/wordpress-plugin-executing-code-twice#answer-170784.
I am trying to apply specific functions to a certain page ID in Woocommerce.
However, it does not seem to apply. I have looked at both Wordpress and Woommerce conditional tags (https://docs.woocommerce.com/document/conditional-tags/).
The simple code I am testing is shown below, but even that is not working.
if ( is_product()) {
echo ' HALLO sdfdsfsdfsdfsdf ';
}
I have also tried with page_id and post_id but cannot get this to work.
I have added this code to my functions.php in my child theme.
Does anybody know to to write a specific function only for a specific product page (I know the value).
Method - 1
is_page() relies on a complete global $wp_query object. If you call it before the action template_redirect has been fired, it might be impossible to get that data.
add_filter( 'template_include', function( $template ) {
if ( is_product() )
echo 'HELLO';
return $template;
});
Method - 2
The WordPress/WooCommerce conditional tags won’t work until after the wp action is fired, making it the earliest point at which you can use the tags. You can view the entire list, and the order of the core WordPress actions at the Action Reference page.
add_action( 'wp', 'init' );
function init() {
if ( is_shop() ) {
echo 'HELLO, this works!';
}
}
I am new to php and I am trying to remove a page title on the homepage with a function in wordpress. I searched a lot for this and couldn't find an answer. I don't want to use css display:none;. I came up with this in the functions.php but it does not work.
function remove_title() {
if (is_home() || is_front_page()) {
$title = '';
} else {
return = $title ;
}
}
add_filter( 'the_title', 'remove_page_title', 10, 2 );
function remove_page_title( $title, $id ) {
if( is_home() || is_front_page() )
return '';
return $title;
}
Would you please try above code?
Though a solution has already been posted, I wanted to bring up that the the_title() is already initiated at the page.php level (or in any template part or partial view within it). The current solution removes the title content and returns a title with value "Untitled". It basically, thinks the page hasn't bene titled. Not a good solutions in my opinion
To remove it programmatically, you have to go to where the page title is initiated in page.php and
replace
the_title( '<h1 class="entry-title">', '</h1>' );
with
if(is_home() || is_front_page() || is_page("any_additional_page")){
// do nothing
} else {
the_title( '<h1 class="entry-title">', '</h1>' );
}
This method is particularly helpful when you need to give different classes to each page title depending on the pages. For example, your home page, your content pages, and your shop pages may all look different or some could be intentionally omitted
Also, if you like to go with the plugin then Hide title plugin can do the job. It hides the title on pages and posts via the edit post screen.
I am running a wholesale shop on Woocommerce. Login is required to see the prices. This is set up and working properly. Now I wish to add a logon form on every product page to only show to visitors (not logged on users).
I am using the WooCommerce Catalog Visibility plugin. This plugin offers the functionality I described above, but my theme is somehow messing it up. The plugin author says to talk to the theme developer and the theme developer says to talk to the plugin author. So now I am trying to find a workaround.
First issue: The plugin comes with a shortcode [woocommerce_logon_form] that will display a logon form. I don't want to manually add this to every existing product since I have thousands of products on my site. I am looking for a way to get it in through the code for the product page layout.
I found this code (to be added to the functions.php) to work well:
// adds notice at single product page above add to cart
add_action( 'woocommerce_single_product_summary', 'return_policy', 20 );
function return_policy() {
echo '<p id="rtrn">30-day return policy offered. See Terms and Conditions for details.</p>';
}
However, it will only show text. The short code won't work when added instead of the sample text.
Second issue: The short code shows the form even when the customer is already logged in.
I am currently using this nice code that shows or hides content depending on whether the user is logged in or not:
add_shortcode( 'access', 'access_check_shortcode' );
function access_check_shortcode( $attr, $content = null ) {
extract( shortcode_atts( array( 'capability' => 'read' ), $attr ) );
if ( current_user_can( $capability ) && !is_null( $content ) && !is_feed() )
return $content;
return '';
}
add_shortcode( 'visitor', 'visitor_check_shortcode' );
function visitor_check_shortcode( $atts, $content = null ) {
if ( ( !is_user_logged_in() && !is_null( $content ) ) || is_feed() )
return $content;
return '';
}
That shortcode works perfectly for text, but not with other shortcodes.
So the combination of these short codes: [visitor][woocommerce_logon_form][/visitor] will not show the logon form to visitors. Instead it will only show them this as text [woocommerce_logon_form].
Please help! I am sure this is probably easily fixed by someone with coding skills.
I appreciate your effort to answer to this question. Keep in mind that my understanding of code is very limited and it would be great if you can also point out in which file to add or modify code.
To make your shortcode working in php code or in php/html code you need to use a native WordPress function do_shortcode() … You can use it with your shortcode for example in your 1st function this way:
add_action( 'woocommerce_single_product_summary', 'return_policy', 20 );
function return_policy() {
echo do_shortcode('[woocommerce_logon_form]');
}
And this will work…
To see all the different hooks you can use instead of woocommerce_single_product_summary, please see this 2 templates code to chose in case a more convenient hook:
WooCommerce single-product.php template
WooCommerce content-single-product.php template
You can also add it the same way in one of your existing short codes, this way:
add_shortcode( 'visitor', 'visitor_check_shortcode' );
function visitor_check_shortcode( $atts, $content = null ) {
if ( ( !is_user_logged_in() && !is_null( $content ) ) || is_feed() )
return do_shortcode('[woocommerce_logon_form]');
return '';
}
And this will work too.
See as reference this answer: Change markup in WooCommerce shortcode output
So as you can see your problem is solved on both issues
How do I modify a page title for specific pages in shortcode?
The following will change the title but it executes for every page. I need more control over where it executes.
function assignPageTitle(){
return "Title goes here";
}
add_filter('wp_title', 'assignPageTitle');
Is there a way to call the above in a shortcode function? I know how to use do_shortcode() but the above is a filter.
My goal is to modify the page title based on a URL parameter. This only happens for specific pages.
Although WordPress shortcodes was not designed to do this, it can be done. The problem is shortcodes are processed AFTER the head section is sent so the solution is to process the shortcode BEFORE the head section is sent.
add_filter( 'pre_get_document_title', function( $title ) {
global $post;
if ( ! $post || ! $post->post_content ) {
return $title;
}
if ( preg_match( '#\[mc_set_title.*\]#', $post->post_content, $matches ) !== 1 ) {
return '';
}
return do_shortcode( $matches[0] );
} );
add_shortcode( 'mc_set_title', function( $atts ) {
if ( ! doing_filter( 'pre_get_document_title' ) ) {
# just remove the shortcode from post content in normal shortcode processing
return '';
}
# in filter 'pre_get_document_title' - you can use $atts and global $post to compute the title
return 'MC TITLE';
} );
The critical point is when the filter 'pre_get_document_title' is done the global $post object is set and $post->post_content is available. So, you can find the shortcodes for this post at this time.
When the shortcode is normally called it replaces itself with the empty string so it has no effect on the post_content. However, when called from the filter 'pre_get_document_title' it can compute the title from its arguments $atts and the global $post.
Taken from the WordPress Codex
Introduced in WordPress 2.5 is the Shortcode API, a simple set of
functions for creating macro codes for use in post content.
This would suggest that you can't control page titles using shortcodes as the shortcode is run inside the post content at which point the title tag has already been rendered and is then too late.
What is it exactly that you want to do? Using the Yoast SEO Plugin you can set Post and Page titles within each post if this is what you want to do?
You could create your custom plugin based on your URL parameters as so:
function assignPageTitle(){
if( $_GET['query'] == 'something' ) { return 'something'; }
elseif( $_GET['query'] == 'something-else' ) { return 'something-else'; }
else { return "Default Title"; }
}
add_filter('wp_title', 'assignPageTitle');