WP - shortcode including a mixture of html and php (ACF variables) - wordpress

I'm trying to create a WP shortcode that would include both html and php. For example, something like that (that does not work):
function my_first_shortcode() {
$content = <<<EOT
<h1>Some title</h1>
<p><?php the_field('description'); ?></p>
EOT;
return $content;
}
add_shortcode('my_shortcode', 'my_first_shortcode');
The the_field('name_of_field'); normally outputs the content of the specified variable/field (Advanced Custom Fields).
Is the HEREDOC way the right way of doing that? If so, how would I do it? It'd be also great if I could pass variables to the shortcode.
Thank you

First, you can't write PHP tags inside HEREDOC.
You can use it like that:
$the_field = 'the_field';
$content = <<<EOT
<h1>Some title</h1>
<p>{$the_field('description')}</p>
EOT;
In order to pass attributes to a shortcode it's very simple.
for example we have the shortcode:
[my_shortcode att_1="some_value" att_2="some_value"]
function my_first_shortcode($atts)
{
$att_1 = $atts['att_1'];
$att_2 = $atts['att_2'];
}
add_shortcode('my_shortcode', 'my_first_shortcode');

I always prefer to use output buffering for my shortcodes, example below.
function my_first_shortcode() {
ob_start(); ?>
<h1>Some title</h1>
<p><?php echo the_field('description'); ?></p>
<?php
return ob_get_contents();
}
add_shortcode('my_shortcode', 'my_first_shortcode');

add_shortcode('location_start_your_application_group', 'start_your_application_group');
function start_your_application_group() {
ob_start();
$start_your_application_group = '';
$start_your_application_group .= '<section class="start-your-application">';
if ( have_rows( 'start_your_application_group', 'option' ) ) :
while ( have_rows( 'start_your_application_group', 'option' ) ) : the_row();
$heading = get_sub_field( 'heading' );
$content = get_sub_field( 'content' );
if ( $heading !== '' ) {
$start_your_application_group .= '<h3 class="start-your-application__heading">' . $heading . '</h3>';
}
if ( $content !== '' ) {
$start_your_application_group .= '<div class="start-your-application__content">' . $content . '</div>';
}
$image = get_sub_field( 'image' );
if ( $image ) {
$start_your_application_group .= '<div class="start-your-application__image-container"><img class="start-your-application__image" src="' . esc_url($image['url']) .'" alt="' . $image['alt'] . '" /></div>';
}
endwhile;
endif;
$start_your_application_group .= '</section>';
$start_your_application_group = ob_get_clean();
return $start_your_application_group;
}

Related

do_shortcode isn't parsing shortcode inside

I'm trying to use do_shortcode in a shortcode function. The problem is that when I use [terms_and_conditions] on my page it doesn't parse the do_shortcode and I see [MM_Form_Field type='custom' id='1' isRequired='true' class='']. It isn't being executed.
This is what my function looks like:
function terms_and_conditions( $atts ) {
// Variables
$terms = get_field('terms_content', 'options');
$checkbox = get_field('terms_checkbox_msg', 'options');
// $smarttag = get_field('terms_smarttag', 'options');
$smarttag = do_shortcode(get_field('terms_smarttag', 'options'));
var_dump($smarttag);
$html_out = '';
$html_out .= '<section id="terms">';
$html_out .= '<div class="terms-content-wrapper">';
$html_out .= $terms;
$html_out .= '</div>'; // end terms-content-wrapper
$html_out .= '<div class="terms-checkbox-wrapper">';
$html_out .= '<div class="terms-checkbox">';
$html_out .= do_shortcode($smarttag);
$html_out .= '<p>' . $checkbox . '</p>';
$html_out .= '</div>'; // end terms-checkbox
$html_out .= '</div>'; // end terms-content-wrapper
$html_out .= '</section>'; // end tip-wrapper
return $html_out;
}
add_shortcode( 'terms_and_conditions', 'terms_and_conditions');
Using ob_start can clean up your shortcodes drastically. But you may prefer to avoid them. This should work...
<?php
function terms_and_conditions( $atts ) {
// Variables
$terms = get_field('terms_content', 'options');
$checkbox = get_field('terms_checkbox_msg', 'options');
$smarttag = get_field('terms_smarttag', 'options');
ob_start();
?>
<section id="terms">
<div class="terms-content-wrapper">
<?php
if($terms){
echo $terms; // <- is terms an array or a string?
}
?>
</div>
<div class="terms-checkbox-wrapper">
<div class="terms-checkbox">
<?php
echo do_shortcode($smarttag);
if(!empty($checkbox)){
echo '<p>' . $checkbox . '</p>'; // <- is checkbox an array or a string?
}
?>
</div>
</div>
</section>
<?php
return ob_get_clean();
}
add_shortcode( 'terms_and_conditions', 'terms_and_conditions');
Another thing you may want to try is changing the quotes you use in your shortcode:
eg, use this:
[MM_Form_Field type="custom" id="1" isRequired="true" class=""]
instead of this:
[MM_Form_Field type='custom' id='1' isRequired='true' class='']

Escaping untrusted data in php for my wordPress theme

I have got a comment from someone superior to me who wants me to escape some comment in two php snippets which I have posted below. The problem is I don't know how to do that. Can anyone help me by modifying the snippets.
Comment I got:
Comment #1:
Validate and/or sanitize untrusted data before entering into the database. All untrusted data should be escaped before output.
Code Snippet #1:
<?php
if ( get_header_image() && !('blank' == get_header_textcolor()) ) {
echo '<div class="site-branding header-background-image" style="background-image: url(' . get_header_image() . ')">';
} else {
echo '<div class="site-branding">';
}
?>
Code Snippet #2:
<?php
printf(
/* translators: %1$s = text link: sangeet, URL: http://wordpress.org/themes/sangeet/, %2$s = text link: Kiran Kumar Dash, URL: https://twitter.com/TheKiranDash */
__( 'Theme: %1$s by %2$s', 'sangeet' ),
'' . esc_attr( 'sangeet', 'sangeet' ) . '',
'' . esc_attr__( 'Kiran Kumar Dash', 'sangeet' ) . '' );
?>
Comment #2:
esc all get_permalink() in content.php
Code snippet #3
<?php
if ( !is_single() ) {
echo '<div class="index-box">';
if ( has_post_thumbnail()) {
echo '<div class="small-index-thumbnail clear">';
echo '<a href="' . get_permalink() . '" title="' . __('Read ', 'sangeet') . get_the_title() . '" rel="bookmark">';
echo the_post_thumbnail('index-thumb');
echo '</a>';
echo '</div>';
}
}
?>
My approach:
I used esc_url to esc the get_permalink() in the snippet. Shall I use esc_all? Or esc_url is just fine.
<?php
if ( !is_single() ) {
echo '<div class="index-box">';
if ( has_post_thumbnail()) {
echo '<div class="small-index-thumbnail clear">';
echo '<a href="' . esc_url(get_permalink()) . '" title="' . __('Read ', 'sangeet') . get_the_title() . '" rel="bookmark">';
echo the_post_thumbnail('index-thumb');
echo '</a>';
echo '</div>';
}
}
?>
As requested:
PS. I didnt write this, only advanced it.
Usage:
$user = sanctify($_GET['user']);
Function:
function sanctify($data){
// Fix &entity\n;
$data = str_replace(array('&','<','>'), array('&amp;','&lt;','&gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');
// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);
// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);
// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);
// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);
$data = str_replace('"','',str_replace("'","",$data));
do{
// Remove really unwanted tags
$old_data = $data;
$data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);
// we are done...
return $data;
}

Using an ACF image object for a custom taxonomy within an echo block loop

I can't seem to pull a ACF image object for a custom taxonomy when used in this loop, which is made of echo blocks:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post();
$terms = get_terms( 'product_type' );
$image = get_field('product_type_tax_image');
$hero_image = $image['sizes']['medium'];
foreach ( $terms as $term ) {
// The $term is an object, so we don't need to specify the $taxonomy.
$term_link = get_term_link( $term );
// If there was an error, continue to the next term.
if ( is_wp_error( $term_link ) ) {
continue;
}
var_dump($hero_image);
// We successfully got a link. Print it out.
echo '<a href="' . esc_url( $term_link ) . '" class="product-grid- block" style="' . $hero_image[0] . '">';
echo '<div class="product-grid-inner-txt-wrap">';
echo '<h4>' . $term->name . '</h4>';
echo '<p>' . $term->description . '</p>';
echo '</div>';
echo '</a>';
}
?>
<?php endwhile; endif; ?>
<?php wp_reset_query(); ?>
The var dump just returns NULL. I've looked at this and this but don't seem to help. What am I doing wrong?
Take a look at this article:
http://www.advancedcustomfields.com/resources/get-values-from-a-taxonomy-term/
To pull a custom field from a Taxonomy Term, you need to add a second item to your get_field function call. Like this:
$image = get_field('product_type_tax_image', $term );
Also, it looks like you're trying to loop through $terms, but you're grabbing the custom field's value outside of your foreach loop, so that should get moved inside that loop, like so:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post();
$terms = get_terms( 'product_type' );
foreach ( $terms as $term ) {
//get $term's image
$image = get_field('product_type_tax_image', $term );
$hero_image = $image['sizes']['medium'];
// The $term is an object, so we don't need to specify the $taxonomy.
$term_link = get_term_link( $term );
// If there was an error, continue to the next term.
if ( is_wp_error( $term_link ) ) {
continue;
}
var_dump($hero_image);
// We successfully got a link. Print it out.
echo '<a href="' . esc_url( $term_link ) . '" class="product-grid- block" style="' . $hero_image[0] . '">';
echo '<div class="product-grid-inner-txt-wrap">';
echo '<h4>' . $term->name . '</h4>';
echo '<p>' . $term->description . '</p>';
echo '</div>';
echo '</a>';
}
?>
<?php endwhile; endif; ?>
<?php wp_reset_query(); ?>

Show attached media image if no thumbnail image detected

I'm using
if ( has_post_thumbnail() ){}
to check if the post have thumbnail image,
but this
echo get_attached_media('image', $post->ID);
display the word
Array
I need to show the attached image
If you are trying to get just one image in the post and use it as a thumbail, you might want to try this one:
Add this to you're functions.php :
// Get URL of first image in a post
function catch_that_image() {
global $post, $posts;
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
$first_img = $matches [1] [0];
// no image found display default image instead
if(empty($first_img)){
$first_img = "/images/default.jpg";
}
return $first_img;
}
To call it just put
<?php echo catch_that_image() ?>
in your template file within the loop.
I found this brilliant code from this forum thread. Saved me a lot of times.
I found this, and it WORKS
<?php
if( has_post_thumbnail() )
{
// check if the post has a Post Thumbnail
echo ' <a href="';
the_permalink();
echo '" title="';
the_title_attribute();
echo '">';
the_post_thumbnail( 'medium' );
echo '</a>';
}
else
{
$imgs = get_attached_media( 'image' );
if( count( $imgs ) > 0 )
{
$img = array_shift( $imgs );
echo wp_get_attachment_image( $img->ID, 'thumbnail' );
}
}
?>
And all thanks and credit for #birgire on WPSE
You need to use get_attached_media( 'image', $post->ID );
Using
echo get_attached_media( 'image' );
should work.

Styling RSS feed?

I'm trying to style the RSS feed that the user would see. So all all they would see is the image from the post, the text from the WYSIWYG editor and a button that's part of the theme.
Here is the button from the single.php template file:
<div class="bottomgift clearfix">
<a target="_blank" rel="nofollow" href="<?php getCustomField('Affiliate Link'); ?>" class="go-button">Go</a>
</div>
How do I add all this to style the RSS feed?
In Functions.php
function modRSS($content) {
global $post;
if ( has_post_thumbnail( $post->ID ) ){
$content = '<div>' . get_the_post_thumbnail( $post->ID, 'full', array( 'style' => 'margin-bottom: 15px;' ) ) . '</div>' . $content;
}
$content = $content . 'Go';
return $content;
}
add_filter('the_excerpt_rss', 'modRSS');
add_filter('the_content_feed', 'modRSS');
You can prepend or amend any syntax to WordPress RSS feeds quite easily.
Here is some code to do that take from here... http://webdesignzo.com/show-featured-images-in-rss-feed-feedburner/ modified a little for your purposes.
function modRSS($content) {
global $post;
if ( has_post_thumbnail( $post->ID ) ){
$content = '<div>' . get_the_post_thumbnail( $post->ID, 'thumbnail', array( 'style' => 'margin-bottom: 15px;' ) ) . '</div>' . $content;
}
$content = $content . '<div class="bottomgift clearfix"><a target="_blank" rel="nofollow" href="' . getCustomField('Affiliate Link') . '" class="go-button">Go</a</div>';
//Adding Custom Fields
$content = $content . get_post_meta($post->ID,'custom_field_name', true);
return $content;
}
add_filter('the_excerpt_rss', 'modRSS');
add_filter('the_content_feed', 'modRSS');
My code is untested but something like this should be what you are looking for.
P.S. This isn't styling per say as your question title suggests, but more adding markup to it.

Resources