Shortcode for creating a table from CSV lines

A site owner asked for an easy way to create and update a table every week from comma separated data.  The shortcode described in this post was created to satisfy that request.

After adding the shortcode to functions.php, and creating a bit of styling in the style.css file, all the owner needs to do each week is to delete the lines from the previous week and then paste in the lines from the current week between the shortcodes.

Here is an example of the simplest usage for a table with 3 columns.  First, the CSS that should be used with all tables:

.sc-table { display: table; }
.sc-table-row { display: table-row; }
.sc-table-cell { display: table-cell;  }

Now an example entry in a post:

[ sc_table columns=3]
row 1 column 1, row 1 column 2, row 1 column3
row 2 column 1, row 2 column 2, row 2 column3
[ /sc_table]

Attributes

Here are the attributes that can be used in the shortcode, with their default values:

‘columns’ => 2,
‘class_prefix’ => ‘dflt’,
‘heading’ => false,
‘cell_widths’ => ”,
‘separator’ => ‘,’,

  • columns  – the number of columns in the table.
  • class_prefix – a prefix that will be added to the class names assigned to items in the table.  Using a different prefix for each table allows you to style each table differently.
  • heading – if set to true (1), the first row will be given special class names to allow styling to be different.
  • cell_widths – a comma separated list of column width values.  Example: ‘100px,50px,125px’.
  • separator – the character that separates the values in a line.  Common separators are the comma and the semicolon.

Classes

Each element in a table is given class names to allow CSS styles to be applied.  Here are the classes assigned to each element:

  • Table – sc-table, dflt-table
  • Heading row – sc-table-row, sc-table-row-hdg, dflt-table-row, dflt-table-row-hdg
  • Odd rows – sc-table-row, dflt-table-row, sc-table-row-odd, dflt-table-row-odd
  • Even rows – sc-table-row, dflt-table-row, sc-table-row-even, dflt-table-row-even
  • Cells – sc-table-cell, sc-cell-#, dflt-table-cell, dflt-cell-#  (# is the cell number, starting with zero)

The Shortcode Function

Paste the code below into your functions.php file in your theme.

function sc_table_fn( $atts, $content='' ) {
   $atts = shortcode_atts( array(
         'columns' => 2,
         'class_prefix' => 'dflt',
         'heading' => false,
         'cell_widths' => '',
         'separator' => ',',
         ),
         $atts);
   //print_r('<pre>ATTS:');print_r($atts);print_r('</pre>');
   extract( $atts );
   $width_vals = explode( ',', $cell_widths );
   $op = '';
   if ( $content ) {
      $lines = explode( "\n", $content );
      //print_r('<pre>LINES:');print_r($lines);print_r('</pre>');
      $line_count = ( $heading ) ? 0 : 1;
      ob_start(); ?>
      <div class="sc-table <?php echo "$class_prefix-table"; ?>">
         <?php foreach ( $lines as $line ) {
            $line = preg_replace('/^<p>/', '', $line); // Strip begining p tag
            $line = preg_replace('/<\/p>$/', '', $line); // Strip ending p tag
            $line = html_entity_decode($line); // Ensure quotes are not encoded
            // Undo any WP 'smart quotes' so str_getcsv will work
            $line = preg_replace('/^(\xE2\x80\x9C|\xE2\x80\x9D|\xE2\x80\xB3|\')/', '"', $line);
            $line = preg_replace('/(\xE2\x80\x9C|\xE2\x80\x9D|\xE2\x80\xB3|\')$/', '"', $line);
            $line = preg_replace('/,(\xE2\x80\x9C|\xE2\x80\x9D|\xE2\x80\xB3|\')/', ',"', $line);
            $line = preg_replace('/(\xE2\x80\x9C|\xE2\x80\x9D|\xE2\x80\xB3|\'),/', '",', $line);
            //$debug = '';
            //for ($i=0;$i<strlen($line) ;++$i ) {
               //$debug .= $line[$i]. '=' .dechex(ord($line[$i])) . ' ';
            //}
            //print_r($debug);
            //print_r('<pre>LINE:');print_r( htmlentities($line) );print_r('</pre>');
            $stripped = strip_tags( $line );
            if ( $stripped == '' ) continue;
            if ( $heading && $line_count == 0 ) {
               ?>
               <div class="sc-table-row sc-table-row-hdg <?php echo "$class_prefix-table-row $class_prefix-table-row-hdg"; ?>">
                  <?php $cells = str_getcsv( $line, $separator );
                     //$cells = explode( $separator, $line );
                     //print_r('<pre>CELLS:');print_r($cells);print_r('</pre>');
                     for ( $cell_count = 0; $cell_count < $columns; ++$cell_count ) {
                        if ( $width_vals[$cell_count] ) {
                           $style_txt = "style='width: {$width_vals[$cell_count]};'";
                        } else {
                           $style_txt = '';
                        }
                        ?>
                        <div class="sc-table-cell <?php echo "sc-cell-$cell_count $class_prefix-table-cell $class_prefix-cell-$cell_count"; ?>" <?php echo $style_txt; ?>>
                           <?php $content = trim($cells[$cell_count]);
                              $content = preg_replace('/^[\'\"]/', '', $content);
                              $content = preg_replace('/[\'\"]$/', '', $content);
                              echo '<p>' . $content . '</p>'; ?>
                        </div>
                     <?php }
                  ?>
               </div>
            <?php } else {
               $odd_even = ( $line_count % 2 ) ? "odd" : "even";
               ?>
               <div class="sc-table-row <?php echo "$class_prefix-table-row sc-table-row-$odd_even $class_prefix-table-row-$odd_even"; ?>">
                  <?php $cells = str_getcsv( $line, $separator );
                     //print_r('<pre>CELLS:');print_r($cells);print_r('</pre>');
                     for ( $cell_count = 0; $cell_count < $columns; ++$cell_count ) {
                        if ( $width_vals[$cell_count] ) {
                           $style_txt = "style=\"width: {$width_vals[$cell_count]};\"";
                        } else {
                           $style_txt = '';
                        }
                        ?>
                        <div class="sc-table-cell <?php echo "sc-cell-$cell_count $class_prefix-table-cell $class_prefix-cell-$cell_count"; ?>" <?php echo $style_txt; ?>>
                           <?php $content = trim($cells[$cell_count]);
                              echo '<p>' . $content . '</p>'; ?>
                        </div>
                     <?php }
                  ?>
               </div>
            <?php }
            ++$line_count;
         } ?>
      </div><!-- /sc-table -->
      <?php $op = ob_get_clean();
   }
   return $op;
}
add_shortcode( 'sc_table', 'sc_table_fn' );

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*