SSbits - Home page
Site by Carbon Crayon
Submit a Post >

Tutorials - Big bits of code to help you do more

Using Short Codes to embed a YouTube video

SSBshortcodes

SilverStripe 2.4 has introduced shortcodes to the CMS editor. Simply, the CMS user can now add short BBCode style code to the editor area and it can then be replaced using a predefined function. For example [link id=23] could be replaced by the link to Page with an ID of 23. In fact that is exactly how internal links created in the links sidebar work in 2.4, preventing them from breaking when URLs change.

The aim of this tutorial

The aim of this tutorial is to allow the CMS user to enter the short code:

[YouTube id=3UTu6lV8ppY]

or

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

 

we will also allow them to add more custom attributes. We will then use this to embed a YouTube video automatically for the user.

Short code structure

Shortcodes are made up of three parts, the actual ShortCode (YouTube) its arguments (id) and its content (the text surrounded buy the tags - 'A video about SilverStripe').

The Short Code Parser

The first thing we need to do is to set-up our parser function that will handle the tag, its arguments and its content.

In Page.php we need to add our handler:

 

class Page extends SiteTree {
...
    public static function YouTubeShortCodeHandler($arguments,$caption= null,$parser = null) {
    }
...
}

 

$arguments will be an associative array and $content will be a string.

We now need to set-up some default values for the YouTube video we are going to embed, such as size, height and quality. We need to also merge the defaults with the passed arguments and then return the embed code using a template that we will create next.

 

public static function YouTubeShortCodeHandler($arguments,$caption = null,$parser = null) {
	// first things first, if we dont have a video ID, then we don't need to
	// go any further
	if (empty($arguments['id'])) {
		return;
	}
	
	$customise = array();
	/*** SET DEFAULTS ***/
	$customise['YouTubeID'] = $arguments['id'];
	//play the video on page load
	$customise['autoplay'] = false;
	//set the caption
	$customise['caption'] = $caption ? Convert::raw2xml($caption) : false;
	//set dimensions
	$customise['width'] = 640;
	$customise['height'] = 385;
	
	//overide the defaults with the arguments supplied
	$customise = array_merge($customise,$arguments);
	
	//get our YouTube template
	$template = new SSViewer('YouTube');
	
	//return the customised template
	return $template->process(new ArrayData($customise));
	
}

 

It is worth noting that the keys of the $arguments array will always be in lowercase.

The Template

In your themes folder you can now add a template called YouTube.ss; I have it in themes/mytheme/Includes as this means I can also use it hard coded into my other page templates if I need to.

YouTube.ss:

 

<div class="YouTube">
	
	<object  type="application/x-shockwave-flash" data="http://www.youtube-nocookie.com/v/$YouTubeID<% if autoplay %>&autoplay=1<% end_if %>" width="$width" height="$height">
		<embed  name="movie" value="http://www.youtube-nocookie.com/v/$YouTubeID<% if autoplay %>&autoplay=1<% end_if %>" />
	</object>
	
	<p>$VideoCaption</p>
</div>	

 

This is XHTML valid YouTube embedding code which uses our custom parameters.

Registering the Parser

Finally, we need to register the parser in our _config.php file:

 

...
//shorcodes
ShortcodeParser::get()->register('YouTube',array('Page','YouTubeShortCodeHandler'));

 

That is it, we have now created our Short Code handler and when a CMS user wants to embed a video from YouTube, they can with ease.

Example usage

[YouTube id=4af1bFh3duo width=300 height=150 related=0]blah[/YouTube]

 

Daniel Hensby avatar

Daniel Hensby

Dan runs a website development company called Better Brief. Better Brief specialise in SilverStripe websites and takes an active role in the UK SilverStripe community, attending SS Meetups and even presenting at them.

  • animasola
    17/10/2010 9:17am (4 years ago)

    I did everything you have instructed but I am unable to make it work, it still shows this on the page:

    [Youtube id=5qF_qbaWt3Q]Waiting for the End[/YouTube]

    I use v2.4.2
    I edited mysite/code/page.php and mysite/_config.php
    I created the YouTube.ss based on the template code you have shown under includes as well

  • Daniel Hensby
    17/10/2010 4:57pm (4 years ago)

    Hmmm, it's been a while since I last used this code on a site, so I'm not sure if something in the short code parser API has changed, but I doubt it has.

    If that is a direct copy of what is output on the site, then capitalisation may be the issue, it should be [YouTube ... Not [Youtube...

    See if that helps.

  • animasola
    21/10/2010 11:33am (4 years ago)

    The capitalization of the "T" actually made it recognizable but another problem arose, it now says "Movie not Loaded".

    You can check it here:
    http://asiacathcom.org/acci/

    But thanks for the great tutorial nonetheless. :)

  • animasola
    21/10/2010 12:31pm (4 years ago)

    Got it to work, there was a problem with the template file.

    There is no closing quotation mark for the data parameter after the <% end_if %>. Also shown in the code snippet above.

    Thanks for the great tut!

  • Daniel Hensby
    21/10/2010 1:02pm (4 years ago)

    Ok, i'll get onto it and fix that.

    Cheers

  • lerni
    02/01/2011 5:10pm (4 years ago)

    If you need to display Page variables you can go with Controller::curr()
    http://silverstripe.org/general-questions/show/14266

  • Rick Harvey
    12/01/2011 9:10am (4 years ago)

    Nice Tutorial!

    It might be worth noting that the shortcode handler can be any callable function (i.e. not necessarily in Page.php). For example...

    * YouTubeHelper.php:
    class YouTubeHelper {
    public function YouTubeShortCodeHandler($arguments,$caption = null,$parser = null) {
    ...
    }
    }

    * _config.php:
    ShortcodeParser::get()->register('YouTube',array('YouTubeHelper','YouTubeShortCodeHandler'));

    BTW - don't forget to rebuild (site/dev/build?flush=1)... :-)

  • William Melbourne
    01/02/2011 2:31am (4 years ago)

    great article. has any one had any success pulling up a custom form with this method, I almost had it I thought with the comment above's idea
    return Controller::curr()->MyForm()
    but that didn't work. and ideas?

  • Daniel Hensby
    01/02/2011 9:47am (4 years ago)

    @William Melbourne:
    You don't have to use short codes to allow a user to put a form in the content area.

    instead, create a function called Content() in your model (Page class or child class of Page) and do a str_replace on some predefinded variable.

    function Content() {
    return str_replace ('$Form',$this->CurrentPage()->Form()->forTemplate(), $this->Content);
    }

  • watguy
    03/02/2011 4:53am (4 years ago)

    Hi

    You mention you put it in the include folder so that your can hard code it into other templates. So how can you do this?

    Thanks for the tutorial

  • Daniel Hensby
    04/02/2011 5:27pm (4 years ago)

    @watguy: <% include YouTube %>

  • watguy
    06/02/2011 10:39pm (4 years ago)

    Yeah but if you do it that way, how do you set the youtube id, height and width etc

  • Daniel Hensby
    07/02/2011 8:50pm (4 years ago)

    Well, I have a page type for youtube videos that have those the db fields (and cms fields) to allow the user to customise the video with more ease and so I can place it in a fixed position in the template.

  • abyss
    18/02/2011 4:42pm (4 years ago)

    Damn,

    next time I should check out your site first before starting to implement new features. I was looking for something similar to chunks or snippets in ModX and basically SS short code is exactly what I was after :-)

    Thanks again, you made my day.

  • Fabs
    04/03/2011 12:10am (4 years ago)

    Hi, thanks for this tutorial, it seems that it will allow our clients to paste iframes.
    I have implemented it all however I still get nothing showing.
    Would you be able to confirm the short code parser code? You have the first code that contains $content and then the second code with $caption and it is much longer. Which code do I use? Do I replace the $content with $caption and use the 2nd code only?
    Thanks heaps.

  • Daniel Hensby
    04/03/2011 9:32am (4 years ago)

    @fabs
    ah-ha! Yes, there is a mistake there. Use the second block of code only. I'll get that fixed.

    Cheers

  • schellmax
    23/03/2011 12:09pm (3 years ago)

    thanks for this. couldn't find any documentation on shortcode parsing in the official docs, so you're filling a noticeable gap here.

  • David Amanshia
    29/03/2011 10:57am (3 years ago)

    Cheers Mr. Hensby... I'm implementing this now...

  • Artyom
    29/03/2011 2:18pm (3 years ago)

    Hi Daniel. Excellent stuff!

    Minor bug fix:
    if (!$arguments['id'])

    yields this : Undefined index: id

    it should really be

    if (!array_key_exists('id', $arguments)

    I'm sure it would be rare, but it bit me when I typed id in wrong so may bite the client! : - )

    thanks for this... I've built one for Vimeo too now

  • Darren-Lee
    09/04/2011 11:14am (3 years ago)

    Great post, Dan - very useful.
    Got me thinking about a shortcode button on the editor for inserting custom shortcodes... like this http://bit.ly/eEvtcx
    Anyone up for posting a tut on how to do that? ;)

  • Rakhesh
    11/05/2011 11:46am (3 years ago)

    Can you please help me to create a shortcode like this

    [youtube NRzesnIuSS0]

    Anyone please help me

  • martin
    08/06/2011 1:59pm (3 years ago)

    It was indeed a great trick.

  • G.
    08/07/2011 2:15pm (3 years ago)

    Great.

    How can this be enabled in the blog module?
    Thanks

  • Daniel Hensby
    08/07/2011 2:18pm (3 years ago)

    If you add this to your site, it will work in any content area, i believe.

  • G.
    08/07/2011 4:30pm (3 years ago)

    hmm. It works on pages, but not in blogentries, it shows only the [text].

  • mrsteveheyes
    15/07/2011 10:26am (3 years ago)

    Thanks so much for this tutorial.

    We at Studio Bonito have put this into a nice easy module to use. It also has a nice button for the TinyMC WYSIWYG

    Feel free to fork it form our GitHub account - https://github.com/studiobonito/silverstripe-youtubevideos

    Cheers,
    Steve

  • Daniel Hensby
    15/07/2011 10:44am (3 years ago)

    Hi mrsteveheyes,

    That looks pretty sweet. thanks!

    The code up here isn't actually complete and there are way more options that can be set. I'll try and find some time to fork and add the rest to the github repo.

    Dan

  • Simon Erkelens
    29/09/2011 10:31pm (3 years ago)

    Please, for gods sake, don't let the user think all is good!

    public function onBeforeWrite(){
    parent::onBeforeWrite();
    /**
    * Strip everything but the actual code.
    */
    if(isset($this->YoutubeCode)){
    preg_match('#(\.be/|/embed/|/v/|/watch\?v=)([A-Za-z0-9_-]{5,11})#', $this->YoutubeCode, $matches);
    if(isset($matches[2]) && $matches[2] != ''){
    $this->YoutubeCode = $matches[2];
    }
    }
    }

  • d7fresh
    23/05/2012 6:33pm (2 years ago)

    I installed the youtubevideos package created by Studio Bonito and I have embedded a YouTube video into one of SS pages on my site. It works perfectly in Firefox, Safari, Chrome and IE9, but it does not work in IE7 or IE8. In IE7 and IE8, all I get is a white box where the video should be.

    Has anyone else run into this problem?

    Cheers

  • Gordon Anderson
    15/02/2013 4:55pm (2 years ago)

    I've created a module for SIlverStripe 3 based on this tutorial, see https://github.com/gordonbanderson/weboftalent-youtube for the code. The only difference from memory was changing

    ShortcodeParser::get()

    to

    ShortcodeParser::get('default')

    in the configuration file


    Cheers

    Gordon

  • LinseyM
    08/04/2013 2:05pm (1 year ago)

    Can anyone help me with how to use "Controller::curr()", as mentioned above please?

    I've got "ClientYouTubeID" as a page variable, rather than as part of the ShortCode, so I need to be able to call the variable $ClientYouTubeID within my YouTube.ss template, and I don't understand how to do it. At the moment it just doesnt return anything.

    Thanks!

  • PeterDietz
    12/06/2013 6:01pm (1 year ago)

    I had the problem where it wasn't rendering the short codes when I added YouTubeShortCodeHandler to Page.php, but it did if I edited SomeExtendPage.php (extends Page). It turns out my problem was that even though I was adding it to Page.php, I tucked it to the bottom of my file, which isn't Page.class, but PageController.class, so if anyone is having problems, make sure your adding the method to the Page class.

    Thanks for the guide!

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image Ty Barho
6 article image Martijn van Nieuwenhoven
7 article image Darren-Lee
8 article image Roman Schmid
9 article image Matt Clegg
10 article image dalesaurus

View full leaderboard


Advertisement