4

A client of mine wants a "project of the month" feature on his Wordpress site. But with a archive page.

My idea was to create a custom post type and call it projects. In here the client can manage projects and make new ones.

With this piece of code i can take the content from the latest project post, and put that content on the main "project of the month" page, while all the past projects are on the archive page.

$latest_cpt = get_posts("post_type=projects&numberposts=1");
$my_postid = $latest_cpt[0]->ID; //This is page id or post id
$content_post = get_post($my_postid);
$content = $content_post->post_content;
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
echo $content;

This works ... but not really.

The project pages are build using visual composer. And some of the elements have background colors or padding. Visual composer gives these elements unique classes like

.vc_custom_1516702624245

And adds the custom style tag when the page loads. Something like this

<style type="text/css" data-type="vc_shortcodes-custom-css">
    .vc_custom_1516711125312 {
        padding-top: 75px !important;
        padding-bottom: 75px !important;
        background-color: #f3f5f6 !important;
    }

    .vc_custom_1516702624245 {
        background-color: #f3f5f6 !important;
    }

    .vc_custom_1516711013808 {
        margin-top: -106px !important;
    }

    .vc_custom_1516702490896 {
        padding-left: 50px !important;
    }

    .vc_custom_1516703325534 {
        margin-top: -15px !important;
    }

    .vc_custom_1516702744160 {
        background-position: center !important;
        background-repeat: no-repeat !important;
        background-size: cover !important;
    }

    .vc_custom_1516702987431 {
        padding-right: 65px !important;
    }

    .vc_custom_1516709810401 {
        border-radius: 3px !important;
    }
</style>

The problem with my approach is that visual composer does not create the style tag for the post content that is being loaded.

So therefore a lot of minor styling details are lost.

Image: Page content on archive page (how it should look)

Image: Page content on "project of the month" page

TL:DR visual composer style not generating post_content

Seb33300
  • 7,464
  • 2
  • 40
  • 57

3 Answers3

8

You can use part of the addShortcodesCustomCss function of Vc_base:

$shortcodes_custom_css = get_post_meta( $id, '_wpb_shortcodes_custom_css', true );
if ( ! empty( $shortcodes_custom_css ) ) {
    $shortcodes_custom_css = strip_tags( $shortcodes_custom_css );
    echo '<style type="text/css" data-type="vc_shortcodes-custom-css">';
    echo $shortcodes_custom_css;
    echo '</style>';
}

replacing $id with yours $my_postid and, if needed, the echo with $content .=

Riccardo
  • 1,309
  • 1
  • 25
  • 35
  • How can i get this in rest api ??? I am using Rest API to get Page content designed with WPBakery. I can get the content but the CSS is missing. –  Sep 18 '19 at 22:28
0

Heres a function combining what i've seen across various stack overflow topics.

If you are using WPBakery for a page builder and want to use the WP_JSON api to serve your content to the frontend such as Angular or React you need to do a few things.

  1. Tell wordpress to render the WP Bakery shortodes into actual HTML
  2. Tell wordpress to include the dynamically generated css classes in the API response.

To do this I simply did the following:

add_action( 'rest_api_init', function ()
{
    register_rest_field(
        'page',
        'content',
        array(
            'get_callback'    => 'compasshb_do_shortcodes',
            'update_callback' => null,
            'schema'          => null,
        )
    );
});

function compasshb_do_shortcodes( $object, $field_name, $request )
{
    WPBMap::addAllMappedShortcodes(); // This does all the work

global $post;
$post = get_post ($object['id']);
$output['rendered'] = apply_filters( 'the_content', $post->post_content );

$output['css'] = '';

$shortcodes_custom_css = get_post_meta( $object['id'], '_wpb_shortcodes_custom_css', true );
if ( ! empty( $shortcodes_custom_css ) ) {
    $shortcodes_custom_css = strip_tags( $shortcodes_custom_css );
    $output['css'] .= $shortcodes_custom_css;
}


return $output;
}

This basically returns the following:

  "content": {
        "rendered": "<div class=\"row\"><div class=\"col-sm-12\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div></div><div class=\"row\"><div class=\"col-sm-6\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div><div class=\"col-sm-6\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div></div><div class=\"row\"><div class=\"col-sm-4\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div><div class=\"col-sm-4 vc_col-has-fill\"><div class=\"vc_column-inner vc_custom_1631795792357\"><div class=\"wpb_wrapper\"><h2 style=\"text-align: left;font-family:Abril Fatface;font-weight:400;font-style:normal\" class=\"vc_custom_heading\" >This is custom heading element</h2>\n\t<div class=\"wpb_text_column wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<p>I am text block. Click edit button to change this text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>\n\n\t\t</div>\n\t</div>\n</div></div></div><div class=\"col-sm-4\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"></div></div></div></div><div class=\"row\"><div class=\"col-sm-12\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><div style='color:#FF0000;' data-foo='something'></div></div></div></div></div>\n",
        "css": ".vc_custom_1631795792357{background-color: #afafaf !important;}"
    },

You can then use the html on your frontend for example using angular by creating a dynamic route that feeds the slug in as a parameter, then simply connect a resolver service to it to hit the api for that page, if it's found, render the page, if not redirect to a 404.

The css can then be added in on component load by appending to the head.

And hey presto, you get WpBakery powered Angular.

Also for SEO, you can use SSR and WP Yoast to control and append meta tags from the WP Admin.

Any questions or improvement suggestions let me know.

Robert Lane
  • 11
  • 1
  • 2
-2
function usp_modify_post_type($post_type) { 
  return 'post,footer,header,page,product,'; // Edit post type as needed
}

add_filter('usp_post_type', 'usp_modify_post_type');
Don't Panic
  • 13,965
  • 5
  • 32
  • 51
HAMZA ALI
  • 1
  • 1