How to extend visual composer with custom post as element - wordpress

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.

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 );
}

Hide specific part of Shortcode if attributes are not set

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' );

Show star ratings in comments

I followed the steps in this article: cssigniter.com/add-rating-wordpress-comment-system to add a star rating to the comments system... but when I list the comments with the code below the stars are not showing up I have tried what seems like a million things and I can not seem to figure out why the stars are not showing up.
Here is the code I am using to pull the comments
if ( is_user_logged_in() ) {
$user_id = get_current_user_id(); $args = array( 'status' => 'approve', 'user_id' => $user_id );
$comments = get_comments($args);
foreach($comments as $comment) : echo '<p>';
$post_id = $comment->comment_post_ID;
$member_name = get_post( $comment->comment_post_ID );
echo ( ' <div style="color: #00205a;"> ' . mysql2date(get_option('date_format'), $comment->comment_date) . ' - </div>' . '<a style="color:#a27747;" href="' . get_permalink( $comment->comment_post_ID ) . '">' . $member_name->post_title . '</a><br />' . '(stars go here)' . '<br />' . $comment->comment_content ). '<br /><br />';
echo '</p>';
endforeach;
}
if ( is_user_logged_in() ) {
$user_id = get_current_user_id(); $args = array( 'status' => 'approve', 'user_id' => $user_id );
$comments = get_comments($args);
foreach($comments as $comment) : echo '<p>';
$member_name = get_post( $comment->comment_post_ID );
if ( $rating = get_comment_meta( $comment->comment_ID, 'rating', true ) ) {
$stars = '<p class="stars">';
for ( $i = 1; $i <= $rating; $i++ ) {
$stars .= '<span class="dashicons dashicons-star-filled"></span>';
}
$stars .= '</p>';
}
echo ( ' <div style="color: #00205a;"> ' . mysql2date(get_option('date_format'), $comment->comment_date) . ' - </div>' . '<a style="color:#a27747;" href="' . get_permalink( $comment->comment_post_ID ) . '">' . $member_name->post_title . '</a><br />'. $stars . '<br />' . $comment->comment_content ). '<br /><br />';
echo '</p>';
endforeach;
}

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!

Drupal 7 - Place field descriptions above the field

By default in Drupal 7, field descriptions appear below the field. Is there anyway to move them above the field?
In Drupal 6, you could paste the following code in template.php to move the descriptions. However, the code does not work in Drupal 7:
/**
* Place CCK Options above field .
*/
function ThemeNAME_form_element($element, $value) {
$output = ' <div class="form-item"';
if(!empty($element['#id'])) {
$output .= ' id="'. $element['#id'] .'-wrapper"';
}
$output .= ">\n";
$required = !empty($element['#required']) ? '<span class="form-required" title="'.t('This field is required.').'">*</span>' : '';
if (!empty($element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' <label for="'. $element['#id'] .'">'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label> \n";
}
else {
$output .= ' <label>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
}
if (!empty($element['#description'])) {
$output .= ' <div class="description">' . $element['#description'] ."</div> \n";
}
$output .= " $value\n";
$output .= " </div> \n";
return $output;
}
I had the same problem and accomplished this by adding it to my theme's template.php file.
/**
* Replacement for theme_webform_element() to enable descriptions to come BEFORE the field to be filled out.
*/
function danland_webform_element($variables) {
$element = $variables['element'];
$value = $variables['element']['#children'];
$wrapper_classes = array(
'form-item',
);
$output = '<div class="' . implode(' ', $wrapper_classes) . '" id="' . $element['#id'] . '-wrapper">' . "\n";
$required = !empty($element['#required']) ? '<span class="form-required" title="' . t('This field is required.') . '">*</span>' : '';
if (!empty($element['#title'])) {
$title = $element['#title'];
$output .= ' <label for="' . $element['#id'] . '">' . t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) . "</label>\n";
}
if (!empty($element['#description'])) {
$output .= ' <div class="description">' . $element['#description'] . "</div>\n";
}
$output .= '<div id="' . $element['#id'] . '">' . $value . '</div>' . "\n";
$output .= "</div>\n";
return $output;
}
Don't forget to clear your cache!
https://drupal.org/project/label_help should also do the trick. Hope that helps
You can do a theme override for the specific field you want to change or a more general override for all fields. Read this:
http://api.drupal.org/api/drupal/modules--field--field.module/function/theme_field/7
You shouldn't have to mess with template.php at all to do this.
Rumblewand's answer, with a conditional that prevents radio/checkboxes from also being thrown into a div above the input. (May be more efficient ways to do this.)
function theme_form_element($variables) {
$element = $variables['element'];
$value = $variables['element']['#children'];
$wrapper_classes = array(
'form-item'
);
$output = '<div class="' . implode(' ', $wrapper_classes) . '" id="' . $element['#id'] . '-wrapper">' . "\n";
$required = !empty($element['#required']) ? '<span class="form-required" title="' . t('This field is required.') . '">*</span>' : '';
//Separate treatment for radio buttons & checkboxes
if (($element['#type'] == 'radio') || ($element['#type'] == 'checkbox')) {
//vs outputting input in its own div separate from label
$output .= $value . "\n";
if (!empty($element['#description'])) {
$output .= '<span class="description">' . $element['#description'] . "</span>\n";
}
if (!empty($element['#title'])) {
$title = $element['#title'];
$output .= '<label class="option" for="' . $element['#id'] . '">' . t('!title !required', array('!title' => filter_xss_admin($title), '!required' => $required)) . "</label>\n";
}
} else {
if (!empty($element['#title'])) {
$title = $element['#title'];
$output .= ' <label for="' . $element['#id'] . '">' . t('!title !required', array('!title' => filter_xss_admin($title), '!required' => $required)) . "</label>\n";
}
if (!empty($element['#description'])) {
$output .= '<div class="description">' . $element['#description'] . "</div>\n";
}
$output .= '<div id="' . $element['#id'] . '">' . $value . '</div>' . "\n";
}
$output .= "</div>\n";
return $output;
}

Resources