Hide specific part of Shortcode if attributes are not set - wordpress

I've created the following shortcode to display blockquotes :
// Add Shortcode
function quote_shortcode( $atts , $content = null ) {
// Attributes
$atts = shortcode_atts(
array(
'author' => 'author',
'author_job' => 'author_job',
),
$atts
);
return
'<div data-module="expert_quote"><blockquote class="full no-picture"><p>“' . $content . '”</p><footer class="quote-footer"><cite><span class="name">' . esc_attr($atts['author']) . '</span> <span class="title">' . esc_attr($atts['author_job']) . '</span></cite></footer></blockquote></div>';
}
add_shortcode( 'quote', 'quote_shortcode' );
I'd like to not return
<span class="name">' . esc_attr($atts['author']) . '</span>
if author is not set in the shortcode. Same goes with author_job.
How can I achieve this?

You need to create your return string conditionally. You can use following code:
function quote_shortcode( $atts , $content = null ) {
// Attributes
$atts = shortcode_atts(
array(
'author' => 'author',
'author_job' => 'author_job',
),
$atts
);
$return_string = '<div data-module="expert_quote">';
$return_string .= '<blockquote class="full no-picture">';
$return_string .= '<p>“' . $content . '”</p>';
$return_string .= '<footer class="quote-footer">';
$return_string .= '<cite>';
if (isset($atts['author'])) {
$return_string .= '<span class="name">' . esc_attr($atts['author']) . '</span>';
}
if (isset($atts['author_job'])) {
$return_string .= '<span class="title">' . esc_attr($atts['author_job']) . '</span>';
}
$return_string .= '</cite>';
$return_string .= '</footer">';
$return_string .= '</blockquote">';
$return_string .= '</div">';
return $return_string;
}
add_shortcode( 'quote', 'quote_shortcode' );

I've managed to make it work but not sure my code is well optimized :
function quote_shortcode( $atts , $content = null ) {
// Attributes
$atts = shortcode_atts(
array(
'author' => '',
'author_job' => '',
),
$atts
);
$return_string = '<div data-module="expert_quote">';
$return_string .= '<blockquote class="full no-picture">';
$return_string .= '<p>“' . $content . '”</p>';
if (!empty($atts['author']) || !empty($atts['author_job'])) {
$return_string .= '<footer class="quote-footer">';
$return_string .= '<cite>';
}
if (!empty($atts['author'])) {
$return_string .= '<span class="name">' . esc_attr($atts['author']) . '</span>';
}
if (!empty($atts['author_job'])) {
$return_string .= '<span class="title">' . esc_attr($atts['author_job']) . '</span>';
}
if (!empty($atts['author']) && !empty($atts['author_job'])) {
$return_string .= '</cite>';
$return_string .= '</footer>';
}
$return_string .= '</blockquote>';
$return_string .= '</div>';
return $return_string;
}
add_shortcode( 'quote', 'quote_shortcode' );

Related

how can i add category meta under the post date?

my link is madbabe.co
inside the grid only has title and date , I want category under the date.
i have found the code for the date, don't know how to add more code to display category.
// Display date if $date is true
if ( 'true' == $date ) {
$date_output = '';
if ( $first_run ) {
$date_style = vcex_inline_style( array(
'color' => $date_color,
'font_size' => $date_font_size,
) );
}
$date_output .= '<div class="vcex-blog-entry-date entry-date"' . $date_style . '>';
$date_output .= get_the_date();
$date_output .= '</div>';
$output .= apply_filters( 'vcex_blog_grid_date', $date_output, $latts );
}
Try making that whole code this:
// Display date if $date is true
if ( 'true' == $date ) {
$date_output = '';
$id = get_the_ID();
$cats = wp_get_post_categories($id);
if ( $first_run ) {
$date_style = vcex_inline_style( array(
'color' => $date_color,
'font_size' => $date_font_size,
) );
}
$date_output .= '<div class="vcex-blog-entry-date entry-date"' . $date_style . '>';
$date_output .= get_the_date();
$date_output .= '</div>';
$date_output .= '<br><div>' . $cats[0]->name; . '</div>';
$output .= apply_filters( 'vcex_blog_grid_date', $date_output, $latts );
}

Wordpress Shortcode Function is displaying before content

I have been working on trying to get this shortcode to show correctly but everything I have tried does not work. Below is my function:
function monster_shortcode( $atts ) {
$monster = $atts['name'];
$query = new WP_Query( array(
'post_type' => 'monsters',
'name' => $monster,
));
if ( $query->have_posts() ) {
while ( $query->have_posts() ) : $query->the_post();
$monster_title = the_title();
$monster_size = the_field('size');
$monster_type = 'type';
$monster_alignment = the_field( 'alignment' );
$monster_ac = the_field( 'armor_class' );
$monster_ac_type = the_field( 'ac_type' );
$monster_hp = the_field( 'hit_points' );
$monster_hd = the_field( 'hit_die' );
$monster_speed = the_field( 'speed' );
$monster_str = the_field( 'str' );
$monster_strb = monster_stats( get_field( 'str' ) );
$monster_dex = the_field( 'dex' );
$monster_dexb = monster_stats( get_field( 'dex' ) );
$monster_con = the_field( 'con' );
$monster_conb = monster_stats( get_field( 'con' ) );
$monster_int = the_field( 'int' );
$monster_intb = monster_stats( get_field( 'int' ) );
$monster_wis = the_field( 'wis' );
$monster_wisb = monster_stats( get_field( 'wis' ) );
$monster_cha = the_field( 'cha' );
$monster_chab = monster_stats( get_field( 'cha' ) );
$monster_saves = the_field( 'saving_throws' );
$monster_skills = the_field( 'skills' );
$monster_dmg = the_field( 'damage_adjustments' );
$monster_senses = the_field( 'senses' );
$monster_lang = the_field( 'languages' );
$monster_cr = the_field( 'cr' );
$monster_actions = the_field( 'actions' );
$monster_reactions = the_field( 'reactions' );
$monster_char = the_field( 'characteristics' );
$monster_content = the_content();
$monster_enviro = the_field( 'enviroments' );
$return = '<h1 class="entry-title">' . $monster_title . '</h1>';
$return .= '<div class="monster-meta">' . $monster_size . ' ' . $monster_type . ', ' . $monster_alignment . '</div>';
$return .= '<ul class="monster-stat">';
$return .= '<li><label>Armor Class</label> ' . $monster_ac . ' (' . $monster_ac_type . ')</li>';
$return .= '<li><label>Hit Points</label> ' . $monster_hp . ' (' . $monster_hd . ')</li>';
$return .= '<li><label>Speed</label> ' . $monster_speed . '</li>';
$return .= '</ul>';
$return .= '<ul class="monster-stat abilities">';
$return .= '<li><label>STR</label>' . $monster_str . ' (' . $monster_strb . ')</li>';
$return .= '<li><label>DEX</label>' . $monster_dex . ' (' . $monster_dexb . ')</li>';
$return .= '<li><label>CON</label>' . $monster_con . ' (' . $monster_conb . ')</li>';
$return .= '<li><label>INT</label>' . $monster_int . ' (' . $monster_intb . ')</li>';
$return .= '<li><label>WIS</label>' . $monster_wis . ' (' . $monster_wisb . ')</li>';
$return .= '<li><label>CHA</label>' . $monster_cha . ' (' . $monster_chab . ')</li>';
$return .= ' </ul>';
$return .= '<ul class="monster-stat">';
$return .= '<li><label>Saving Throws</label> ' . $monster_saves . '</li>';
$return .= '<li><label>Skills</label> ' . $monster_skills . '</li>';
$return .= '<li><label>Damage Adjustments</label> ' . $monster_dmg . '</li>';
$return .= '<li><label>Senses</label> ' . $monster_senses . '</li>';
$return .= '<li><label>Langauage</label> ' . $monster_lang . '</li>';
$return .= '<li><label>Challenge Rating</label> ' . $monster_cr . '</li>';
$return .= '</ul>';
$return .= '<p>' . $monster_traits . '</p>';
$return .= '<h4 class="monster-label">Actions</h2><p>' . $monster_actions . '</p>';
$return .= '<h4 class="monster-label">Reactions</h2><p>' . $monster_reactions . '</p>';
$return .= '<h4 class="monster-label">Characteristics</h2><p>' . $monster_char . '</p>';
$return .= '<h4 class="monster-label">Details</h2><p>' . $monster_content . '</p>';
$return .= '<p><label>Enviroments:</label> ' . $monster_enviro . '</p>';
endwhile;
}
return $return;
wp_reset_postdata();
}
add_shortcode( 'monster', 'monster_shortcode' );
I then put the shortcode [monster name="men-at-arms"] on a page. All the function $variables show up before the post content and all the function html shows where it should be. You can see the output here https://www.dropbox.com/s/xvuqofya1jylsfl/Screenshot%20%283%29.png?dl=0
You're using the display functions instead of the return functions.
the_title() will literally echo the title. If you want it as a variable, you need to use get_the_title() (or you can set the third argument to false in the_title() - but that's generally not desirable)
This applies to all the functions you're using that are outputting a value.
the_title() => get_the_title()
the_field() => get_field()
the_content() => get_the_content()
Since it's now pulling in the hosting post's content, you need to pass the ID from the shortcode to the functions. Either like so:
$monster = $atts['name'];
$monster_id = $atts['id'];
...
$monster_title = get_the_title( $monster_id );
$monster_size = get_field( 'size', $monster_id );
Or like so:
$monster = $atts['name'];
...
$monster_title = get_the_title( $post->ID );
$monster_size = get_field( 'size', $post->ID );
Alternatively, you can remove ALL the variable definitions and just modify the HTML returning portion.
while ( $query->have_posts() ) : $query->the_post(); ?>
<h1 class="entry-title"><?php the_title(); ?></h1>
<div class="monster-meta"><?php the_field('size'); ?> <?php the_field('type'); ?> <?php the_field('alignment'); ?>
<ul class="monster-stat">
...
</div>
<?php endwhile; ?>

How to extend visual composer with custom post as element

I installed visual composer in my wordpress website. I need to add an custom post type as an element in visual composer and need to map the template file to the created custom post type element in visual composer.
<?php
add_action( 'vc_before_init', 'vc_extend_func' );
function vc_extend_func() {
vc_map( array(
"name" => __( "Testing", "my-text-domain" ),
"base" => "test",
"class" => "",
"category" => __( "Content", "my-text-domain"),
) );
}
?>
This piece of code created the element in visual composer. My question is how to map a template to this element.
<?php
$dir = get_stylesheet_directory() . '/vc_templates';
vc_set_shortcodes_templates_dir( $dir );
?>
I also overwrite the default shortcode template path. But I didn't get the desired result. Kindly, provide solution to map the template for the created to post type.
Thanks in Advance.
I've done exactly this for my theme. I've created a "portfolio" custom post and then added it into Visual Composer as element. It also have some options and it can display the posts based on "category". Below is the full working code.
Step 1 - create a php file and paste this code:
add_action( 'vc_before_init', 'agr_portfolio_integrateWithVC' );
function agr_portfolio_integrateWithVC() {
$taxonomy = 'portfolio_categories';
$categories_array = array();
$categories = get_terms( array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
) );
$categories_array[] = 'All';
foreach( $categories as $category ){
$categories_array[] = $category->name;
}
vc_map(array(
"name" => __("Portfolio", THEME_TEXT_DOMAIN) ,
"base" => "agr_portfolio",
"category" => __( "Adina Addons", THEME_TEXT_DOMAIN),
'icon' => get_template_directory_uri().'/visual_composer/agr-portfolio/agr-portfolio.png',
'description' => __('Displays Portfolio items with many styles & options.', THEME_TEXT_DOMAIN) ,
"params" => array(
array(
"type" => "dropdown",
"heading" => __("Style", THEME_TEXT_DOMAIN) ,
"param_name" => "agr_portfolio_style",
"value" => array(
"Modern" => "modern",
"Classic" => "classic",
"Newspaper" => "newspaper",
"Masonry" => "masonry"
) ,
"description" => __("Select Portfolio loop style to use.", THEME_TEXT_DOMAIN)
) ,
array(
"type" => "dropdown",
"heading" => __("Category", THEME_TEXT_DOMAIN) ,
"param_name" => "agr_portfolio_category",
"value" => $categories_array ,
"description" => __("Select Portfolio category to display.", THEME_TEXT_DOMAIN)
) ,
array(
"type" => "dropdown",
"heading" => __("Image Size", THEME_TEXT_DOMAIN) ,
"param_name" => "agr_portfolio_image_size",
"value" => array(
"Cover" => "cover",
"Contain" => "contain"
) ,
"description" => __("Select Portfolio image style.", THEME_TEXT_DOMAIN)
) ,
array(
"type" => "dropdown",
"heading" => __("How many columns", THEME_TEXT_DOMAIN) ,
"param_name" => "agr_portfolio_nr_columns",
"value" => array(
"Default" => "col-md-6 col-xs-12",
"1 column" => "col-md-12 col-xs-12",
"2 columns" => "col-md-6 col-xs-12",
"3 columns" => "col-md-4 col-xs-12",
"4 columns " => "col-md-3 col-xs-12",
"6 columns " => "col-md-2 col-xs-12"
) ,
"description" => __("Select Portfolio image style.", THEME_TEXT_DOMAIN)
) ,
array(
'type' => 'textfield',
'heading' => __( 'How many posts', THEME_TEXT_DOMAIN ),
'param_name' => 'agr_portfolio_nr_posts',
'value' => '10',
'admin_label' => true,
'description' => __( 'Enter the number of posts to be displayed.', THEME_TEXT_DOMAIN ),
),
array(
"type" => "dropdown",
"heading" => __("Order", THEME_TEXT_DOMAIN) ,
"param_name" => "agr_portfolio_order",
"value" => array(
"DESC (descending order)" => "DESC",
"ASC (ascending order)" => "ASC"
) ,
"description" => __("Portfolio items will be displayed in DESC or ASC order", THEME_TEXT_DOMAIN)
) ,
array(
"type" => "dropdown",
"heading" => __("Order By", THEME_TEXT_DOMAIN) ,
"param_name" => "agr_portfolio_order_by",
"value" => array(
"Date" => "date",
"Title name" => "title"
) ,
"description" => __("Sort Portfolio items by selected parameter.", THEME_TEXT_DOMAIN)
) ,
array(
"type" => "textfield",
"heading" => __("Extra class name", THEME_TEXT_DOMAIN) ,
"param_name" => "agr_portfolio_class",
"value" => "",
"description" => __("If you wish to style particular content element differently, then use this field to add a class name and then refer to it in your Custom CSS.", THEME_TEXT_DOMAIN)
)
)
));
}
// this is a custom pagination function. Put it in the same file.
function agr_portfolio_pagination($pages = '', $range = 2) {
$showitems = ($range * 2)+1;
$paginationData = '';
global $paged;
if(empty($paged)) $paged = 1;
if($pages == '') {
global $wp_query;
$pages = $wp_query->max_num_pages;
if(!$pages) {
$pages = 1;
}
}
if(1 != $pages) {
$paginationData = '<div class="pagination">';
if($paged > 2 && $paged > $range+1 && $showitems < $pages) {
$paginationData .= '«';
}
if($paged > 1 && $showitems < $pages) {
$paginationData .= '«';
}
for ($i=1; $i <= $pages; $i++) {
if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems )) {
if($paged == $i){
$paginationData .= "<span class='current'>".$i."</span>";
} else {
$paginationData .= "<a href='".get_pagenum_link($i)."' class='inactive' >".$i."</a>";
}
}
}
if ($paged < $pages && $showitems < $pages) {
$paginationData .= "<a href='".get_pagenum_link($paged + 1)."'>›</a>";
}
if ($paged < $pages-1 && $paged+$range-1 < $pages && $showitems < $pages) {
$paginationData .= "<a href='".get_pagenum_link($pages)."'>»</a>";
}
$paginationData .= '</div>';
}
return $paginationData;
}
// The next function will display the portfolio element into the page. Again, paste it in the same file.
function agr_portfolio_func( $atts) {
extract(shortcode_atts(array(
'agr_portfolio_style' => 'modern',
'agr_portfolio_category' => '',
'agr_portfolio_image_size' => 'cover',
'agr_portfolio_nr_columns' => 'col-md-6 col-xs-12',
'agr_portfolio_nr_posts' => '12',
'agr_portfolio_order' => 'DESC',
'agr_portfolio_order_by' => 'date',
'agr_portfolio_class' => '',
), $atts));
if (get_query_var('paged')) {
$paged = get_query_var('paged');
} elseif (get_query_var('page')) {
$paged = get_query_var('page');
} else {
$paged = 1;
}
$type = 'portfolio-posts';
$post_per_page = $agr_portfolio_nr_posts;
if ($agr_portfolio_category == '') {
$args = array(
'post_type' => $type,
'post_status' => 'publish',
'posts_per_page' => $post_per_page,
'order' => $agr_portfolio_order,
'orderby' => $agr_portfolio_order_by,
'paged' => $paged
);
} else {
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'portfolio_categories',
'field' => 'slug',
'terms' => $agr_portfolio_category
)
),
'post_type' => $type,
'post_status' => 'publish',
'posts_per_page' => $post_per_page,
'order' => $agr_portfolio_order,
'orderby' => $agr_portfolio_order_by,
'paged' => $paged
);
}
$wp_query = null;
$wp_query = new WP_Query($args);
$dataToReturn = '<div class="portoflio-list ' . $agr_portfolio_class . '">';
if ($wp_query->have_posts()) {
$totalPages = $wp_query->max_num_pages;
while ($wp_query->have_posts()) {
$wp_query->the_post();
$title = get_post(get_post_thumbnail_id())->post_title; //The Title
$caption = get_post(get_post_thumbnail_id())->post_excerpt; //The Caption
$description = get_post(get_post_thumbnail_id())->post_content; // The Description
switch ($agr_portfolio_style) {
case "modern":
if (has_post_thumbnail()) {
$dataToReturn .= '<div id="post-' . get_the_ID() . '" class="' . join(' ', get_post_class($agr_portfolio_nr_columns)) . '">';
$dataToReturn .= '<a href="' . esc_url(get_permalink()) . '" alt="' . $description . '" title="' . $title . '">';
$dataToReturn .= '<div class="image-container" style="background-image: url(' . get_the_post_thumbnail_url() . ');background-size: ' . $agr_portfolio_image_size . '"></div>';
$dataToReturn .= '</a>';
$dataToReturn .= '<div class="content-container">';
$dataToReturn .= '<h4 class="portfolio-title">';
$dataToReturn .= '' . get_the_title() . '';
$dataToReturn .= '</h4>';
$dataToReturn .= '</div>';
$dataToReturn .= '</div>';
} else {
$dataToReturn .= '<div id="post-' . get_the_ID() . '" class="' . join(' ', get_post_class($agr_portfolio_nr_columns)) . '">';
$dataToReturn .= '<a href="' . esc_url(get_permalink()) . '" alt="' . $description . '" title="' . $title . '">';
$dataToReturn .= '<div class="image-container border-img"><h5 class="no-image-available text-center">No Img Available</h5></div>';
$dataToReturn .= '</a>';
$dataToReturn .= '<div class="content-container">';
$dataToReturn .= '<h4 class="portfolio-title">';
$dataToReturn .= '' . get_the_title() . '';
$dataToReturn .= '</h4>';
$dataToReturn .= '</div>';
$dataToReturn .= '</div>';
}
break;
case "classic":
$content = get_the_content();
$trimmed_content = wp_trim_words($content, 60, ' ...');
$vcElementsToRemove = array(
'[vc_row]',
'[/vc_row]',
'[vc_column]',
'[/vc_column]',
'[vc_column_text]',
'[/vc_column_text]',
'[vc_row_inner]',
'[/vc_row_inner]',
'[vc_column_inner width="1/2"]',
'[vc_column_inner width="1/3"]',
'[vc_column_inner width="1/4"]',
'[vc_column_inner width="1/6"]'
);
$trimmed_content = str_replace($vcElementsToRemove, "", $trimmed_content);
if (has_post_thumbnail()) {
$dataToReturn .= '<div id="post-' . get_the_ID() . '" class="' . join(' ', get_post_class($agr_portfolio_nr_columns)) . '">';
$dataToReturn .= '<a href="' . esc_url(get_permalink()) . '" alt="' . $description . '" title="' . $title . '">';
$dataToReturn .= '<div class="image-container" style="background-image: url(' . get_the_post_thumbnail_url() . ');background-size: ' . $agr_portfolio_image_size . '"></div>';
$dataToReturn .= '</a>';
$dataToReturn .= '<div class="content-container">';
$dataToReturn .= '<h4 class="portfolio-title">';
$dataToReturn .= '' . get_the_title() . '';
$dataToReturn .= '</h4>';
$dataToReturn .= '<p class="mt20">' . $trimmed_content . '</p>';
$dataToReturn .= '</div>';
$dataToReturn .= '</div>';
} else {
$dataToReturn .= '<div id="post-' . get_the_ID() . '" class="' . join(' ', get_post_class($agr_portfolio_nr_columns)) . '">';
$dataToReturn .= '<a href="' . esc_url(get_permalink()) . '" alt="' . $description . '" title="' . $title . '">';
$dataToReturn .= '<div class="image-container border-img"><h5 class="no-image-available text-center">No Img Available</h5></div>';
$dataToReturn .= '</a>';
$dataToReturn .= '<div class="content-container">';
$dataToReturn .= '<h4 class="portfolio-title">';
$dataToReturn .= '' . get_the_title() . '';
$dataToReturn .= '</h4>';
$dataToReturn .= '<p class="mt20">' . $trimmed_content . '</p>';
$dataToReturn .= '</div>';
$dataToReturn .= '</div>';
}
break;
case "newspaper":
if (has_post_thumbnail()) {
$dataToReturn .= '<div id="post-' . get_the_ID() . '" class="' . join(' ', get_post_class($agr_portfolio_nr_columns)) . '">';
$dataToReturn .= '<a href="' . esc_url(get_permalink()) . '" alt="' . $description . '" title="' . $title . '">';
$dataToReturn .= '<div class="image-container" style="background-image: url(' . get_the_post_thumbnail_url() . ');background-size: ' . $agr_portfolio_image_size . '"></div>';
$dataToReturn .= '</a>';
$dataToReturn .= '<div class="content-container">';
$dataToReturn .= '<h4 class="portfolio-title">';
$dataToReturn .= '' . get_the_title() . '';
$dataToReturn .= '</h4>';
$dataToReturn .= '</div>';
$dataToReturn .= '</div>';
}
break;
case "masonry":
if (has_post_thumbnail()) {
$dataToReturn .= '<div id="post-' . get_the_ID() . '" class="' . join(' ', get_post_class($agr_portfolio_nr_columns)) . '">';
$dataToReturn .= '<a href="' . esc_url(get_permalink()) . '" alt="' . $description . '" title="' . $title . '">';
$dataToReturn .= '<div class="image-container" style="background-image: url(' . get_the_post_thumbnail_url() . ');background-size: ' . $agr_portfolio_image_size . '"></div>';
$dataToReturn .= '</a>';
$dataToReturn .= '<div class="content-container">';
$dataToReturn .= '<h4 class="portfolio-title">';
$dataToReturn .= '' . get_the_title() . '';
$dataToReturn .= '</h4>';
$dataToReturn .= '</div>';
$dataToReturn .= '</div>';
}
break;
default:
if (has_post_thumbnail()) {
$dataToReturn .= '<div id="post-' . get_the_ID() . '" class="' . join(' ', get_post_class($agr_portfolio_nr_columns)) . '">';
$dataToReturn .= '<a href="' . esc_url(get_permalink()) . '" alt="' . $description . '" title="' . $title . '">';
$dataToReturn .= '<div class="image-container" style="background-image: url(' . get_the_post_thumbnail_url() . ');background-size: ' . $agr_portfolio_image_size . '"></div>';
$dataToReturn .= '</a>';
$dataToReturn .= '<div class="content-container">';
$dataToReturn .= '<h4 class="portfolio-title">';
$dataToReturn .= '' . get_the_title() . '';
$dataToReturn .= '</h4>';
$dataToReturn .= '</div>';
$dataToReturn .= '</div>';
}
}
}
$dataToReturn .= '<div class="col-md-12 col-xs-12 navigation text-center">';
$dataToReturn .= agr_portfolio_pagination($totalPages);
$dataToReturn .= '</div>';
} else {
$dataToReturn .= '<div id="post-404" class="noposts text-center">';
$dataToReturn .= '<p>' . _e('No Portfolio Item found.', THEME_TEXT_DOMAIN) . '</p>';
$dataToReturn .= '</div>';
}
wp_reset_postdata();
$dataToReturn .= '</div>';
return $dataToReturn;
}
Step 2 - Load the Php file into functions.php
include_once 'custom-portfolio.php';
// Also in functions.php I've created a function that will load multiple Visual Components elements.
function register_vc_shortcodes(){
add_shortcode( 'custom_portfolio', 'agr_portfolio_func' );
add_shortcode( 'other_element', 'other_element_func' );
add_shortcode( 'other_element2', 'other_element_func2' );
}
add_action( 'init', 'register_vc_shortcodes');
Important Info:
1. In order for this code to work, your custom post "register_post_type" should be "portfolio-posts"
2. The category name "register_taxonomy" should be "portfolio_categories"
3. You can change this with your own taxonomy.

Bootstrap modal implementation in wordpress codex

I'm having a little hard time here implementing a modal view to display the post content rather than sending the user to another page.
I have this
function get_grid_archive_theme( $post, $archive_template = null ) {
$archive_template = isset( $archive_template ) ? $archive_template : get_product_listing_template();
$return = '';
if ( $archive_template == 'grid' ) {
$product_id = $post->ID;
$excerpt = get_the_excerpt( $product_id );
$post_content = get_the_content( $product_id );
$image_id = get_post_thumbnail_id( $product_id );
$thumbnail_product = wp_get_attachment_image_src( $image_id, 'classic-grid-listing' );
$product_name = get_product_name();
if ( $thumbnail_product ) {
$img_class[ 'alt' ] = $product_name;
$img_class[ 'class' ] = 'classic-grid-image';
$image = wp_get_attachment_image( $image_id, 'classic-grid-listing', false, $img_class );
} else {
$url = default_product_thumbnail_url();
$image = '<img src="' . $url . '" class="classic-grid-image default-image" alt="' . $product_name . '" >';
}
$archive_price = apply_filters( 'archive_price_filter', '', $post );
$classic_grid_settings = get_classic_grid_settings();
$row_class = get_row_class( $classic_grid_settings );
$return = '<div class="col-xs-12 col-sm-6 col-md-3 product-' . $product_id . ' classic-grid ' . $row_class . ' ">';
$return .= '<a data-toggle="modal" data-target="#' . $product_id . ' " href="#">';
//$return .= '<div style="background-image:url(\'' . $url . '\');" class="classic-grid-element"></div>';
$return .= '<div class="classic-grid-image-wrapper"><div class="pseudo"></div><div class="image">' . $image . '</div></div>';
$return .= '<div class="excerpt-cnt"><div class="excerpt-text">' . $excerpt . '</div></div><h3 class="product-name">' . $product_name . '</h3>' . $archive_price;
if ( $classic_grid_settings[ 'attributes' ] == 1 && function_exists( 'product_attributes_number' ) ) {
$attributes_number = product_attributes_number();
if ( $attributes_number > 0 && has_product_any_attributes( $product_id ) ) {
$max_listing_attributes = apply_filters( 'max_product_listing_attributes', $classic_grid_settings[ 'attributes_num' ] );
$return .= '<div class="product-attributes">';
$a = 0;
for ( $i = 1; $i <= $attributes_number; $i++ ) {
$attribute_value = get_attribute_value( $i, $product_id );
if ( !empty( $attribute_value ) ) {
$return .= '<div><span class="attribute-label-listing">' . get_attribute_label( $i, $product_id ) . ':</span> <span class="attribute-value-listing">' . get_attribute_value( $i, $product_id ) . '</span> <span class="attribute-unit-listing">' . get_attribute_unit( $i, $product_id ) . '</span></div>';
$a++;
}
if ( $a == $max_listing_attributes ) {
break;
}
}
$return .= '</div>';
}
}
$return .= '</a>';
$return .= apply_filters( 'classic_grid_product_listing_element', '', $product_id );
$return .= '</div>';
}
$return .= '<div id="' . $product_id . ' " class="modal" role="dialog">';
$return .= '<div class="modal-dialog"><div class="modal-content">';
$return .= '<div class="modal-header">';
$return .= '<h4 class="modal-title">' . $product_name .'</h4>';
$return .= '</div>';
$return .= '<div class="modal-body">';
$return .= '<p>' . $post_content .'</p>';
$return .= '</div>';
$return .= '<div class="modal-footer">';
$return .= '</div>';
$return .= '</div></div>';
$return .= '</div>';
return $return;
}
This code extracts a series of posts excerpts and displays them in a 4 column layout As the picture below depicts
Each one can be clicked and it will show the content of that post in a modal. Well the thing is, it just doesn't but the modal is loaded in the DOM because when I inspect the code there are no JS errors, and the modals are shown in the HTML but still as display:none;. If I click that off or change it to block manually in the web-dev tool the modal shows.
Bootstrap is loaded in the site too. What am I missing? Why doesn't the data-target toggle the display from none to block?
I think there is just a small space problem in your code, in the line below.
$return .= '<div id="' . $product_id . ' " class="modal" role="dialog">';
Remove the space before the close of id attribute, as given below.
$return .= '<div id="' . $product_id . '" class="modal" role="dialog">';
I hope this will help!

How to modify a theme-bundled widget in child theme?

I want to remove the nofollow code from the latest posts displayed in the sidebar. I found that the code which adds rel=nofollow tag to latest post is located here
theme folder/example theme/lib/activity/plugin.php.
Here is the exact code:
private function get_latest_posts( $post_count ) {
// Get the latest posts
$latest_posts = get_posts(
array(
'numberposts' => $post_count,
'order' => 'desc',
'orderby' => 'date'
)
);
// Create the markup for the listing
$html = '<div class="tab-pane" id="recent">';
$html .= '<ul class="latest-posts">';
if( count( $latest_posts ) > 0 ) {
foreach( $latest_posts as $post ) {
$html .= '<li class="clearfix">';
// Add the small featured image
if( has_post_thumbnail( $post->ID ) ) {
$html .= '<a class="latest-post-tn fademe" href="' . get_permalink( $post->ID ) . '" rel="nofollow">';
$html .= get_the_post_thumbnail( $post->ID, array( 50, 50 ) );
$html .= '</a>';
} // end if
$html .='<div class="latest-meta">';
// Add the title
$html .= '<a href="' . get_permalink( $post->ID ) . '" rel="nofollow">';
$html .= get_the_title( $post->ID );
$html .= '</a>';
// Add date posted
// If there's no title, then we need to turn the date into the link
if( strlen( get_the_title( $post->ID ) ) == 0 ) {
$html .= '<a href="' . get_permalink( $post->ID ) . '" rel="nofollow">';
} // end if
$html .= '<span class="latest-date">';
$html .= get_the_time( get_option( 'date_format' ), $post->ID );
$html .= '</span>';
// Close the anchor
if(strlen( get_the_title( $post->ID ) ) == 0 ) {
$html .= '</a>';
} // end if
$html .='</div>';
$html .= '</li>';
} // end foreach
} else {
$html .= '<li>';
$html .= '<p class="no-posts">' . __( "You have no recent posts.", 'standard' ) . '</p>';
$html .= '</li>';
} // end if/else
$html .= '</ul>';
$html .= '</div>';
return $html;
} // end get_latest_posts
Now please tell me how to remove the nofollow tag from this code using the child theme?
Since you have control of the child theme, you can wrap the call to display the widget zone for that widget with something that grabs the output, performs a regex search/replace on it, and outputs the result. I wrote a blog post about that recently:
Filtering the output of WordPress widgets
The basics are that you have a function that replaces dynamic_sidebar() with your own function, like this:
function theme_dynamic_sidebar($index = 1) {
// capture output from the widgets
ob_start();
$result = dynamic_sidebar($index);
$out = ob_get_clean();
// do regex search/replace on $out
echo $out;
return $result;
}
Seems that you are out of luck.
That's a private function and no filter hooks are offered by the theme author.
You may try to override the include('path/to/plugin.php'); and include your own modified version.

Resources