Adding Custom EmojiOne Emoticon Plugins to TinyMCE


Sections

  1. Introduction
  2. Step 1 – Create a MySQL table to store the EmojiOne Emoji details
  3. Step 2 – Populate the Database Table
  4. Step 3 – Decide which TinyMCE Plugins to create
  5. Step 4 – Decide which category icons to use for the TinyMCE buttons
  6. Step 5 – Edit TinyMCE CSS files
  7. Step 6 – Include FontAwesome CSS
  8. Step 7 – Review the standard Emoticons Plugin
  9. Step 8 – Create a Custom EmojiOne Plugin
  10. Step 9 – Download
  11. Step 10 – Other Stuff

Introduction

Screenshots

In this post, I describe how I created some custom plugins for TinyMCE (version 4) which can be used to insert the very nice and lovely emojiOne artwork into your TinyMCE content.

This is what they look like:

Toobar icons (there are 2 rows for the 2 different versions – read on for info)

Toobar

Click on an icon to view the Emoji

Click to view Emoji

Click Emoji to insert into TinyMCE content (title and alt attributes also added)

Inserted Emoji

Background

If you use TinyMCE you might have seen the Emoticons plugin which allows you to add simple emoticons to TinyMCE.

See the Pen TinyMCE Basic Example with Emoticons Plugin by Paper Knees (@paperknees) on CodePen.

That’s a pretty limited selection of emojis for people used to the vast selection available these days on smart phones.

EmojiOne

At around the time I started using TinyMCE on something I was tinkering with I came across EmojiOne.

EmojiOne provide a huge selection of Emojis which are more in line with those people are familiar with you use smart phones, where the emojis are split into standard categories, such as people, activities, travel, food, nature, symbols, flags etc.

As well as providing the artwork files, they also have a tonne of useful resources which can be incorporated into websites, as described on this EmojiOne Github page.

EmojiOne Versions

EmojiOne makes their content available as packaged releases, in much the same way software providers release software in major and minor releases.

Version 1 was released on 4th September 2014. As at the end of October 2017, Release 3.1.2 is the latest version.

Up to and including Version 2.2.7 it used to be possible to download the EmojiOne emojis in various forms, such as:

  • PNG, 64 * 64
  • PNG, 64 * 64, Black and White
  • PNG, 128 * 128
  • PNG, 512 * 512
  • Sprites
  • SVG
  • SVG – Black and White

From Version 3 onwards, the free version includes PNG files only, in three sizes (32*32, 64*64 and 128*128), which is fair enough as a lot of work must go into creating and maintaining such a huge library of images.

For example – here are two of the same emojis, set at 256 pixels in the image definition in the HTML tag for the image:

PNG SVG
PNG SVG

The advantage of the SVG versions is that they can be scaled up without losing any of their quality, since they are Scalable Vector Graphics.

EmojiOne via CDN

Another great thing about EmojiOne (version 2) is that it’s possible to use the PNG and SVG images hosted on CDNs, or Content Delivery Networks. That means if the images are hosted on a CDN, they are being downloaded from a fast website, and any bandwidth being used up from downloading the images is not taken up on your hosting package, but on the CDNs. I haven’t found anywhere hosting the PNGs from Version 3 yet.

I have used cloudflare.com and jsdelivr.net – for example:

  1. https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.7/assets/svg/1f60e.svg
  2. https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.7/assets/png/1f60e.png
  3. https://cdn.jsdelivr.net/emojione/assets/svg/1f60e.svg
  4. https://cdn.jsdelivr.net/emojione/assets/png/1f60e.png

I wanted to work out how to integrate EmojiOne emojis with TinyMCE – I’ve done two versions, one for Version 2.2.7 (with SVGs) and another for Version 3.1 (with PNGs).

I’m not a programmer, so my disclaimer here is the process I followed is probably basic and full of flaws, but it works for me.

Step 1 – Create a MySQL table to store the EmojiOne Emoji details

Since I’m working with 2 different versions of EmojiOne, I want to split out the data into 2 different tables, so I store the details of the emojis in these MySQL tables:

  1. Version 2.2.7: xx_emoji_2
  2. Version 3 onwards: xx_emoji_3

Table definitions:


-- For version 2.2.7:

CREATE TABLE `xx_emoji_2` (
  `fld_id` int(11) NOT NULL AUTO_INCREMENT,
  `unicode` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `shortname` varchar(255) DEFAULT NULL,
  `category` varchar(255) DEFAULT NULL,
  `emoji_order` int(5) DEFAULT NULL,
  `keywords` varchar(255) DEFAULT NULL,
  `fld_last_used` datetime DEFAULT NULL,
  `fld_use_count` int(20) DEFAULT '0',
  PRIMARY KEY (`fld_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- For version 3 onwards:

CREATE TABLE `xx_emoji_3` (
  `fld_id` int(11) NOT NULL AUTO_INCREMENT,
  `unicode` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `shortname` varchar(255) DEFAULT NULL,
  `category` varchar(255) DEFAULT NULL,
  `emoji_order` int(5) DEFAULT NULL,
  `keywords` varchar(255) DEFAULT NULL,
  `fld_last_used` datetime DEFAULT NULL,
  `fld_use_count` int(20) DEFAULT '0',
  PRIMARY KEY (`fld_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

The next step covers populating the tables with data.

Step 2 – Populate the Database Table

I’ve provided 2 sets of instructions here, since the process varies slightly depending on the EmojiOne version you decide to use.

2.1 – Populate the table by looping through Version 2.2.7 emoji.json file with PHP

The advantage of Version 2.2.7 is that the SVG files are still available to be used for free (with attribution), and are available via a CDN.

Verion 2.2.7 includes 1,832 files, but only 1,820 are categorised in the json file. Each of the files belongs to a category, and has associated information with it, such as its name, unicode, shortcode etc.

Thankfully EmojiOne releases contain a JSONEmojiOne page on Github.

Once unzipped, in the root of the folder there’s a file called emoji.json. This file contains details for each emoji. Here’s the structure used, for a single Emoji:


/* Version 2.27 */
{
   "grinning":{
      "unicode":"1f600",
      "unicode_alt":"",
      "code_decimal":"😀",
      "name":"grinning face",
      "shortname":":grinning:",
      "category":"people",
      "emoji_order":"1",
      "aliases":[

      ],
      "aliases_ascii":[

      ],
      "keywords":[
         "happy",
         "smiley",
         "emotion"
      ]
   }
}

Each release also has a emoji_strategy.json file – I’m not sure why you’d use one instead of the other, but this is the format used for a single emoji, from that file:


/* Version 2.2.7 */
{
   "grinning":{
      "unicode":"1f600",
      "shortname":":grinning:",
      "aliases":"",
      "keywords":"grinning face happy smiley emotion"
   }
}

I saved that file into the relevant folder and then run some PHP code to loop through the JSON file and load the records into the MySQL table.

// link to connection file
// ... not included here

// point to the json file
$str = file_get_contents('http://localhost:8080/public_html/_dev/emoji/2.2.7/emoji.json');

// Takes a JSON encoded string and converts it into a PHP variable:
$json_a = json_decode($str, true);

// loop through the JSON data:
foreach($json_a as $key => $val) {
    
	// assign variables and give them values based on the JSON data:
	$unicode = $val['unicode'];
    $name = $val['name'];
    $shortname = $val['shortname'];
    $category = $val['category'];
    $emoji_order = $val['emoji_order'];
    $keywords = implode(',', $val['keywords']);

	// define the SQL statement
	$sql = "INSERT INTO xx_emoji_2 (unicode
								 , name
								 , shortname
								 , category
								 , keywords
								 , emoji_order) 
						   VALUES (:unicode
								 , :name
								 , :shortname
								 , :category
								 , :keywords
								 , :emoji_order)";
	
	// load the data into the MySQL table using PDO
	
	$stmt = $pdo->prepare($sql);
	
	$stmt->bindParam(':unicode', $unicode);
	$stmt->bindParam(':name', $name);
	$stmt->bindParam(':shortname', $shortname);
	$stmt->bindParam(':category', $category);
	$stmt->bindParam(':keywords', $keywords);
	$stmt->bindParam(':emoji_order', $emoji_order);
	
	$stmt->execute();

}

2.2 – Populate the table by looping through Version 3 emoji.json file with PHP

The advantage of version 3 is that it contains many more emoji designs, and the whole set has been redesigned with a new look and feel. The downside is that the files are only available as PNG files for free.

Verion 3.1.2 includes 2,666 files. Each of the files belongs to a category, and has associated information with it, such as its name, unicode, shortcode etc.

Thankfully EmojiOne releases contain a JSON file, which provides detailed information about each emoji. Therefore I downloaded the release zip file from the EmojiOne page on Github.

Once unzipped, in the root of the folder there’s a file called emoji.json. This file contains details for each emoji. Here’s the structure used, for a single Emoji (note the format is slightly different to that used in version 2.2.7:


/* Version 3.1.2 */
{
   "1f600":{
      "name":"grinning face",
      "unicode_version":6.1,
      "category":"people",
      "order":1,
      "display":1,
      "shortname":":grinning:",
      "shortname_alternates":[

      ],
      "ascii":[

      ],
      "diversity":null,
      "diversities":[

      ],
      "gender":null,
      "genders":[

      ],
      "code_points":{
         "base":"1f600",
         "fully_qualified":"1f600",
         "non_fully_qualified":"1f600",
         "output":"1f600",
         "default_matches":[
            "1f600"
         ],
         "greedy_matches":[
            "1f600"
         ],
         "decimal":""
      },
      "keywords":[
         "face",
         "grin"
      ]
   }
}

Each release also has a emoji_strategy.json file – I’m not sure why you’d use one instead of the other, but this is the format used for a single emoji, from that file:


/* Version 3.1.2 */
{
   "1f600":{
      "name":"grinning face",
      "shortname":":grinning:",
      "shortname_alternates":[

      ],
      "keywords":[
         "face",
         "grin"
      ],
      "unicode_output":"1f600"
   }
}

I saved that file into the relevant folder and then run some PHP code to loop through the JSON file and load the records into the MySQL table.

// link to connection file
// ... not included here

// point to the json file
$str = file_get_contents('http://localhost:8080/public_html/_dev/emoji/emoji_3.1.json');

// Takes a JSON encoded string and converts it into a PHP variable:
$json_a = json_decode($str, true);

// loop through the JSON data:
foreach($json_a as $key => $val) {
    
	$unicode = $val['code_points']['base'];
    $name = $val['name'];
    $shortname = $val['shortname'];
    $category = $val['category'];
    $emoji_order = $val['order'];
    $keywords = implode(',', $val['keywords']);
	 
     $sql = "INSERT INTO xx_emoji_3 (unicode
								 , name
								 , shortname
								 , category
								 , keywords
								 , emoji_order) 
						   VALUES (:unicode
								 , :name
								 , :shortname
								 , :category
								 , :keywords
								 , :emoji_order)"; 
	
 	$stmt = $pdo->prepare($sql);
	
	$stmt->bindParam(':unicode', $unicode);
	$stmt->bindParam(':name', $name);
	$stmt->bindParam(':shortname', $shortname);
	$stmt->bindParam(':category', $category);
	$stmt->bindParam(':emoji_order', $emoji_order);
	$stmt->bindParam(':keywords', $keywords);
	
	$stmt->execute();

}

Step 3 – Decide which TinyMCE Plugins to create

Once data was available in a database table, I started looking at how to edit TinyMCE to access it.

To create new buttons on the TinyMCE toolbar, I needed to write some new TinyMCE Plugins.

I’m not a programmer, as I said, so had to hack about to get this to work.

Each emoji belongs to a category. You can see the count of emojis per category via this SQL:

       SELECT category
	    , COUNT(*)
	  FROM xx_emoji_2
      GROUP BY category
      ORDER BY category;
category  count(*)  
--------  ----------
activity         139
flags            257
food              85
modifier           5
nature           160
objects          180
people           575
regional          26
symbols          275
travel           118

A lot of emojis are available in 6 different skin tonesfor example:

SVG SVG SVG SVG SVG SVG

Therefore the SQL can be revised to ignore the skin tone duplicates, assuming that’s what you want to do:

       SELECT category
	    , COUNT(*)
	  FROM xx_emoji_2
	 WHERE `unicode` NOT LIKE '%-1f3f%' 
      GROUP BY category
      ORDER BY category;
category  COUNT(*)  
--------  ----------
activity          69
flags            257
food              85
modifier           5
nature           160
objects          180
people           225
regional          26
symbols          275
travel           118

I then had a better idea about the categories I wanted to work with.

Step 4 – Decide which category icons to use for the TinyMCE buttons

I wanted to a button on the TinyMCE toolbar for each EmojiOne category.

There are various options for adding images to TinyMCE buttons – I chose to edit some of the core TinyMCE CSS and use icons from Font Awesome.

However, I also found that you can just add them directly into your plugin Javascript – for example:

    a.addButton("emojione_2_activity", {
        type: "panelbutton",
		image: 'https://oracle101.co.uk/assets/images/category_icons/v2/symbols.png',
		style: 'padding-top:4px;',
        panel: {
            role: "application",
            autohide: !0,
            html: c,
            onclick: function(b) {
                var c = a.dom.getParent(b.target, "a");
                c && (a.insertContent('' + c.getAttribute('), this.hide())
            }
        },
        tooltip: "EmojiOne - v2 - Activity"
    })

Anyway, back to using the FontAwesome method…

I had seen that it was possible to add a custom icon to TinyMCE from a question on Stack Overflow.

From the SQL above, I could see that EmojiOne’s emojis belonged to 9 categories (I didn’t create a category for ‘modifier’).

I also wanted to work out how to add “Recent” and “Popular” categories to match the type of functionality that users are familiar with on smart phones, so I needed icons for new buttons.

I had to get the CSS rule value for the Font Awesome icon I wanted to use, so used the Font Awesome Cheat Sheet to search for the icons and then copy the rule.

In the end I decided on the following:

Category Font Awesome Code Icon
Popular content: "\f077";
Recent content: "\f017";
People content: "\f118";
Nature content: "\f1b0";
Food content: "\f179";
Activity content: "\f1e3";
Travel and Places content: "\f1b9";
Objects content: "\f0eb";
Symbols content: "\f295";
Flags content: "\f024";
Letters content: "\f031";

Step 5 – Edit TinyMCE CSS files

In order for the icons to be available for TinyMCE to use, two CSS files need to be edited.

  1. tinymce\skins\lightgray\skin.min.css
  2. tinymce\skins\lightgray\skin.mobile.min.css

I wanted to split out the Version 2 and 3 emojis, so I added the following to the end of each CSS file (the versions only different in that the version 3 icons are blue, version 2 are black):

/* ###################################################################

   TinyMCE Buttons for EmojiOne Plugins, using FontAwesome Icons
   EmojiOne Version 2
   http://stackoverflow.com/questions/25191791/adding-a-custom-icon-to-a-tinymce-button 
   
   ###################################################################*/

/* poular */
.mce-i-emojione_2__popular:before {
    content: "\f077";
    font-family: FontAwesome;
	color:#000;
}

/* recent */
.mce-i-emojione_2__recent:before {
    content: "\f017";
    font-family: FontAwesome;
	color:#000;
}

/* people */
.mce-i-emojione_2_people:before {
    content: "\f118";
    font-family: FontAwesome;
	color:#000;
}

/* nature */
.mce-i-emojione_2_nature:before {
    content: "\f1b0";
    font-family: FontAwesome;
	color:#000;
}

/* food */
.mce-i-emojione_2_food:before {
    content: "\f179";
    font-family: FontAwesome;
	color:#000;
}

/* activity */
.mce-i-emojione_2_activity:before {
    content: "\f1e3";
    font-family: FontAwesome;
	color:#000;
}

/* travel */
.mce-i-emojione_2_travel:before {
    content: "\f1b9";
    font-family: FontAwesome;
	color:#000;
}

/* objects */
.mce-i-emojione_2_objects:before {
    content: "\f0eb";
    font-family: FontAwesome;
	padding-left:3px;
	color:#000;
}

/* symbols */
.mce-i-emojione_2_symbols:before {
    content: "\f295";
    font-family: FontAwesome;
	color:#000;
}

/* flags */
.mce-i-emojione_2_flags:before {
    content: "\f024";
    font-family: FontAwesome;
	color:#000;
}

/* letters */
.mce-i-emojione_2_letters:before {
    content: "\f031";
    font-family: FontAwesome;
	color:#000;
}

/* ###################################################################

   TinyMCE Buttons for EmojiOne Plugins, using FontAwesome Icons
   EmojiOne Version 3
   http://stackoverflow.com/questions/25191791/adding-a-custom-icon-to-a-tinymce-button 
   
   ###################################################################*/

/* poular */
.mce-i-emojione_3__popular:before {
    content: "\f077";
    font-family: FontAwesome;
	color:#306090;
}

/* recent */
.mce-i-emojione_3__recent:before {
    content: "\f017";
    font-family: FontAwesome;
	color:#306090;
}

/* people */
.mce-i-emojione_3_people:before {
    content: "\f118";
    font-family: FontAwesome;
	color:#306090;
}

/* nature */
.mce-i-emojione_3_nature:before {
    content: "\f1b0";
    font-family: FontAwesome;
	color:#306090;
}

/* food */
.mce-i-emojione_3_food:before {
    content: "\f179";
    font-family: FontAwesome;
	color:#306090;
}

/* activity */
.mce-i-emojione_3_activity:before {
    content: "\f1e3";
    font-family: FontAwesome;
	color:#306090;
}

/* travel */
.mce-i-emojione_3_travel:before {
    content: "\f1b9";
    font-family: FontAwesome;
	color:#306090;
}

/* objects */
.mce-i-emojione_3_objects:before {
    content: "\f0eb";
    font-family: FontAwesome;
	padding-left:3px;
	color:#306090;
}

/* symbols */
.mce-i-emojione_3_symbols:before {
    content: "\f295";
    font-family: FontAwesome;
	color:#306090;
}

/* flags */
.mce-i-emojione_3_flags:before {
    content: "\f024";
    font-family: FontAwesome;
	color:#306090;
}

/* letters */
.mce-i-emojione_3_letters:before {
    content: "\f031";
    font-family: FontAwesome;
	color:#306090;
}

Step 6 – Include FontAwesome CSS

The icons will not appear until you have included the FontAwesome CSS file in the head tags of the page that contains your TinyMCE form. Therefore, make sure to include a link to the relevant CSS file with something like this:

Once that had been done, I started looking at the process of creating the Plugins.

Step 7 – Review the standard Emoticons Plugin

TinyMCE Plugins are stored in the tinymce\plugins directory – the emoticons plugin is in tinymce\plugins\emoticons

The standard format on a plugin is that the name of the plugin will be the same as it’s plugin folder.

Therefore all Plugins have the same naming convention – they all contain a file inside the Plugin folder called plugin.min.js.

The “out of the box” emoticons plugin’s plugin.min.js file looked like this in Version 4.3.12 of TinyMCE – it has since changed (as of November 2017):

tinymce.PluginManager.add("emoticons", function(a, b) {
    function c() {
        var a;
        return a = '', tinymce.each(d, function(c) {
            a += "", tinymce.each(c, function(c) {
                var d = b + "/img/smiley-" + c + ".gif";
                a += ''
            }), a += ""
        }), a += "
" } var d = [ ["cool", "cry", "embarassed", "foot-in-mouth"], ["frown", "innocent", "kiss", "laughing"], ["money-mouth", "sealed", "smile", "surprised"], ["tongue-out", "undecided", "wink", "yell"] ]; a.addButton("emoticons", { type: "panelbutton", panel: { role: "application", autohide: !0, html: c, onclick: function(b) { var c = a.dom.getParent(b.target, "a"); c && (a.insertContent('' + c.getAttribute('), this.hide()) } }, tooltip: "Emoticons" }) });

This is my non-programmers way of explaining what the code does:

  1. The list of emoticons are defined in the d variable – e.g. cool, cry, embarassed etc.
  2. The c function loops through each set of square brackets in d and for each row, it creates a set of code for an HTML table cell. Therefore in this case you can see that the resulting table will contain 4 rows, each containing 4 emojis, since there are 4 rows of square brackets, each containing 4 values.
  3. It does a whole load of other stuff which I’m not smart enough to explain, though I have a tentative understanding of it…

Step 8 – Create a Custom EmojiOne Plugin

There are 2 ways I could approach this:

  1. Create a plugin where the list of emojis were hard coded in the JS file
    • Advantage:
      • The emojis are diplayed faster as they don’t need to be extracted from a server-side script
      • No back-end server-side scripting required
    • Disadvantage:
      • Long-winded manual process required to define the hard-coded values
      • Any changes to the content would require manual editing of the plugin JS file
      • Though you might not need to make changes very often, so the above 2 disadvantages aren’t major
  2. Create a plugin where the list of emojis were returned by a server-side script (e.g. php):
    • Advantage:
      • Changes to the content are easily made by changing the query in the PHP file or the contents of the database table linked to the PHP file
    • Disadvantage:
      • Back-end server-side scripting required

I have documented both routes here.

8.1 – PHP Version

In order to create my own version of the plugin using a PHP script to deliver the list of emojis, this is what I wanted it to do:

  1. Populate the list of emoji (variable d) from the database table – using an Ajax Request. That is – load the list of emoji into TinyMCE from the MySQL table without reloading the entire page each time I wanted to click on an emoji toolbar button
  2. Take data from the emoji database table and also include HTML title and alt tags.
  3. Use the SVG versions of the EmojiOne emojis, hosted on JSDelivr.

This is the code from the plugin.min.js used on the food plugin:

tinymce.PluginManager.add("newmoji_food", function(a, b) {
    function c() {
        var a;
        
        return a = '', tinymce.each(food, function(c) {

            a += "", tinymce.each(c, function(c) {

                var str_len = c.length;
                var pipe_pos = c.indexOf("|");
                var var_unicode = c.substr(0, pipe_pos);
                var var_title = c.substr(pipe_pos+1, str_len);
                var img_src = "https://cdn.jsdelivr.net/emojione/assets/svg/" + var_unicode + ".svg";

                a += ''

            }), a += ""
        }), a += "
" } tinymce.util.XHR.send({ url: 'emoji.php?cat=food', success: function(returnedData) { MyData = JSON.parse(returnedData); food = MyData; } }); a.addButton("newmoji_food", { type: "panelbutton", panel: { role: "application", autohide: !0, html: c, onclick: function(b) { var c = a.dom.getParent(b.target, "a"); c && (a.insertContent(''), this.hide()) } }, tooltip: "Emoticons - Food" }) });

I got it working in the end – it was a process of trial and error.

Key points:

  1. You need a emoji.php PHP page to be in the same directory as the page that your TinyMCE form is on, not in the directory that the plugin JS file is located in. So if your TinyMCE form is on example.com/working/test.php, then the emoji file needs to be in the working folder.
  2. Lines 1 and 27 contain the name of the Plugin – newmoji_food in this case, and must contain the same values, and match the name of the plugin used when you edited your CSS in Step 6, plus must match the folder name for the plugin.
  3. Lines 5 and 24 both contain an internal variable, food which must be a unique name across your emoji plugins. The value must be the same in lines 5 and 24 within each plugin.
  4. Line 13 contains the base link to the SVG images on JSDelivr.
  5. The data returned by the PHP file contains the emoji unicode name (e.g. 1f93e) and the text for the emoji’s title attribute (e.g. handball), each separated by a pipe (|)
  6. The code in the plugin splits out each emoji, assigning the unicode to one variable (var_unicode) and the title text to another (var_title).
  7. The plugin ensure that each emoji has a title attribute so that when you mouse over it after clicking a plugin button, the title attribute provides details about the emoji.
  8. The code in the plugin inserts title and alt tags into the HTML for an image into the HTML in the TinyMCE content.

The completed plugins are all available to download at the end of this post.

Create PHP file to read the data from the MySQL table

The plugins all use data from the emoji.php page. That returns the data from the table and provides it in the correct format for the plugin to split out the data and display it correctly in TinyMCE.

// link to connection file
// ... not included here

// get the querystring value
$cat = $_GET['cat'];

if (isset($_GET['cat'])) {

	// based on the category value, define the SQL statement to run
	if ($cat == "recent") {
		$sql = "SELECT unicode, name, fld_last_used FROM xx_emoji WHERE fld_last_used IS NOT NULL ORDER BY fld_last_used DESC LIMIT 72";
	} elseif ($cat == "popular") {
		$sql = "SELECT unicode, name, fld_use_count FROM xx_emoji WHERE fld_use_count > 0 ORDER BY fld_use_count DESC LIMIT 72";
	} elseif ($cat == "regional") {
		$sql = "SELECT unicode, fld_id, name FROM xx_emoji WHERE category = :cat AND unicode NOT LIKE '%-1f3f%' ORDER BY fld_id DESC";
	} else {
		$sql = "SELECT unicode, name FROM xx_emoji WHERE category = :cat AND unicode NOT LIKE '%-1f3f%'";
	}
	
	// run the SQL statement using PDO
	$stmt = $pdo->prepare($sql);
	$stmt->bindParam(':cat', $cat);
	$stmt->execute();
	$ct = $stmt->rowCount();

	$str = NULL;
	$max = $ct;
	$row_count = 18; // split the results into columns of 18 - change to suit your own requirements
	$i = 1;

	while ($row = $stmt->fetch()){
		
		// join unicode and name together, with pipe delimiter
		
		$emoji = $row['unicode'];
		$emoji_name = $row['name'];

		// for recent category, include the date the emoji was last used
		if ($cat == "recent") {
			$emoji_name = $row['name'] . " @ " . $row['fld_last_used'];
		}

		// for popular category, include the emoji's use count
		if ($cat == "popular") {
			$emoji_name = $row['name'] . ": " . $row['fld_use_count'];
		}

		// join the emoji unicode and name variables, split by the pipe
		$new = $emoji . "|" . $emoji_name;
		
		// formatting to ensure that the data is split into blocks of 18, each with a square bracket at the start end end
		$rem = $i % $row_count;
		
		if ($rem === 1) {
			$str .= "[";
		}
		
		if ($rem > 0 && $i != $max) {
			$str .= "\"$new\",";
		} else {
			$str .= "\"$new\"";
		}

		// if we still have more records to return, and are at the end of the block of 18, add a comma after the ending square bracket
		if ($rem === 0 && $i < $max) {
			$str .= "],\n";
		}
		
		// otherwise, just display the square bracket
		if ($i === $max) {
			$str .= "]\n";
		}
		
		$i++;
		
	}

	// wrap all of the output in square brackets again
	$str = "[" . $str . "]";

	// print the output to the page
	echo $str;

}

It might be that you don't want to use a scripting page to populate the list of emojis in each category, because you might not have access to a server to run a scripting language on, or might think it's overkill to use this method. If that's the case I've provided versions of the plugins which have the emoji files hard-coded in the javascript.

If you don't like the way the hard-codinng has been done, in that

Track emoji usage in xx_emoji table

In order for the emoticons_00_recent and emoticons_00_popular plugins to work, we need to track the usage of each emoji as the TinyMCE form data is submitted.

We can then track the use count for each emoji, and the last used data.

This is a summary of how I do it.

// ###############################################
// 	PROCESS FORM DATA
// ###############################################

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

	$mode = $_POST['method'];
	
	if ($mode = "send") {
		
		$config = 	HTMLPurifier_Config::createDefault(); // assumes you are using HTMLPurifier https://github.com/ezyang/htmlpurifier
		$purifier = new HTMLPurifier($config);
		
		$recBody = 	$_POST['recBody'];
		$recBody = 	str_replace('

 

','',$recBody); $recBody = $purifier->purify($recBody); // get other form data and save in relevant database table //track emojis $doc = new DOMDocument(); $doc->loadHTML($recBody); $imageTags = $doc->getElementsByTagName('img'); // look at img tags foreach($imageTags as $tag) { $img = basename($tag->getAttribute('src')) . PHP_EOL; // get data from src section $img = trim(str_replace('.svg', '', $img)); // look for the.svg file extension in the img src // search to see if that .svg file is a defined emoji $sql2 = "SELECT unicode FROM xx_emoji WHERE unicode = :img"; $stmt2 = $pdo->prepare($sql2); $stmt2->bindParam(':img', $img); $stmt2->execute(); $row = $stmt2->fetch(PDO::FETCH_ASSOC); // if it is, update the stats... if ($row) { $sql3 = "UPDATE xx_emoji SET fld_use_count = fld_use_count + 1, fld_last_used = now() WHERE unicode = :img"; $stmt3 = $pdo->prepare($sql3); $stmt3->bindParam(':img', $img); $stmt3->execute(); } } // do other stuff if required } }

8.2 - Hard-Coded Version

The JS for the plugin is very similar to that uses above - the difference is that this section:

    tinymce.util.XHR.send({
        url: 'emoji.php?cat=food',
        success: function(returnedData) {
			MyData = JSON.parse(returnedData);
            food = MyData;
        }
    });

Is replaced with:

	var food = [
    [
        "1f347|grapes",
        "1f348|melon",
        "1f349|watermelon",
        "1f34a|tangerine"
    ]
];

Except in the working version, the list of items in the food variable is a lot longer. I shortened it above to make the code more readable.

That's all there is to it.

Rather than me list all of the code above, you can download the final version of the hard-coded plugins at the end of this post.

Step 9 - Download

Download

I have bundled together the files for this post into the zip file you can download via the button above.

This is a summary of the content of the zip file:

/*
|   
+---css
|       css-for-icons.css			contains CSS to create the toolbar icons
|       
+---php_json
|       emoji_2.php					php page to serve ajax content for version2 emoji designs
|       emoji_3.php					php page to serve ajax content for version3 emoji designs
|       emoji_load_2.php			php page to parse emojione version 2.2.7 emoji.json file and save data into a database table
|       emoji_load_3.php			php page to parse emojione version 3 emoji.json file and save data into a database table
|       init.php					php page containing connection to mySQL database and PDO config
|       
+---plugins
|       plugins-dynamic.zip			zipped collection of 22 plugins, where content is created via ajax-linked PHP pages (emoji_2.php and emoji_3.php above)
|       plugins-hard-coded.zip		zipped collection of 22 plugins, where content is created via hard-coded lists of emoji designs (apart from the popular / recent plugins)
|       
\---sql
        emojione-v2-data.sql		SQL to create version 2 MySQL table and populate with 1,820 emojis
        emojione-v3-data.sql		SQL to create version 3 MySQL table and populate with 2,666 emojis

*/

Step 10 - Other Stuff

Category Lists

You can hack about with the category lists to suit - I realise the number of emojis in each category is pretty huge and unwieldy.

Inserted Image Dimensions

The size of the images once inserted into the TinyMCE content window are probably too big.

You can edit that in the `plugin.min.js` file each each plugin directory, by setting the dimensions on this line:

c && (a.insertContent('' + c.getAttribute('), this.hide())

Auto Smiley Conversion

Unfortunately this solution doesn't include anything fancy like auto smiley conversion. I've seen other solutions offering the same, such as the Smileys project on Github. I'm not smart enough to figure out how to do that.

Future Plans

I'd really like to be able to add another plugin which allows users to be able to easily search through the emojis, in much the same way has been done on the react emoji picker for use with emojione, but I have no idea how I'd start to go about that.

I have a rough idea how to go about it, but am stuck on that as at the time of writing this on 19th November 2017. I asked about it on Stackoverflow but haven't figured it out yet.

License

MIT License

Emojione is used under the Creative Commons License (CC-BY 4.0) - If you use these plugins you should also include attribute to Emojione somewhere within your website or application to satisfy the terms of the license.

Quickly navigate and search through My Oracle Support using Keyword Bookmarks

Intro

When working with Oracle I often need to look up a Note or Patch in My Oracle Support.

You can use keyword bookmarks in Firefox and Chrome to search for items using the address bar (using a combination of a pre-defined keyword followed by the search term), which saves a lot of time compared to having to open up My Oracle Support, and then clicking into the search form and searching for whatever you need, or clicking into the SR or Patch tabs and running searches from there.

In fact, they’re not always searches – for example, if you know a My Oracle Support Note, you can easily navigate to that Note ID without having to search for it using this method – you just type in the keyword bookmark (e.g. n), followed by the Note ID, press enter, and you’re redirected to the page on My Oracle Support for that Note. There’s no need to search for it in My Oracle Support – you just go direct to the right place, bypassing any searching. The same applies to Bugs, Patches and Service Requests.

Additionally, the URL I use for Service Requests is handy because unlike the link you see in an email notification to say you’ve had an update on the Service Request, this URL takes you to a version of the Service Request page which does not have relative dates. For example, instead of it saying the SR was raised 5+ months ago and was update 2 days ago, it gives you actual dates instead, which I find a lot more useful.

Firefox

1 – Type CTRL + SHIFT + B to open the Bookmark Manager:

2 – Create a new folder for your keyword bookmarks by right-clicking on the relevant folder you want to put the new folder in, and click “New Folder”:

2017-10-25-firefox-01

3 – Give the folder a name

4 – Once done, right-click the new folder and click “New Bookmark”

2017-10-25-firefox-02

5 – Add in a new Bookmark as follows:

2017-10-25-firefox-03

6 – For each of the following:

Name Location Keyword
Google – Search https://www.google.co.uk/search?q=%s gs
Google – Image Search https://www.google.co.uk/search?q=%s&tbm=isch gi
Google – Map Search https://www.google.co.uk/maps/place/%s gm
MOS – Search https://support.oracle.com/epmos/faces/KMConsolidatedSearch?kmPgTpl:r1:0:mr1:s1:mSearch:bk_srchTxt%20No%20%s sch
MOS – Note https://support.oracle.com/rs?type=doc&id=%s n
MOS – SR https://support.oracle.com/epmos/faces/SrDetail?srDetailRelativeDateParam=false&srNumber=%s sr
MOS – Patch https://support.oracle.com/rs?type=patch&id=%s p
MOS – Bug https://support.oracle.com/rs?type=bug&id=%s b

7 – When finished, the bookmarks will be listed as follows

2017-10-25-firefox-04

As you can see from the Google examples above – the same principle can be applied to any URL which includes the key bit of info in the querystring.

8 – Click the “More” down arrow to access the keyword if you want to edit it at a later date:

2017-10-25-firefox-05

The Keyword field is now visible:

2017-10-25-firefox-06

Chrome

1 – Right-click the address bar and click “Edit Search Engines”

2 – The following opens:

2017-10-25-chrome-01

3 – Click the “Add” button and add in the details – for example:

2017-10-25-chrome-02

4 – Repeat for the following:

Name Location Keyword
Google – Search https://www.google.co.uk/search?q=%s gs
Google – Image Search https://www.google.co.uk/search?q=%s&tbm=isch gi
Google – Map Search https://www.google.co.uk/maps/place/%s gm
MOS – Search https://support.oracle.com/epmos/faces/KMConsolidatedSearch?kmPgTpl:r1:0:mr1:s1:mSearch:bk_srchTxt%20No%20%s sch
MOS – Note https://support.oracle.com/rs?type=doc&id=%s n
MOS – SR https://support.oracle.com/epmos/faces/SrDetail?srDetailRelativeDateParam=false&srNumber=%s sr
MOS – Patch https://support.oracle.com/rs?type=patch&id=%s p
MOS – Bug https://support.oracle.com/rs?type=bug&id=%s b

5 – They appear as follows:

2017-10-25-chrome-03

Using Keyword Bookmarks

1 – When in Firefox or Chrome, press CTRL + L to move into the browser’s address bar.

2 – To search for a My Oracle Support Note, type the keyword (e.g. n) followed by the note ID – e.g.

2017-10-25-address-bar

3 – Press enter to run the search or redirect to the relevant Note ID, Patch, Bug or Service Request.

These are quick to set up, and once you get used to them, they save a lot of time. You can then add in others you find useful for all sorts of other websites.

SyntaxHighlighter and Bootstrap – line number alignment problem

I’m a fan of Alex Gorbatchev’s SyntaxHighlighter, which provides an easy way to include syntax highlighting in web pages.

I noticed that when using it in conjunction with the Bootstrap, that the line numbers appeared to be misaligned – here’s an example:

Misaligned line numbers

I had a look on the web, and found a solution via SyntaxHighter’s GitHub page, on an issue post about Lines misaligned with numbers.

The fix involves adding this CSS:

.syntaxhighlighter table td.gutter {
    vertical-align: middle !important;
}

As provided by Robert Butler.

Once applied, the issue was fixed: