Skip Certain Gutenberg Block in Loop - wordpress

I have some WordPress Gutenberg blocks that I want to display in a different part of my theme. I know how to find the block and display it in my theme's template, but I don't know how to stop the block from showing with the rest of the blocks in the loop.
To clarify as an example: I have one block that I want to have in the admin area with the other blocks but I don't want to display it in the loop content. I need a way to skip it or filter it out in the normal loop. Then I use this code to output in another area of my theme:
function be_display_post_blockquote() {
global $post;
$blocks = parse_blocks( $post->post_content );
foreach( $blocks as $block ) {
if( 'lazyblock/area-2' === $block['blockName'] ) {
echo render_block( $block );
break;
}
}
}
The problem with the above code is it duplicates the block to show with the other "normal" loop content and also in my new location. Can you help me write a function/filter to stop specific blocks from showing up in the loop?

I figured this out...
Here is the function to filter the content of the loop and remove a specific block from the output because you already outputted the content of that specific block in another location in your theme or theme template file.
//If single block exists on page or post don't show it with the other blocks
function remove_blocks() {
// Check if we're inside the main loop in a post or page
if ( ( is_single() || is_page() ) && in_the_loop() && is_main_query() ) {
//parse the blocks so they can be run through the foreach loop
$blocks = parse_blocks( get_the_content() );
foreach ( $blocks as $block ) {
//look to see if your block is in the post content -> if yes continue past it if no then render block as normal
if ( 'lazyblock/top-of-page' === $block['blockName'] ) {
continue;
} else {
echo render_block( $block );
}
}
}
}
add_filter( 'the_content', 'remove_blocks');

Related

Using render_block only on Gutenberg blocks which aren't nested

I want to add a wrapper div to Gutenberg blocks so I can do things like full width images and other custom ACF blocks. I found this on the WP documentation:
function block_wrap_filter( $block_content, $block ) {
if ( empty( trim( $block_content ) ) ) {
return $block_content;
}
$blockid = $block['id'];
echo $blockid;
return sprintf(
'<section class="outer-%1$s"><div class="inner">%2$s</div></section>',
sanitize_title( $block['blockName'] ),
$block_content
);
}
add_filter( 'render_block', 'block_wrap_filter', 10, 2 );
This works great except for the fact that it will apply the wrappers to nested blocks. Is there anyway to filter it so it doesn't apply to blocks that are within other blocks?
I've looked to see if there's any hooks or if the $block var lists itself as a child or anything but can't see anything I can make use of there.
I thought maybe if I could get the ID of the block and then see if the child has a related ID, then maybe I could use some sort of php if statement to wrap the filter. But I haven't been able to get $block to give an ID.

How do I change the css of my page based on woocommerce parent product category?

I want to change the css of my page based on the selected woocommerce parent product category. I want to change the colour scheme of my navbar and footer based on these categories. I have already created the style sheets to achieve this and if I change the css path in developer options on my browser it works.
I have tried editing the taxonomy-product_cat.php file and I am able to successfully navigate to a different page using the following code:
// Get current category slug
global $wp_query;
$cat_slug = $wp_query->query_vars['product_cat'];
// Call template conditionally
if($cat_slug == 'sport-bikes') {
wc_get_template( 'archive-land.php' );
} else {
wc_get_template( 'archive-product.php' );
}
The two issues I've encountered here are:
1) This only works for the specific sub-category - If I use the parent category "land" it does not work.
2) I'm unable to edit the css from whatever template I use. In this instance I created the "archive-land.php" template.
I have also tried adding the following to my functions.php file:
// add taxonomy term to body_class
function woo_custom_taxonomy_in_body_class( $classes ){
if( is_singular( 'product' ) )
{
$custom_terms = get_the_terms(0, 'product_cat');
if ($custom_terms) {
foreach ($custom_terms as $custom_term) {
$classes[] = 'product_cat_' . $custom_term->slug;
}
}
}
return $classes;
}
add_filter( 'body_class', 'woo_custom_taxonomy_in_body_class' );
Based on the following solution on this link:
Woocommerce custom style for specific product category?
The issues encountered here are:
1) The body class remains as " customize-support"
2) My css files are specific to changing the colour of the headers and footers
Basically I just want to change the colour scheme of my headers and footers based on the parent product category.
Edit:
Partially solved - I've created a separate "archive-land.php" and "archive-marine.php" and added the following code to the top of each file calling the css files I need:
<?php
function c3land_theme_styles(){
wp_enqueue_style( 'hoverland', get_template_directory_uri() . '/css/hoverland.css' );
wp_enqueue_style( 'land', get_template_directory_uri() . '/css/land.css' );
}
add_action( 'wp_enqueue_scripts','c3land_theme_styles' );
?>
This takes care of switching the css but I still need to have them changed on the parent category rather than the sub-categories here is my updated code on taxonomy-product_cat.php file:
// Get current category slug
global $wp_query;
$cat_slug = $wp_query->query_vars['product_cat'];
// Call template conditionally
if($cat_slug == 'sport-bikes') {
wc_get_template( 'archive-land.php' );
}
if($cat_slug == 'outboard-motors') {
wc_get_template( 'archive-marine.php' );
}
else {
wc_get_template( 'archive-product.php' );
}
1) Are there any potential issues in my initial proposed solution or is there a more elegant / proper way of achieving this ?
2) How to I call my "archive-land.php or archive-marine.php" by the parent category ?

hide wordpress posts and categories for not logged in users

Basically I handled this issue by overriding parent theme files in child theme.
i.e., by using
if( is_user_logged_in() ){
...................
wordpress loop
}
I had to do this for every template ( wherever there is wordpress loop )
Though I didn't have to do this for displaying sidebars as if there was category in widget and whenever user clicks on it to view it, it would automatically say you don't have proper privileges to view this content.
So, my question is, is there any better way to hide wordpress content ( this may be anything, like normal posts, custom post types,.. ) from just visitors.
function bt_hide_from_guestes( $content ) {
global $post;
if ( $post->post_type == 'post' ) {
if ( !is_user_logged_in() ) {
$content = 'Please login to view this post';
}
}
return $content;
}
add_filter( 'the_content', 'bt_hide_from_guestes' );
Above code didn't help
It looks like your filter function should work for you. Try setting a priority and the "accepted arg" number:
add_filter( 'the_content', 'bt_hide_from_guestes', 10, 1 );

How to use If condition for wordpress plugin Widget Logic

I'm trying to put an IF condition on a widget through the plugin Widget Logic.
if single post is 'this', then dispay this text.
I tried this but it doesn't work, do you know why ?
if ( is_single( 'dialyse-mayotte' ) ) {
echo 'test'; // conditional content/code
}
thanks for your help
is_single only checks if the page is single you should check if the page is this and is it a single page
if ( is_page( 'dialyse-mayotte') && is_single() ) { echo "test"; }

Wordpress meta data is written on top of page instead of the loop

i'm building a wordpress webpage based on the Skeleton Wordpress theme.
I have 2 posts showing on a page and each of these posts have custom fields values (meta data). Im using the shortcode from the skeleton theme to get a post-feed from a specific category and in that loop i have inserted this tag that displays the custom fields data
<?php the_meta(); ?>
I am getting the data - but the problem is, the data is shown on TOP of the page instead of inside the in the post.
What could've ive possibly done wrong? or is it something with skeleton i am doing wrong?
Webpage : http://visbyfangelse.se.preview.binero.se/rum-priser-preview/
as you can see two posts are shown - and the meta data is shown on the top of the page.
Code to the loop : http://pastebin.com/mRQY5GNz
As you can see i want the meta displayed in the div which i assigned this class to "my_room_meta".
the_meta() echos the results to the page, you could make your own replacement function:
function get_the_meta() {
if ( $keys = get_post_custom_keys() ) {
$output="<ul class='post-meta'>\n";
foreach ( (array) $keys as $key ) {
$keyt = trim($key);
if ( is_protected_meta( $keyt, 'post' ) )
continue;
$values = array_map('trim', get_post_custom_values($key));
$value = implode($values,', ');
$output.= apply_filters('the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value);
}
return $output . "</ul>\n";
}
}
}

Resources