Just like you I am extremely excited about the release of [Newscoop 4.2] and the new [Symfony Bundles] plugin system. In the following few steps I will demonstrate to you how to get started creating a super simple Plugin for [Newscoop 4.2].
- Motivation (we won't get anywhere if you don't have this!)
- Your favourite code editor
- Git client
- (S)FTP Client for connecting to your server
- Some knowledge of how to use the Terminal
- If you're on Windows we'll be connecting via PuTTY to your Newscoop install
- Github account (we'll be needing one)
Because the new Plugin system is based on Symfony Bundles we are now able to use Packagist to maintain and update our Plugins. This allows for more flexibility and better community integration in Newscoop. Here's a quick sum-up of the advantages and disadvantages:
Advantages
- Symfony Bundle
- This means the Plugins can be extremely powerful!
- Plugin is registered on Packagist and can be installed and updated directly from the command line (web integration is coming!)
Disadvantage
- Packagist is required at the moment
Now before any Development can start we have to figure out what we want our Package to do.
In this case we are going to build a simple Plugin that generates some <meta />
tags for a Newscoop article that can be interpreted by Facebook. These are also known as OG Meta
or OpenGraph Meta
tags.
What does that mean? These tags usually look something like this:
<meta property="og:title" content="European Council candidates set to be named" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http:/www.yoursite.com/en/jan2011/politics/64/European-Council-candidates-set-to-be-named.htm" />
<meta property="og:site_name" content="The New Custodian" />
<meta property="og:description" content="BRUSSELS - Italian and Greek candidates nominated for President of the European Council in secret ballot." />
<meta property="og:image" content="http://www.yoursite.com/images/cms-image-000000092.jpg" />
These special tags are used by Facebook which uses them to display information about shared pages. Facebook however won't display everything you're now looking at, only these parts:
Title: European Council candidates set to be named
Type: Article
URL: http:/www.yoursite.com/en/jan2011/politics/64/European-Council-candidates-set-to-be-named.htm
Site Name: The New Custodian
Description: BRUSSELS - Italian and Greek candidates nominated for President of the European Council in secret ballot.
Image: http://www.yoursite.com/images/cms-image-000000092.jpg
The information that we're passing to Facebook is so that it knows what the page the user actually shared is about.
Now we have the introduction for what we want to build out of the way, it's time for some code!
I am assuming that we're developing on either a Mac or a Linux machine. If you're on Windows, bear with me, we'll get to you soon enough.
Start your Terminal (on Mac this can be found under Applications/Utilities/Terminal.app
)
In Terminal let's create a Working Directory.
user@somepc:~$ mkdir newscoop-plugin-facebook
user@somepc:~$ cd newscoop-plugin-facebook/
user@somepc:~/newscoop-plugin-facebook$ git init .
After the last command you will recieve a response similar to the one below:
Initialized empty Git repository in /Users/user/newscoop-plugin-facebook/.git/
From here on I will denote the Terminal commands with just $
only type the command AFTER the dollar-sign.
Awesome! We have just made a working directory and initialised a Git repository within it. We have to do this because Packagist requires a linked Git repository.
Now we have the basic environment we need let's make some files we will need. And because we're all lazy and a bit nerdy we'll use a cool command to quickly create a few skeleton files.
$ touch composer.json NewscoopFacebookMetaBundle.php README.md
These files don't do anything yet but they provide a blank slate to begin with.
Let's edit them.
The Composer.json is a very important file, it describes what the Plugin does and who wrote it among other things.
You should find the file in ~/newscoop-plugin-facebook
. If you are on a Mac we can use a small trick, type open .
in your Terminal and a Finder window will open at the correct directory.
Open your favourite Code Editor and open this file in it!
The following code has to be placed in it, we'll go bit by bit over it to make it more clear.
The "name" is not known yet because you haven't signed up at Packagist yet (if you have already you know what to do here) so you don't have the information yet. For now leave it as it is shown here.
{
"name": "GITHUB_USERNAME/GITHUB_REPO_NAME",
This sets a description and keywords for Packagist
"description": "My awesome Newscoop Plugin for Facebook integration",
"keywords": ["newscoop", "facebook"],
The License can be any License you want, but we like the GPL so we're going to use that.
"version": "0.1",
"type": "newscoop-plugin",
"license": "GPL-3.0",
Your name and email address, for copyright purposes!
"authors": [
{
"name": "YOUR NAME",
"email": "[email protected]"
More information about the different kinds of copyright can be found at the Creative Commons website.
The last bit, just copy it into the file.
}
],
"require": {
"php": ">=5.3.3",
"newscoop/plugins-installer": "*"
},
"autoload": {
"psr-0": { "Newscoop\\FacebookMetaBundle\\NewscoopFacebookMetaBundle": "" }
},
"target-dir": "Newscoop/FacebookMetaBundle",
"minimum-stability": "dev"
}
Now your composer.json
should be complete. Save it and close it for now.
This file we won't really use but we need it so that Newscoop understands what it has to do with the Plugin. Just copy it as shown here.
<?php
namespace Newscoop\FacebookMetaBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class NewscoopFacebookMetaBundle extends Bundle
{
}
This file can contain anything you want, usually a description of the software it accompanies, but for now you can just leave it empty.
Now let's jump back into the Terminal and create the rest of the structure we need.
$ mkdir -p Resources/smartyPlugins/
This little cool command here made 2 directories in one go. This is because of the -p
flag we gave to mkdir
.
$ touch Resources/smartyPlugins/block.facebook_meta_block.php
Now the last file of the Plugin has been created, it's time for the actual Plugin we're creating!
Newscoop currently extensively uses Smarty Block Functions
which is a really easy way to add extra logic to your already awesome Newscoop Template.
In the Plugin we will now create a new Smarty Block Function
which we will later call from our Newscoop Template.
Edit your new file block.facebook_meta_block.php
, inside the directory Resources/smartyPlugins/ and add the following blocks.
function smarty_block_facebook_meta_block($params, $content, &$smarty, &$repeat) {
This is the actual function that 'runs' the current the new Plugin.
The arguments we pass to the function are coming from Smarty. Here is a brief explanation:
$params
are the parameters Smarty passes to it internally$content
this variable holds the content inside theSmarty Function Block
inside the Template&$smarty
is the actual$smarty
object we normally have inside aSmarty
Template, this is there known as $this&$repeat
this var lets us know if theSmarty Function Block
is inside a loop and if present the iteration it's at
Continuing with the rest of the code:
if (!isset($content)) {
return '';
}
If there is $content
set inside the Template in our Smarty Function Block
we return nothing extra and assume the Templater wants to override our function in the Template.
$smarty->smarty->loadPlugin('smarty_shared_escape_special_chars');
$context = $smarty->getTemplateVars('gimme');
Load the $context
. In the Template this is normally known as $gimme
. Anything that $gimme
can give us we can now directly access in our Plugin! How cool is that?
$html = '';
Initialise and set an empty value to $html
.
if ($context->article->defined) {
Test to see if the current page we're going to be displayed on is actually an article. Equivalent to $gimme->article->defined
Now the fun part! The actual code we want to load extra in our HTML so that Facebook knows what what!
We set the og:title
meta property and are telling the content to be $context->article->name
(again the same as: $gimme->article->name
)
$html .= '<meta property="og:title" content="'.$context->article->name.'" />'."\n";
We are using the shorthand for concatenating the strings in PHP .=
. We could have also written it as: $html = $html . 'new string';
, but that's very messy and error prone.
Because we have to add in extra variables
in that variable
string we concatenate these by using again the .
operator in PHP.
Example: $html .= 'Foo Bar'.$var;
means literally: "Add the text 'Foo Bar' to the variable
$html
and join it together with $var
".
If you find this scary, do not wit, it's not required to finish this tutorial! It's just explaining a bit of the PHP parts we're using.
Set the og:type
meta property and are telling the content to be article. We do this hard-coded because we know it's always an Article (remember the Test to see if it's an article or not?)
$html .= '<meta property="og:type" content="article" />'."\n";
Facebook also really wants to know what the URL is that you want your visitors to use to link back to your article. Here we call to an internal Newscoop Smarty Function to generate the correct URL for the Article. If you however have special visitor tracking and whatnot you could of course place that all in here too!.
To recap: set the og:url
's content to: 'http:/'.$context->publication->site
. smarty_function_uri($params, $smarty)
.
$html .= '<meta property="og:url" content="http:/'.$context->publication->site. smarty_function_uri($params, $smarty) .'" />'."\n";
Of course we should not forget to set the Site Name!
Set og:site_name
to context->publication->name
$html .= '<meta property="og:site_name" content="'. $context->publication->name .'" />'."\n";
And because we can we show the Article Deck in the Facebook share too!
Important It might be that your Newscoop install doesn't have the Deck
type inside an Article. Check this first!
Set the og:description
to strip_tags($context->article->deck)
. We place the $context->article->deck
inside the PHP function strip_tags
first to prevent that we might have a <b>
or similar in that block of text.
$html .= '<meta property="og:description" content="'.strip_tags($context->article->deck).'" />'."\n";
Not every Newscoop Article has an Image. We certainly try (at least I hope you do!) but to prevent that it will show a 404 not found
error or something similar when someone Shares your awesome Newscoop Article we do a small Test to see if the article actually has an image. We do this with $context->article->image->imageurl
. This variable
contains an URL. PHP is really smart so if it's empty it will automatically return false
and it won't go inside the Test block.
if ($context->article->image->imageurl) {
Awesome! Turns out you do have an image! We set the og:image
's content to: $context->article->image->imageurl
which will generate the correct URL for the Image of your Newscoop Article.
$html .= '<meta property="og:image" content="'. $context->article->image->imageurl .'" />'."\n";
And of course, we have to close the current Test!
}
Remember testing before if it's an article? Here we define what it should do in case it's not.
} else {
We tell it to simply show the Newscoop Site Name
$html .= '<meta property="og:site_name" content="'. $context->publication->name .'" />'."\n";
Close the Test to see if it's an article.
}
Return the $html
variable we have now filled with awesome Facebook compatible OpenGraph Meta Tags
.
return $html;
And last but not least, close the Smarty Function Block
}
Now save the file block.facebook_meta_block.php
, take a short break or let's continue! Cause we're almost done!
Because we're using Git we should of course not forget to commit our changes! Also we need to do this because eventually we're going to Push our changes to Github.
$ git add .
$ git commit -m "Initial commit of my awesome Newscoop Plugin"
Now go and Register with Github and come back here once your done
Ah good, your back! Ok Github has some awesome docs to get you started etc and you should have already read through them (right?).
Now, in Github you should create a Repository
. Also great guides on Github for those! Look them through!
Now we have to add the Remote Github Repo to our local Repo. We do this with the following command:
This adds the new Remote Repo
$ git remote add origin YOUR_GITHUB_REPO_URL
And with this command we can check if it was successful
$ git remote -v
If you want more info you can check with the Github Help themselves
Before we didn't set the correct package name in our composer.json
which we know now!
Open up your composer.json
and change the following to reflect your Github Username and Github Repository Name
"name": "GITHUB_USERNAME/GITHUB_REPO_NAME",
We have to one more time commit to reflect these changes:
$ git add composer.json
$ git commit -m "Update to the composer.json"
Now to actually Push our changes
$ git push origin
Now take a look at your Github Repository page, refresh it and you'll see the new files we just created. Almost there!
Now we got to setup Packagist. Luckily we just registered already with Github and Packagist allows us to Login with the Github account information.
Go the the Packagist Login page and click on Login with Github
.
After login we can Submit a Package, which asks for your Github Repository URL. Paste in the same URL we used before in the section Add the Remote Github Repo to our local Git repo
If everything went alright, you should now have your Plugin registered with Packagist!
Now for the real deal! On the server where you run Newscoop 4.2 we have to do a few things to install the Plugin. Connect to it via SSH and we're off!
The following commands are assuming we're on the server that has Newscoop 4.2 installed!
First we change directories to where the Newscoop install is, this is usually /var/www/newscoop/
but can vary depending on your setup.
$ cd /var/www/newscoop/
Now we are going to install the Plugin! Go to Packagist and there you can find the full name of your Packagist package. This should usually be the same as the Github repo but we can better check!
Replace that in the following command and execute it.
$ php application/console plugins:install "PACKAGIST_USER/PACKAGIST_PACKAGE_NAME" --env=prod
To explain what it does:
php
tells the Command Line PHP application to execute the following statements.application/console
tells PHP to run it in our application enviroment from the console.plugins:
tells the application enviroment we're focusing on the pluginsinstall
of course installs! This can also beupdate
(orremove
but why would you want that?)--env=prod
is required that it installs it in the Production enviroment where your Site will be running in.
If everything went alright your Plugin is now Installed! But, one more important bit we should NOT forget!
We have to modify your existing Template to include the new Plugin, if we don't it'll never show anything and all this precious work was for nothing!
This varies from theme to theme but I'll show you where to do this using the Sample Site Rockstar
.
The file we need to edit is located then here YOURNEWSCOOPDIR/themes/publication_2/theme_1/_tpl/_html-head.tpl
Find a bit where you want to add it to in the <head>
and place the following code:
{{ facebook_meta_block }}{{ /facebook_meta_block }}
If your current Template already has Open Graph Meta
tags, remove them else we'll have them double.
Clear out the Newscoop cache.
Load your Newscoop site with an article open. Now take a look in the Source Code
and look in the <head>
part of the page.
You should now see something like:
<meta property="og:title" content="European Council candidates set to be named" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http:/www.yoursite.com/en/jan2011/politics/64/European-Council-candidates-set-to-be-named.htm" />
<meta property="og:site_name" content="The New Custodian" />
<meta property="og:description" content="BRUSSELS - Italian and Greek candidates nominated for President of the European Council in secret ballot." />
<meta property="og:image" content="http://www.yoursite.com/images/cms-image-000000092.jpg" />
If this is the case, high-five yourself cause your done! You just made your own Plugin!
This was a very simple Plugin and in another post I will show you how to create a more complex Plugin which will respond to Newscoop Events
.