Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Shortcodes with HTML Content


Reply


6 Posts   1508 Views

Avatar
danzzz

Community Member, 175 Posts

13 January 2012 at 2:19am

hi there,

I'm trying to find a solution for shortcodes with HTML content, not only a YouTube Video or a map.
I know the tutorial on ssbits: http://www.ssbits.com/tutorials/2010/2-4-using-short-codes-to-embed-a-youtube-video/
where a shortcode looks like this:

[YouTube id=3UTu6lV8ppY]A video about SilverStripe[/YouTube]

What I want to do is to give the user the possibility to make a 3 column layout in the editor.

My Shortcodes look like this in the backend editor:

[Column class=one_third]

Title

bla text mext bla text mext

[/Column]

An the finished HTML Code is:

<p><div class="one_third">

</p>
<h1>Headline</h1>
<p>text mext text mext</p>
<p>

</div></p>

As you can see, there are some <p> tags generated we dont need, that breaks styling of page.

anybody had the same issue or know how to avoid this?

Avatar
Juanitou

Community Member, 323 Posts

13 January 2012 at 2:09pm

Hi!

Just a guess as you haven’t posted it, but maybe new lines in your handler function are being enclosed in <p></p> tags in the HTMLEditor.

Please, keep me informed about what do you find.

Best regards,
Juan

Avatar
danzzz

Community Member, 175 Posts

15 January 2012 at 1:44am

Edited: 15/01/2012 1:45am

juanitou

sorry, dont understand what you mean ...

this is my handler function:

public static function ColumnShortCodeHandler($arguments,$content= null,$parser = null) {
   
   if (empty($arguments['class'])) {
    return;
   }
   $customise = array();
   $customise['content'] = $content;
   $template = new SSViewer('ColumnOneThird');
   
   return $template->process(new ArrayData($customise));

}

the $content comes directly from the WYSIWYG editor.

and this is ColumnOneThird.ss

<div class="one_third">
$content
</div>

Avatar
Juanitou

Community Member, 323 Posts

15 January 2012 at 4:13am

Edited: 15/01/2012 4:16am

Hi!

Try putting the content of ColumnOneThird.ss in one line:

<div class="one_third">$content</div>

I bet you’ll obtain a different HTML result. The problem is, I guess, that as long as you use an HTMLEditorField, you’ll always get at least a pair of <p></p> enclosing the content. Some find-replace with regex in your $content variable should arrange it.

Hope it helps,
Juan

Avatar
danzzz

Community Member, 175 Posts

16 January 2012 at 12:14am

hi,

thx, this helped some, but I still have empty <p></p> tags before and after the htmlcode of the shortcode:

<div class="one_third">

<p></p>

<h1>Headline</h1>
<p>text mext text mext</p>

<p></p>

</div>

Avatar
akbortoli

Community Member, 1 Post

3 October 2012 at 11:45am

i've submitted a Pull Request with a fix to ensures that shortcodes are not wrapped in <<p>>...<</p>>

[url]https://github.com/silverstripe/sapphire/pull/838[/url]

here is the fix

[url]https://github.com/akbortoli/sapphire/commit/801b90d8907c52d941e7d1e47353d6a4100f57a6[/url]

Open "framework/parsers/ShortcodeParser.php" and add this

to the "parse" method:

public function parse($content) {
   if(!$this->shortcodes) return $content;

   $content = $this->removePTag($content);

add new method to the ShortcodeParser class:

/**
* Don't auto-p wrap shortcodes that stand alone
*
* Ensures that shortcodes are not wrapped in <<p>>...<</p>>.
*
* @param string $content The content.
* @return string The filtered content.
*/
protected function removePTag($content) {
   if(!$this->shortcodes) return $content;

   $tagregexp = join('|', array_map('preg_quote', array_keys($this->shortcodes)));

   $pattern =
       '/'
      . '<p>' // Opening paragraph
      . '\\s*+' // Optional leading whitespace
      . '(' // 1: The shortcode
      . '\\[' // Opening bracket
      . "($tagregexp)" // 2: Shortcode name
      . '\\b' // Word boundary
       // Unroll the loop: Inside the opening shortcode tag
      . '[^\\]\\/]*' // Not a closing bracket or forward slash
      . '(?:'
      . '\\/(?!\\])' // A forward slash not followed by a closing bracket
      . '[^\\]\\/]*' // Not a closing bracket or forward slash
      . ')*?'
      . '(?:'
      . '\\/\\]' // Self closing tag and closing bracket
      . '|'
      . '\\]' // Closing bracket
      . '(?:' // Unroll the loop: Optionally, anything between the opening and closing shortcode tags
      . '[^\\[]*+' // Not an opening bracket
      . '(?:'
      . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
      . '[^\\[]*+' // Not an opening bracket
      . ')*+'
      . '\\[\\/\\2\\]' // Closing shortcode tag
      . ')?'
      . ')'
      . ')'
      . '\\s*+' // optional trailing whitespace
      . '<\\/p>' // closing paragraph
      . '/s';

   return preg_replace( $pattern, '$1', $content );
}