Headline
CVE-2023-5566: shortcodes.php in smpl-shortcodes/tags/1.0.20/includes – WordPress Plugin Repository
The Simple Shortcodes plugin for WordPress is vulnerable to Stored Cross-Site Scripting via shortcodes in versions up to, and including, 1.0.20 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers with contributor-level and above permissions to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
1<?php2/**3 * SMPL Shortcodes4 *5 * (1) Columns6 * - one_sixth7 * - one_fourth8 * - one_third9 * - one_half10 * - two_third11 * - three_fourth12 * - one_fifth13 * - two_fifth14 * - three_fifth15 * - four_fifth16 * - three_tenth17 * - seven_tenth18 * (2) Components19 * - alert20 * - button21 * - divider22 * - cta23 * - callout24 * (3) Inline Elements25 * - blockquote26 * - youtube27 * - vimeo28 * (3) Tabs, Accordion, & Toggles29 * - tabs30 * - accordion31 * - toggle32 * (6) Display Posts33 * - post_grid34 */3536/*-----------------------------------------------------------*/37/* Columns38/*-----------------------------------------------------------*/3940/**41 * Columns42 *43 * @since 1.0.044 *45 * @param array $atts Standard WordPress shortcode attributes46 * @param string $content The enclosed content47 * @param string $tag Current shortcode tag48 */49function smpl_shortcode_column( $atts, $content = null, $tag = ‘’ ) {5051 // Determine if column is last in row52 $last = '’;53 if( isset( $atts[0] ) && trim( $atts[0] ) == ‘last’)54 $last = ' last’;5556 // Determine width of column57 $class = '’;5859 switch ( $tag ) {6061 case ‘one_sixth’ :62 $class .= 'one_sixth’;63 break;6465 case ‘five_sixth’ :66 $class .= 'five_sixth’;67 break;6869 case ‘one_fourth’ :70 $class .= 'one_fourth’;71 break;7273 case ‘two_sixth’ :74 case ‘one_third’ :75 $class .= 'one_third’;76 break;7778 case ‘three_sixth’ :79 case ‘one_half’ :80 $class .= 'one_half’;81 break;8283 case ‘four_sixth’ :84 case ‘two_third’ :85 case ‘two_thirds’ :86 $class .= 'two_thirds’;87 break;8889 case ‘three_fourth’ :90 case ‘three_fourths’ :91 $class .= 'three_fourths’;92 break;9394 case ‘one_fifth’ :95 $class .= 'one_fifth’;96 break;9798 case ‘two_fifth’ :99 case ‘two_fifths’ :100 $class .= 'two_fifth’;101 break;102103 case ‘three_fifth’ :104 case ‘three_fifths’ :105 $class .= 'three_fifth’;106 break;107108 case ‘four_fifth’ :109 case 'four_fifths’:110 $class .= 'four_fifth’;111 break;112113 }114115 // Is user adding additional classes?116 if ( isset( $atts[‘class’] ) ) {117 $class .= ' '.$atts[‘class’];118 }119120 // Force wpautop in shortcode? (not relevant if columns not wrapped in [raw])121 if ( isset( $atts[‘wpautop’] ) && trim( $atts[‘wpautop’] ) == ‘true’) {122 $content = wpautop( $content );123 }124125 // Return column126 $content = '<div class="’.$class.$last.’">’.$content.’</div>’;127 return do_shortcode( $content );128129}130131132133function smpl_shortcode_legacy_column_last( $atts, $content = null, $tag = ‘’ ) {134135136 // Determine width of column137 $class = '’;138139 switch ( $tag ) {140141 case ‘one_sixth_last’ :142 $class .= 'one_sixth last’;143 break;144145 case ‘two_sixth_last’ :146 $class .= 'two_sixth last’;147 break;148149 case ‘three_sixth_last’ :150 $class .= 'three_sixth last’;151 break;152153 case ‘four_sixth_last’ :154 $class .= 'four_sixth last’;155 break;156157 case ‘five_sixth_last’ :158 $class .= 'five_sixth last’;159 break;160161 case ‘one_fourth_last’ :162 $class .= 'one_fourth last’;163 break;164165 case ‘one_third_last’ :166 $class .= 'one_third last’;167 break;168169 case ‘one_half_last’ :170 $class .= 'one_half last’;171 break;172173 case ‘two_third_last’ :174 case ‘two_thirds_last’ :175 $class .= 'two_thirds last’;176 break;177178 case ‘three_fourth_last’ :179 case ‘three_fourths_last’ :180 $class .= 'three_fourths last’;181 break;182183 case ‘one_fifth_last’ :184 $class .= 'one_fifth last’;185 break;186187 case ‘two_fifth_last’ :188 case ‘two_fifths_last’ :189 $class .= 'two_fifths last’;190 break;191192 case ‘three_fifth_last’ :193 case ‘three_fifths_last’ :194 $class .= 'three_fifth last’;195 break;196197 case ‘four_fifth_last’ :198 case ‘four_fifths_last’ :199 $class .= 'four_fifth last’;200 break;201202 }203204 // Is user adding additional classes?205 if ( isset( $atts[‘class’] ) ) {206 $class .= ' '.$atts[‘class’];207 }208209 // Force wpautop in shortcode? (not relevant if columns not wrapped in [raw])210 if ( isset( $atts[‘wpautop’] ) && trim( $atts[‘wpautop’] ) == ‘true’) {211 $content = wpautop( $content );212 }213214 // Return column215 $content = '<div class="’.$class.’">’.$content.’</div><div class="clear"></div>’;216 return do_shortcode( $content );217218}219220/**221 * Clear Row222 *223 * @since 1.0.0224 */225function smpl_shortcode_clear() {226 return '<div class="clear"></div>’;227}228229/*-----------------------------------------------------------*/230/* Components231/*-----------------------------------------------------------*/232233/**234 * Button235 *236 * @since 1.0.0237 *238 * @param array $atts Standard WordPress shortcode attributes239 * @param string $content The enclosed content240 * @return string $output Content to output for shortcode241 */242243244function smpl_shortcode_button( $atts, $content = null ) {245 extract(shortcode_atts(array(246 ‘link’ => '’,247 ‘size’ => 'medium’,248 ‘color’ => '’,249 ‘class’ => '’,250 ‘block’ => 'false’,251 ‘icon_before’ => '’,252 ‘target’ => '_self’,253 ‘caption’ => '’,254 ‘align’ => 'right’255 ), $atts));256 $button =’’;257 $button .= '<div class="button-container ‘.$size.’ ‘. $align.’ '. $class.’">’;258 $button .= '<a target="’.$target.’" class="button '.$color.’" href="’.$link.’">’;259 $button .= $content;260 if ($caption != ‘’) {261 $button .= '<br /><span class="btn_caption">’.$caption.’</span>’;262 };263 $button .= '</a></div>’;264 if ($align != ‘left’ && $align != ‘right’) {265 $button .= '<div class="clear"></div>’;266 }267 return $button;268}269270271/**272 * Info Boxes273 *274 * @since 1.0.0275 *276 * @param array $atts Standard WordPress shortcode attributes277 * @param string $content The enclosed content278 * @return string $output Content to output for shortcode279 */280function smpl_shortcode_cta( $atts, $content = null ) {281282 $output = '’;283 $has_icon = '’;284285 $default = array(286 ‘style’ => 'blue’, // blue, green, grey, orange, purple, red, teal, magenta287 ‘icon’ => '’288 );289 extract( shortcode_atts( $default, $atts ) );290291 // Classes292 $classes = sprintf( 'cta info-box-%s’, $style );293294 // Add icon295 if( $icon ) {296 $classes .= ' info-box-has-icon’;297 $content = sprintf( '<i class="icon fa fa-%s"></i>%s’, $icon, do_shortcode($content) );298 }299300 $output = sprintf( '<div class="%s">%s</div>’, $classes, do_shortcode($content) );301302 return $output;303}304305/**306 * Callout Boxes (CTA)307 *308 * @since 1.0.0309 *310 * @param array $atts Standard WordPress shortcode attributes311 * @param string $content The enclosed content312 * @return string $output Content to output for shortcode313 */314function smpl_shortcode_callout( $atts, $content = null ) {315 extract( shortcode_atts( array(316 ‘style’ => 'white’,317 ‘title’ => '’,318 ‘align’ => 'center’,319 ‘centertitle’ => '’,320 ‘width’ => '’321 ), $atts ) );322323if (!empty($width)) {324 // regex to check for percentage or px symbol325 $pattern = “/%|px/";326 // if specified327 if (preg_match ($pattern, $width)) {328 $width = ‘style="width:’ . $width .’;” ';329 // else, just add px by default330 } else {331 $width = ‘style="width:’ . $width .’px;" ';332 }333 // empty. defaults to css334} else {335 $width = '’;336}337if (!empty($centertitle) && $centertitle == “true”) {338 $centertitle = 'center’;339} else {340 $centertitle = '’;341}342343 if (!empty($title)) {344 $st_callout = '<div class="st-callout hastitle ' . esc_attr($style) . ' ' . esc_attr($align) . '" '.$width.’>’;345 $st_callout .= '<h4 class="st-callout-title '.esc_attr($centertitle).’">’.esc_attr($title).’</h4><div class="inside">’;346 } else {347 $st_callout = '<div class="st-callout ' . esc_attr($style) . ' ' . esc_attr($align) . '" '.$width.’><div class="inside">’;348 }349 $st_callout .= do_shortcode($content);350 $st_callout .= '</div></div><div class="clear"></div>’;351 return $st_callout;352}353354355/**356 * Alerts357 *358 * @since 1.0.0359 *360 * @param array $atts Standard WordPress shortcode attributes361 * @param string $content The enclosed content362 * @return string $output Content to output for shortcode363 */364function smpl_shortcode_alert( $atts, $content = null ) {365366 $default = array(367 ‘class’ => '’,368 ‘style’ => 'info’, // 'info’,’alert’,’warn’,’success’,’idea’369 ‘show_icon’ => 'true’370 );371 extract( shortcode_atts( $default, $atts ) );372373 // CSS classes374 $classes = 'note’;375376377 if( in_array( $style, array( ‘info’,’alert’,’warn’,’success’,’download’,’idea’ ) ) || in_array( $class, array( ‘info’,’alert’,’warn’,’success’,’download’,’idea’ ) ) ) {378 $classes .= sprintf( ' %s’, $style );379 $classes .= sprintf( ' %s’, $class );380 }381 if ($show_icon == “false”) {382 $classes .= ' no-icon’;383 }384385 // Start output386 $output = sprintf( '<div class="%s"><div class="note-inner">’, $classes );387388 // Finish output389 $output .= do_shortcode( $content ).’</div></div>’;390391 return $output;392}393394/**395 * Divider396 *397 * @since 1.0.0398 *399 * @param array $atts Standard WordPress shortcode attributes400 * @param string $content The enclosed content401 */402function smpl_shortcode_divider( $atts, $content = null ) {403404 $default = array(405 ‘style’ => ‘solid’ // dashed, shadow, solid406 );407 extract( shortcode_atts( $default, $atts ) );408409 switch ($style) {410 case 'solid’:411 return '<hr/>’;412 break;413 case 'dashed’:414 return '<hr class="dashed"/>’;415 break;416 case 'shadow’:417 return '<div class="clearfade"></div>’;418 break;419 default:420 return '<hr/>’;421 break;422 }423}424425426427/**428 * Clear Fade429 *430 * @since 1.0.1431 */432function smpl_shortcode_clearfade() {433 return '<div class="clear"></div><div class="clearfade"></div>’;434}435436437/**438 * Blockquote439 *440 * @since 1.2.0441 *442 * @param array $atts Standard WordPress shortcode attributes443 * @param string $content The enclosed content444 */445function smpl_shortcode_blockquote( $atts, $content = null ) {446 extract(shortcode_atts(array(447 ‘quote’ => '’,448 ‘source’ => '’, // Source of quote449 ‘source_link’ => '’, // URL to link source to450 ‘align’ => '’, // How to align blockquote - left, right451 ‘class’ => ‘’ // Any additional CSS classes452 ),$atts));453454 $atts = wp_parse_args( $atts, $defaults );455456 $output .= '<blockquote>’;457 $output .= $quote;458 if ($source) {459 if ($source_link) {460 $output .= sprintf( '<br /><em><a rel="external" href="%s">%s</a></em>’, $source_link,$source );461 } else {462 $output .= sprintf( '<br /><em>— %s</em>’, $source );463 }464 }465 $output.= '</blockquote>’;466467 return $output;468}469470471/*-----------------------------------------------------------*/472/* Tabs, Accordion, & Toggles473/*-----------------------------------------------------------*/474475/**476 * Tabs477 *478 * @since 1.0.0479 *480 * @param array $atts Standard WordPress shortcode attributes481 * @param string $content The enclosed content482 * @return string $output Content to output for shortcode483 */484485function smpl_shortcode_tabgroup( $atts, $content ){486 $GLOBALS[‘tab_count’] = 0;487 $GLOBALS[‘tabs’] = '’;488 do_shortcode( $content );489 if( is_array( $GLOBALS[‘tabs’] ) ){490 foreach( $GLOBALS[‘tabs’] as $tab ){491 $tabs[] = '<li><a href="#’.$tab[‘id’].’">’.$tab[‘title’].’</a></li>’;492 $panes[] = '<li id="’.$tab[‘id’].’Tab">’.$tab[‘content’].’</li>’;493 }494 $return = “\n".’<!-- the tabs --><ul class="tabs">’.implode( “\n", $tabs ).’</ul>’."\n".’<!-- tab “panes” --><ul class="tabs-content">’.implode( “\n", $panes ).’</ul>’."\n";495 }496 return $return;497}498499function smpl_shortcode_tab( $atts, $content ){500501 extract(shortcode_atts(array(502 ‘title’ => '%d’,503 ‘id’ => ‘%d’),504 $atts));505506 $x = $GLOBALS[‘tab_count’];507508 $GLOBALS[‘tabs’][$x] = array(509 ‘title’ => sprintf( $title, $GLOBALS[‘tab_count’]),510 ‘content’ => do_shortcode($content),511 ‘id’ => $id);512513 $GLOBALS[‘tab_count’]++;514}515516/**517 * Accordion518 *519 * @since 1.0.0520 *521 * @param array $atts Standard WordPress shortcode attributes522 * @param string $content The enclosed content523 * @return string $output Content to output for shortcode524 */525function smpl_shortcode_accordion( $atts, $content = null ) {526527 $accordion_id = uniqid( 'accordion_’.rand() );528529 $output = sprintf( '<div id="%s” class="accordion">%s</div>’, $accordion_id, do_shortcode( $content ) );530531 return $output;532}533534/**535 * Toggles536 *537 * @since 1.0.0538 *539 * @param array $atts Standard WordPress shortcode attributes540 * @param string $content The enclosed content541 * @return string $output Content to output for shortcode542 */543function smpl_shortcode_toggle( $atts, $content = null ) {544545 $default = array(546 ‘title’ => '’,547 ‘open’ => 'false’,548 ‘class’ => '’549 );550 extract( shortcode_atts( $default, $atts ) );551552 // Individual toggle ID553 $toggle_id = uniqid( 'toggle_’.rand() );554555556 // Is toggle open?557 if( $open == ‘true’ ) {558 $class .= ' open’;559 }560561 $output = '562 <p class="trigger '.$class.’">563 <a href="#’.$toggle_id.’">’.$title.’</a>564 </p>565 <div class="toggle_container” style="display:none;">566 <div class="block">567 '.do_shortcode( $content ).’568 </div>569 </div>570 <div class="clear"></div>’;571572573 return $output;574}575576577578/*-----------------------------------------------------------------------------------*/579// Responsive YouTube Videos580// Usage: [youtube responsive="true” autoplay="true" controls="true" id="oHg5SJYRHA0" showinfo="true"]581/*-----------------------------------------------------------------------------------*/582583584// id // video id to embed585// responsive // true or false586// center // true or false587// width // width of video (if not responsive)588// height // height of video (if not responsive)589// autoplay // true or false590// controls // true or false591// showinfo // true or false592593function smpl_shortcode_youtube( $atts, $content = null ) {594 extract( shortcode_atts( array(595 ‘id’ => 'oHg5SJYRHA0’,596 ‘responsive’ => 'true’,597 ‘showinfo’ => 'false’,598 ‘branding’ => 'false’,599 ‘hd’ => 'true’,600 ‘related’ => 'false’,601 ‘width’ => '’,602 ‘height’ => '’,603 ‘center’ => 'false’,604 ‘autoplay’ => '0’,605 ‘theme’ => 'dark’,606 ‘controls’ => ‘true’),$atts));607608$theme = esc_attr($theme);609610$show_info = esc_attr($showinfo);611if ($show_info == “true”) { $info = '1’; }612if ($show_info == “false”) { $info = '0’; }613//$info614615$branding = esc_attr($branding);616if ($branding == “false”) { $modestbranding = '1’; }617if ($branding == “true”) { $modestbranding = '0’; }618//$modestbranding619620$related = esc_attr($related);621if ($related == “true”) { $related = '1’; }622if ($related == “false”) { $related = '0’; }623//$related624625$hd = esc_attr($hd);626if ($hd == “true”) { $showhd = '1’; }627if ($hd == “false”) { $showhd = '0’; }628//$show_hd629630$show_info = esc_attr($showinfo);631if ($show_info == “true”) { $info = '1’; }632if ($show_info == “false”) { $info = '0’; }633//$info634635$theme = esc_attr($theme);636//$theme637638if (esc_attr($autoplay) == ‘true’) {$autoplay = '1’;}639if (esc_attr($autoplay) == ‘false’) {$autoplay = '0’;}640641if (esc_attr($controls) == ‘true’) {$controls = '1’;}642if (esc_attr($controls) == ‘false’) {$controls = '0’;}643644if (esc_attr($responsive) == ‘true’) {$responsive = 'true’;}645if (esc_attr($responsive) == ‘false’) {$responsive = 'false’;}646647if (esc_attr($center) == ‘true’) {$center = 'margin:0px auto;’;}648if (esc_attr($center) == ‘false’) {$center = '’;}649650651$video_width = esc_attr($width);652$video_height = esc_attr($height);653654if (!isset($video_width) || !isset($video_height)) {655 $video = '<div class="video false"><iframe id="player" type="text/html" frameborder="0" ';656} else {657 $video = '<div class="video '.$responsive.’" style="width:’.$video_width.’px;height:’.$video_height.’px;’.$center.’"><iframe id="player" type="text/html" frameborder="0" ';658}659660if (!empty($video_width)) {661$video .= 'width="’.$video_width.’" ';662}663if (!empty($video_height)) {664$video .= 'height="’.$video_height.’" ';665}666667$video .= 'src="http://www.youtube.com/embed/’.esc_attr($id).’?autoplay=’.$autoplay.’&controls=’.$controls.’&showinfo=’.$info.’&hd=’.$showhd.’&modestbranding=’.$modestbranding.’&theme=’.$theme.’&rel=’.$related.’’;668$video .= '"></iframe></div>’;669670return $video;671}672673674/*-----------------------------------------------------------------------------------*/675// Responsive Vimeo Videos676// Usage: [vimeo responsive="true" id="6686768"]677/*-----------------------------------------------------------------------------------*/678679680// id // video id to embed681// responsive // true or false682// center // true or false683// width // width of video (if not responsive)684// height // height of video (if not responsive)685686function smpl_shortcode_vimeo( $atts, $content = null ) {687 extract( shortcode_atts( array(688 ‘id’ => '6686768’,689 ‘responsive’ => 'true’,690 ‘width’ => '’,691 ‘height’ => '’,692 ‘center’ => ‘false’),$atts));693694695if (esc_attr($responsive) == ‘true’) {$responsive = 'true’;}696if (esc_attr($responsive) == ‘false’) {$responsive = 'false’;}697698if (esc_attr($center) == ‘true’) {$center = 'margin:0px auto;’;}699if (esc_attr($center) == ‘false’) {$center = '’;}700701702$video_width = esc_attr($width);703$video_height = esc_attr($height);704705if (!isset($video_width) || !isset($video_height)) {706 $video = '<div class="video false"><iframe id="player" type="text/html" frameborder="0" ';707} else {708 $video = '<div class="video '.$responsive.’" style="width:’.$video_width.’px;height:’.$video_height.’px;’.$center.’"><iframe id="player" type="text/html" frameborder="0" ';709}710711if (!empty($video_width)) {712$video .= 'width="’.$video_width.’" ';713}714if (!empty($video_height)) {715$video .= 'height="’.$video_height.’" ';716}717$video .= 'src="//player.vimeo.com/video/’.esc_attr($id).’" ';718719$video .= 'frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>’;720721return $video;722}723724/*-----------------------------------------------------------------------------------*/725//726// Latest Posts727// Shortcode Parameters:728//729/*-----------------------------------------------------------------------------------*/730// excerpt="true|false" ------ display the excerpt or <!–more–> tag break731// length="50" ------ excerpt character length732// thumbs="true|false" ------ display featured thumbnail733// width="50" ------ featured thumbnail width734// cols="2" ------ split the results into X number of columns (4 max)735// height="50" ------ featured thumbnail height736// num="6" ------ number of entries to display737// cat="1,-2" ------ categories to include or exclude (-)738// morelink="Read More…" ------ more link text739// offset="0" ------ offset/skip X number of posts740// type="page|post" ------ query type741// parent="1" (page only) ------ page parent742// orderby="date|customfield" ------ custom ordering743// order="ASC|DESC" ------ sort order744/*-----------------------------------------------------------------------------------*/745746// Example: [latest excerpt="true" thumbs="true" width="50" height="50" num="5" cat="8,10,11"]747748/*-----------------------------------------------------------------------------------*/749750function smpl_shortcode_latest($atts, $content = null) {751 extract(shortcode_atts(array(752 “offset” => '’,753 “num” => '4’,754 “cols” => '1’,755 “thumbs” => 'false’,756 “date” => 'false’,757 “excerpt” => 'false’,758 “length” => '50’,759 “morelink” => '’,760 “width” => '100’,761 “height” => '100’,762 “type” => 'post’,763 “parent” => '’,764 “cat” => '’,765 “orderby” => 'date’,766 “order” => 'ASC’767 ), $atts));768 global $post;769770 $do_not_duplicate[] = $post->ID;771 $args = array(772 ‘post__not_in’ => $do_not_duplicate,773 ‘cat’ => $cat,774 ‘post_type’ => $type,775 ‘post_parent’ => $parent,776 ‘showposts’ => $num,777 ‘orderby’ => $orderby,778 ‘offset’ => $offset,779 ‘order’ => $order780 );781782 // query783 $myposts = new WP_Query($args);784785786 // set some variables for quicker math processing787 $count = 1;788 $col_count = $cols;789 $num_of_posts = $myposts->post_count;790 $post_per_column = ceil($num_of_posts / $col_count);791792 switch ($col_count) {793 case '4’:794 $div = “one_fourth";795 break;796 case '3’:797 $div = “one_third";798 break;799 case ‘2’:800 $div = "one_half";801 break;802 default:803 $div = “row";804 break;805 }806 // container807 $result=’<div id="category-'.$cat.’” class="latestposts">’;808809 // begin loop810 while($myposts->have_posts()) : $myposts->the_post();811812 // remove left margin from first column813 if ($count == 1) {814 $result.=’<div class="’.$div.’ alpha">’;815 }816817 // math to determine interior/last columns818 switch ($col_count) {819 case ‘4’:820 if ($count == $post_per_column * 3 + 1) {821 $result.=’<div class="’.$div.’ last">’;822 // $result.=’BEGIN LAST’;823 } elseif ($count == $post_per_column + 1 || $count == $post_per_column * 2 + 1) {824 $result.=’<div class="’.$div.’">’;825 // $result.=’BEGIN INNER’;826 }827 break;828 case ‘3’:829 if ($count == $post_per_column * 2 + 1) {830 $result.=’<div class="’.$div.’ last">’;831 // $result.=’BEGIN LAST’;832 } elseif ($count == $post_per_column + 1) {833 $result.=’<div class="’.$div.’">’;834 // $result.=’BEGIN INNER’;835 }836 break;837 case ‘2’:838 // get first item of last set839 if ($count == $post_per_column + 1) {840 $result.=’<div class="’.$div.’ last">’;841 // $result.=’BEGIN LAST’;842 }843 break;844 default:845 $result.=’’;846 break;847 }848849 // item open850 $result.=’<div class="latest-item clearfix">’;851852 // title853 if ($excerpt == ‘true’) {854 $result.=’<h4><a href="’.get_permalink().’">’.the_title(“","",false).’</a></h4>’;855 } else {856 $result.=’<div class="latest-title"><a href="’.get_permalink().’">’.the_title(“","",false).’</a></div>’;857 }858859 // post date860 if ($date == ‘true’) {861 $result.=’<div class="postmeta small"><span class="post_written">’.get_the_date().’</span></div>’;862 # code…863 }864865 // thumbnail866 if (has_post_thumbnail() && $thumbs == ‘true’) {867 if ( function_exists( ‘st_timthumb’ ) ) {868 $result.= '<img alt="’.get_the_title().’” class="alignleft latest-img” src="’.get_bloginfo(‘template_directory’).’/thumb.php?src=’.get_image_path().’&h=’.$height.’&w=’.$width.’"/>’;869 } else {870 $result .= get_the_post_thumbnail( $post->ID, 'thumbnail’, array(‘class’ => ‘alignleft latest-img’) );871 }872 }873874 // excerpt875 if ($excerpt == ‘true’) {876 // allowed tags in excerpts877 $allowed_tags = '<a>,<i>,<em>,<b>,<strong>,<ul>,<ol>,<li>,<blockquote>,<img>,<span>,<p>’;878 // filter the content879 $text = preg_replace('/\[.*\]/’, '’, strip_tags(get_the_excerpt(), $allowed_tags));880 // remove the more-link881 $pattern = '/(<a.*?class="button more-link”[^>]*>)(.*?)(<\/a>)/’;882 // display the new excerpt883 $content = preg_replace($pattern,"", $text);884 $result.= ‘<div class="latest-excerpt">’.smpl_limit_words($content,$length,’…’).’</div>’;885 }886887 // more link888 if ($morelink) {889 $result.= '<a class="button more-link” href="’.get_permalink().’">’.$morelink.’</a>’;890 }891892 // item close893 $result.=’</div>’;894895 // close columns if open896 if ($count == $post_per_column || $count == $num_of_posts || $count % $post_per_column == 0) {897 $result.=’</div>’;898 }899900 // rinse and repeat901 $count++;902903 endwhile;904 wp_reset_postdata();905906 // container close907 $result.=’<div class="clear"></div></div>’;908 return $result;909}910911912913function smpl_excerpt($words = 40, $link_text = 'Continue reading this entry »’, $allowed_tags = '’, $container = 'p’, $smileys = ‘no’ )914{915 global $post;916917 if ( $allowed_tags == ‘all’ ) $allowed_tags = '<a>,<i>,<em>,<b>,<strong>,<ul>,<ol>,<li>,<span>,<blockquote>,<img>’;918919 $text = preg_replace('/\[.*\]/’, '’, strip_tags($post->post_content, $allowed_tags));920921 $text = explode(' ', $text);922 $tot = count($text);923924 for ( $i=0; $i<$words; $i++ ) : $output .= $text[$i] . ' '; endfor;925926 if ( $smileys == “yes” ) $output = convert_smilies($output);927928 ?><p><?php echo force_balance_tags($output) ?><?php if ( $i < $tot ) : ?> …<?php else : ?></p><?php endif; ?>929 <?php if ( $i < $tot ) :930 if ( $container == ‘p’ || $container == ‘div’ ) : ?></p><?php endif;931 if ( $container != ‘plain’ ) : ?><<?php echo $container; ?> class="more"><?php if ( $container == ‘div’ ) : ?><p><?php endif; endif; ?>932933 <a href="<?php the_permalink(); ?>" title="<?php echo $link_text; ?>"><?php echo $link_text; ?></a><?php934935 if ( $container == ‘div’ ) : ?></p><?php endif; if ( $container != ‘plain’ ) : ?></<?php echo $container; ?>><?php endif;936 if ( $container == ‘plain’ || $container == ‘span’ ) : ?></p><?php endif;937 endif;938939}940941/*-----------------------------------------------------------------------------------*/942// Creates an additional hook to limit the excerpt943/*-----------------------------------------------------------------------------------*/944945function smpl_limit_words($string, $word_limit, $ending=false) {946 $content = '’;947 // creates an array of words from $string (this will be our excerpt)948 // explode divides the excerpt up by using a space character949 $words = explode(' ', $string);950 // this next bit chops the $words array and sticks it back together951 // starting at the first word ‘0’ and ending at the $word_limit952 // the $word_limit which is passed in the function will be the number953 // of words we want to use954 // implode glues the chopped up array back together using a space character955 $content .= implode(' ', array_slice($words, 0, $word_limit));956 if (count($words) > $word_limit) {957 $content .= $ending;958 }959 return $content;960}961962963function smpl_content_formatter( $content ) {964 $new_content = '’;965 $pattern_full = '{(\[raw\].*?\[/raw\])}is’;966 $pattern_contents = '{\[raw\](.*?)\[/raw\]}is’;967 $pieces = preg_split( $pattern_full, $content, -1, PREG_SPLIT_DELIM_CAPTURE );968 foreach( $pieces as $piece ) {969 if( preg_match( $pattern_contents, $piece, $matches ) )970 $new_content .= $matches[1];971 else972 $new_content .= shortcode_unautop( wpautop( wptexturize( $piece ) ) );973 }974 return $new_content;975}