Weird WordPress One: Outputting pagebuilder contents on PHP templates
Tags: wordpress, php, webdev, pagebuilders
Published: 2023-07-30 14:28:28

Documenting non-standard WordPress work that I come across.

I've just completed a job for a client that required a custom Woocommerce Archive. The problems were:

- They had a sitewide footer that needed to appear on archive pages that had to remain editable via Wpbakery for updates by non-programmers
- Wpbakery page builder was not available on woocommerce archive pages

I moan about pagebuilders all the time to anyone who will listen but even I know that sometimes they are a requirement for end users that want to manage their own pages. In this case we had to output wpbakery content onto an archive page which is generated by Woocommerce depending on the category query and any attribute or tag parameters. This theme they used did not have an affordance to use wpbakery to build out a woocommerce archive page, nor did they want to add bloat to the theme by using an auxiliary plugin like WCbuilder. 

At this point you may want to know why they didn't just build their own page and use the builder's built in woocommerce product loop 'Product Category'? This is because the sidebar widget for woocommerce, 'Filter product by attribute', simply does not work on non-woocommerce pages, this is a known issue since 2020 and remains unfixed to this day (https://github.com/woocommerce/woocommerce/issues/27419).

After complaining quietly to myself about how a major plugin still hasn't managed to fix this common issue in 3 years, I came up with a solution that resulted in the following:

- Create a page in the backend that would contain the archive footer and allow them to edit it via standard Wpbakery editing
- Write a shortcode that wrapped a function to output the page content of the 'footer page' into the archive page.

At this point my plugin code looked like this:

```
<?php
// Adds Shortcode
add_shortcode( 'footer-loop', 'footerloop_shortcode' );
function footerloop_shortcode() {
    
    // queries the footer page
    $scamp_query = new WP_Query( 'pagename=footerblock' );
    
    while ( $scamp_query->have_posts() ) : $scamp_query->the_post();
        the_content();
    endwhile;
   
    wp_reset_postdata(); 
}?>

```

and in the template file:

```
<?php echo do_shortcode('[footer-loop]'); ?>
```

Now this worked just fine to begin with and it output the pagebuilder content cleanly and preserved the columns, images and subscription boxes. On closer inspection though it did not output any of the builder's block-level CSS. 

Curses.

Then I recalled that the css for these blocks is stored in the post meta and that I'd have to echo that out in a style tag to properly render the builder content. The code was then updated to:

```
<?php
add_shortcode( 'footer-loop', 'footerloop_shortcode' );
function footerloop_shortcode() {
    
    // queries the footer page
    $scamp_query = new WP_Query( 'pagename=footerblock' );
    
    while ( $scamp_query->have_posts() ) : $scamp_query->the_post();
        the_content();
    endwhile;
    echo '<style type="text/css" data-type="vc_shortcodes-custom-css">';
	   echo get_post_meta( 1840, '_wpb_shortcodes_custom_css', true );
  echo '</style>';
    wp_reset_postdata();
   
}?>

```

This now resulted in the block rendering properly but it is not the cleanest method as it now outputs a style tag below the footer. Yes its only about four lines but its not optimal for it to deploy outside the head. 

To fix this, I renamed my style.css file in my plugin to style.css.php and below the other rules I put in there for basic styling I wrote in the:

```
<?php
echo get_post_meta( 1840, '_wpb_shortcodes_custom_css', true );
?>
```

without the encapsulating style tags from the plugin. If you do something like this yourself make sure you register and enqueue the file so that it deploys in your head tag also.

And that's that. Weird use case for WordPress done.