How to display recent Hubspot’s blog posts in WordPress site and create a shortcode to use anywhere we like
//Why blog on Hubspot
Wordpress itself is blogging cms but in some cases as one of our recent clients the blog is already established on Hubspot and WordPress is used as company webpage (static content) so to speak.
// How to get the data from Hubspot
When we speak about retrieving data from site to site nowadays, we usually think of JSON as the industry standard. BUT Hubspot has RSS build-in which in no sense a bad thing. RSS (Really Simple Syndication) –wikipedia is rather old technology but still in use the response comes in .xml similar to syntax html.
WordPress’ RSS is accessible at your-domain-name.com/feed
Hubspot’s RSS => hubslpot-domain.com/rss.xml
We are talking about the default settings of WP and HS. Customization are possible as you can see in this article (HS rss article) customizations at all.
We were looking for the fastest and easiest solution not involving another plugin just to retrieve the last posts and not messing with Hubspot customizations at all.
For this particular example we are going to use Hubspot’s blog https://developers.hubspot.com/blog and if we add /rss.xml at the end and the browser should render .xml something like this:
//What is in this .xml after all
As you see there is parent <channel> and many <item> tags which we are interested in. To get more visual lets paste the url in https://codebeautify.org/rssviewer and it should look something like this:
Any <item> is an article and has title, description, content, link, date, category, author.
//How to fetch it in WordPress
For this task WordPress has pretty neat function fetch_feed() it takes url as parameter and returns (SimplePie) object on success or error if fails to retrieve .xml . This one goes straight into page.php
<?php
//fetch the data from the rss URL of your blog
$hubspot_posts = fetch_feed('https://developers.hubspot.com/blog/rss.xml');
//Check that is not an error
if( ! is_wp_error( $hubspot_posts ) ){
//Grab 3 items starting from 0 position
$items = $hubspot_posts->get_items(0,3);
}else{
echo '<p>The url is not correct</p>';
}
//Check items are array and is not empty
if( is_array($items) && ! empty($items)){
//For every item
foreach ($items as $item) {
//Display the title
echo $item->get_title();
echo "<br>"; //next line
//Display the description
echo $item->get_description();
echo "<br>"; //next line
//Display the date
echo $item->get_date();
echo "<br>"; //next line
//Display the link
echo $item->get_permalink();
}
}
?>
The result:
Depending on the Theme installed will look a bit different but not satisfying at all.
Just to clarify the $item methods:
- get_title() => comes raw string no H1 or other html
- get_description() => is div > a > img and paragraph with content
- get_date() => takes parameters to format the date as your liking
- get_permalink() => gives raw url to the post
To have full control of the look we have to remove the inline style tag and separate image from the content and the solution we found is preg_replace() and preg_split() native PHP methods.
<?php
// For every item
foreach ($items as $item) {
//get_content and remove style tags from it
$content = preg_replace('/\sstyle=(\"|\')[\s\S]*?(\"|\')/i', '', $item->get_description());
//split the string and make array from it use <p> as separator
$content_split = preg_split("/<p>/", $content);
// <div><img></div> first part of the content
$image = $content_split[0];
// text</p> second part of the text
$text = $content_split[1]; ?>
}
?>
Now when we have all that we need we will displayed with a bit of inline css just to look better. Add the html the classes and css as per your liking. We will trim the content to 25 words with wp_trim_words()
The code:
<?php
//fetch the data from the rss URL of your blog
$hubspot_posts = fetch_feed('https://developers.hubspot.com/blog/rss.xml');
//Check that is not an error
if( ! is_wp_error( $hubspot_posts ) ){
//Grab 3 items starting from 0 position
$items = $hubspot_posts->get_items(0,4);
}else{
echo '<p>The url is not correct</p>';
}
//Check items are array and is not empty
if( is_array($items) && ! empty($items)){
echo '<div style="display:flex;flex-wrap:wrap;justify-content:center;">';
//For every item
foreach ($items as $item) {
//get_content and remove style tags from it
$content = preg_replace('/\sstyle=(\"|\')[\s\S]*?(\"|\')/i', '', $item->get_description());
//split the string and make array from it use <p> as separator
$content_split = preg_split("/<p>/", $content);
// <div><img></div> first part of the content
$image = $content_split[0];
// text</p> second part of the text
$text = $content_split[1]; ?>
<div style="width: 400px;margin: 20px;">
<?php echo $image; ?>
<h4><?php echo $item->get_title(); ?></h4>
<p><?php echo wp_trim_words( $text, 25 ); ?></p>
<a href="<?php echo $item->get_permalink(); ?>">Read More</a>
</div>
<?php
}
echo '</div><!-- Posts wrapper -->';
}
?>
The result:
Now lets wrap this in function and add_shortcode() and will be ready to be displayed everywhere. Now this goes in functions.php of our theme or child theme
<?php
function hubspot_blog_posts_shortcode( $atts ){
$defaults = shortcode_atts(
array(
'url' =>'',
'number_posts' => 4,
'trim_words' => 25,
'error_message' => 'The url is not correct'
), $atts);
//fetch the data from the rss URL of your blog
$hubspot_posts = fetch_feed( esc_url( $defaults['url'] ) );
//Check that is not an error
if( ! is_wp_error( $hubspot_posts ) ){
//Grab 3 items starting from 0 positon
$items = $hubspot_posts->get_items( 0, abs($defaults['number_posts']) );
}else{
return "<p>{$defaults['error_message']}</p>";
}
ob_start();
//Check items are array and is not empty
if( is_array($items) && ! empty($items)){
echo '<div style="display:flex;flex-wrap:wrap;justify-content:center;">';
//For every item
foreach ($items as $item) {
//get_content and remove style tags from it
$content = preg_replace('/\sstyle=(\"|\')[\s\S]*?(\"|\')/i', '', $item->get_description());
//split the string and make array from it use <p> as separator
$content_split = preg_split("/(<p>|<\/p>)/", $content);
// <div><img></div> first part of the content
$image = $content_split[0];
// text</p> second part of the text
$text = $content_split[1]; ?>
<div style="width: 400px;margin: 20px;">
<?php echo $image; ?>
<h4><?php echo $item->get_title(); ?></h4>
<p><?php echo wp_trim_words( $text, $defaults['trim_words'] ); ?></p>
<a href="<?php echo $item->get_permalink(); ?>">Read More</a>
</div>
<?php
}
echo '</div><!-- Posts wrapper -->';
}
return ob_get_clean();
}
add_shortcode( 'hubspot_posts', 'hubspot_blog_posts_shortcode' );
Now [hubspot_posts] is ready to go. Four parameters accepted:
- url => the url of the blog + /rss.xml *required
- number_posts => how many posts you want to display
- trim_words => how many words of the content to trim
- error_message => what to say if the call to url is not successful
This Shortcode will display 3 posts with 30 words of the provided content from developers.hubspot.com/blog and if the url is broken will say in paragraph “Nothing found…”
[hubspot_posts url=”https://developers.hubspot.com/blog/rss.xml” error_message=”Nothing found…” number_posts=”3″ trim_words=30]
Hope that helps to someone and any suggestions advices and questions are appreciated.
0 Comments