bootstrap-3-shortcodes icon indicating copy to clipboard operation
bootstrap-3-shortcodes copied to clipboard

Nested grid

Open MWDelaney opened this issue 10 years ago • 8 comments

Hey, @filipstefansson and @simonyeldon,

We've had a few requests for supporting nested grids via shortcodes. See here: https://wordpress.org/support/topic/inner-row?replies=9

WordPress explicitly doesn't support this (see here: http://codex.wordpress.org/Shortcode_API#Nested_Shortcodes) so supporting nested shortcodes would require defining a maximum depth and adding [row-1], [row-2], [column-1], [column-2], etc.

Personally I think this over-complicates our relatively simple plugin, and does a hacky job of working around a legitimate limitation of WordPress. Documenting nested grids in a way an end-user could understand might be impossible.

Still, it's technically possible to add, so I figured I would ask you guys your opinions, too.

MWDelaney avatar Jun 27 '14 04:06 MWDelaney

Personally, for me, this is about the ONLY downfall of the plugin. The only one that I have slight frustrations with is not being able to add a caret icon to the collapsibles, but I modified the plugin for that. Nesting is really the only thing that should be more of a "requirement", because handing off a site to a client and explaining code view (so they don't mess up inline code nesting) is not an easy task.

aibrean avatar Jul 01 '14 16:07 aibrean

It's noteworthy, that other, similar plugins have answered this question the way we have historically: that it's a limitation of WordPress and that nesting shortcodes of the same name simply isn't possible.

However.

I've committed an experimental attempt at programmatically adding 10 levels of depth to every shortcode. This means we're creating 500 shortcodes rather than 50. That's a big deal. I'm not sure that we'll end up keeping this, but it's there in the repo for now.

MWDelaney avatar Jul 01 '14 20:07 MWDelaney

I was just trying to figure out how to do nested columns. I feel like this is also the only downfall of the plugin you developed. Everything else works great!

phxbulldog avatar May 09 '15 04:05 phxbulldog

Oh... that makes sense. I was scratching my head trying to work out why the markup rendered when trying to nest grid shortcodes was all wrong...

I would seriously suggest making this limitation very clear in the Wordpress plugin description.

That said, I think there should be an option for advanced users who are more likely to nest grids. It wouldn't be that hard to explain eg...

[row]
 [column]
  ...
  [row-nested-1]
   [column-nested-1]
    ...
    [row-nested-2]
     [column-nested-2]

       ...and so on up to fixed level of nesting (eg 10)... 

     [/column-nested-2]
    [/row-nested-2]
    ...
   [/column-nested-1]
  [/row-nested-1]
  ....
 [/column]
[column]
...
[/column] 
[/row]

tom-jackson avatar Jun 25 '15 07:06 tom-jackson

I needed a way to wrap a container-fluid around a container (for the background color) so I created a simple shortcode that I wrap around these shortcodes.

Here is that function:

/*****************************
 *  Container With Background With Margins (2 containers)
 *****************************/
// [full_container bg="#555" xclass="your classes"] [/full_container]
function container_func( $atts, $content = null) {
    $a = shortcode_atts( array(
        'xclass' => '',
        'bg' => '#fff'
    ), $atts );

    $color = esc_attr($a['bg']);
    $xclass = esc_attr($a['xclass']);
    $content = do_shortcode($content); // the do_shortcode makes it possible to wrap around other shortcodes

    return <<< EOD
<div class="container-fluid $xclass" style='background-color: $color'>
    <div class="container">
    $content
    </div>
</div>
EOD;

}
add_shortcode( 'full_container', 'container_func' );

And using it in wordpress:

[full_container xclass="bg-gray" bg="#ddd"]
[row][column md="6"]
<h2>Heading</h2>
Copy here... 
[/column]
[column md="6"]
[img responsive="true"]
<img src="http://placehold.it/450x250" />
[/img]
[/column]
[/row]
[/full_container]

radmation avatar Jul 11 '16 22:07 radmation

There is quite an ingenious solution/workaround for the nested shortcode problem as used in this plugin: https://pl.wordpress.org/plugins/div-shortcode/#description The idea is to use two shortcodes - one for the opening, and one for closing div: [div] and [end-div] respectively. This is easily nestable like so:

[div class="row"]
   [div class="col-md-4"]
   [end-div]
   [div class="col-md-4"]
   [end-div]
   ..... and so on .....
[end-div]

I use it this as a band-aid solution for the moment I need some columns nested. A bit hacky, but gets the job done. Maybe such shortcodes could be implemented in this plugin. For instance, called: [nrow], [end-nrow], [ncolumn], [end-ncolumn].

On the other hand, additional shortcodes might really contribute to some clutter as pointed out previously. Being able to write my own plugin for that, I am still happy with the div shortcode plugin and not consider the extra work worth it.

kmbt avatar Jan 31 '18 10:01 kmbt

At least we could use one nesting, here is what I did:

  1. added a shortcode: $shortcodes = array( ... 'row-container', ... );

  2. added a function: `function bs_row_container( $atts, $content = null ) {

$atts = shortcode_atts( array( "xclass" => false, "data" => false ), $atts );

$class = 'row'; $class .= ( $atts['xclass'] ) ? ' ' . $atts['xclass'] : '';

$data_props = $this->parse_data_attributes( $atts['data'] );

return sprintf( '<div class="%s"%s>%s', esc_attr( trim($class) ), ( $data_props ) ? ' ' . $data_props : '', do_shortcode( $content ) ); }`

  1. modified the README.html: this is how to use them `

Columns can also contain rows, to simulate a dynamic table:

[row] [column md="6"] [row-container] ... [/row-container] [row-container] ... [/row-container] [/column] [column md="6"] [row-container] ... [/row-container] [row-container] ... [/row-container] [/column] [/row]

`

It doesn't break nothing, it just adds something, so you can update your code directly.

audioscavenger avatar Feb 25 '18 23:02 audioscavenger

I've tweaked it a bit. The below works for me.

bootstrap-shortcodes.php

Update the bs_row function with the following:

function bs_row( $atts, $content = null ) {

		$atts = shortcode_atts( array(
				"xclass" => false,
				"data"   => false
		), $atts );

		$class  = 'row';
		$class .= ( $atts['xclass'] )   ? ' ' . $atts['xclass'] : '';

                $content = preg_replace('/(row-[a-z]+)/', 'row', $content);
		$content = str_replace('&#8221;', '"', $content);
		$content = str_replace('&#8243;', '"', $content);

		$data_props = $this->parse_data_attributes( $atts['data'] );

		return sprintf(
			'<div class="%s"%s>%s</div>',
			esc_attr( trim($class) ),
			( $data_props ) ? ' ' . $data_props : '',
			do_shortcode( $content )
		);
	}

The exact change is found here:

$content = preg_replace('/(row-[a-z]+)/', 'row', $content);
$content = str_replace('&#8221;', '"', $content);
$content = str_replace('&#8243;', '"', $content);

Update the bs_column function with the following:

function bs_column( $atts, $content = null ) {

		$atts = shortcode_atts( array(
				"lg"          => false,
				"md"          => false,
				"sm"          => false,
				"xs"          => false,
				"offset_lg"   => false,
				"offset_md"   => false,
				"offset_sm"   => false,
				"offset_xs"   => false,
				"pull_lg"     => false,
				"pull_md"     => false,
				"pull_sm"     => false,
				"pull_xs"     => false,
				"push_lg"     => false,
				"push_md"     => false,
				"push_sm"     => false,
				"push_xs"     => false,
				"xclass"      => false,
				"data"        => false
		), $atts );

		$class  = '';
		$class .= ( $atts['lg'] )			                                ? ' col-lg-' . $atts['lg'] : '';
		$class .= ( $atts['md'] )                                           ? ' col-md-' . $atts['md'] : '';
		$class .= ( $atts['sm'] )                                           ? ' col-sm-' . $atts['sm'] : '';
		$class .= ( $atts['xs'] )                                           ? ' col-xs-' . $atts['xs'] : '';
		$class .= ( $atts['offset_lg'] || $atts['offset_lg'] === "0" )      ? ' col-lg-offset-' . $atts['offset_lg'] : '';
		$class .= ( $atts['offset_md'] || $atts['offset_md'] === "0" )      ? ' col-md-offset-' . $atts['offset_md'] : '';
		$class .= ( $atts['offset_sm'] || $atts['offset_sm'] === "0" )      ? ' col-sm-offset-' . $atts['offset_sm'] : '';
		$class .= ( $atts['offset_xs'] || $atts['offset_xs'] === "0" )      ? ' col-xs-offset-' . $atts['offset_xs'] : '';
		$class .= ( $atts['pull_lg']   || $atts['pull_lg'] === "0" )        ? ' col-lg-pull-' . $atts['pull_lg'] : '';
		$class .= ( $atts['pull_md']   || $atts['pull_md'] === "0" )        ? ' col-md-pull-' . $atts['pull_md'] : '';
		$class .= ( $atts['pull_sm']   || $atts['pull_sm'] === "0" )        ? ' col-sm-pull-' . $atts['pull_sm'] : '';
		$class .= ( $atts['pull_xs']   || $atts['pull_xs'] === "0" )        ? ' col-xs-pull-' . $atts['pull_xs'] : '';
		$class .= ( $atts['push_lg']   || $atts['push_lg'] === "0" )        ? ' col-lg-push-' . $atts['push_lg'] : '';
		$class .= ( $atts['push_md']   || $atts['push_md'] === "0" )        ? ' col-md-push-' . $atts['push_md'] : '';
		$class .= ( $atts['push_sm']   || $atts['push_sm'] === "0" )        ? ' col-sm-push-' . $atts['push_sm'] : '';
		$class .= ( $atts['push_xs']   || $atts['push_xs'] === "0" )        ? ' col-xs-push-' . $atts['push_xs'] : '';
		$class .= ( $atts['xclass'] )                                       ? ' ' . trim($atts['xclass'], '"') : '';

                // Replaces the custom column i.e. column-a, etc. with just column so it can do_shortcode on it
		$content = preg_replace('/(column-[a-z]+)/', 'column', $content);
		$content = str_replace('&#8221;', '"', $content);
		$content = str_replace('&#8243;', '"', $content);

		$data_props = $this->parse_data_attributes( $atts['data'] );

		return sprintf(
			'<div class="%s"%s>%s</div>',
			esc_attr( trim($class) ),
			( $data_props ) ? ' ' . $data_props : '',
			do_shortcode( $content )
		);
	}

The exact change is found here:

$content = preg_replace('/(column-[a-z]+)/', 'column', $content);
$content = str_replace('&#8221;', '"', $content);
$content = str_replace('&#8243;', '"', $content);

How to use:

[row]
    [column md="6"]
        [row-b]
            [column-b md="3"]
                test
            [/column-b]
        [/row-b]
    [/column]
[/row]

alenbroi avatar Nov 02 '18 06:11 alenbroi