Extension:Emoticons

From MediaWiki.org
Jump to navigation Jump to search

Other languages:
Deutsch • ‎English • ‎dansk • ‎日本語

Warning Warning:

This extension makes forum-style emoticon (smiley) replacements within MediaWiki. See the list of emoticons below.


Installation[edit]

Install[edit]

1. Create the file: extensions/Emoticons/Emoticons.php

2. Add the following to the end of: LocalSettings.php

require_once($IP."/extensions/Emoticons/Emoticons.php");

3. Create the page "MediaWiki:Emoticons"

4. Add one line to this page for each emoticon. Each line contains the text to be replaced followed by "//" followed by the text to replace it with.

Source code[edit]

<?php
 
# Emoticon MediaWiki Extension
# Created by Alex Wollangk (alex@wollangk.com), and Techjar (tecknojar@gmail.com)

if ( !defined( 'MEDIAWIKI' ) ) {
	die( 'This file is a MediaWiki extension, it is not a valid entry point.' );
}
 
global $wgHooks;
global $wgExtensionCredits;
 
$wgExtensionCredits['parserhook'][] = array(
	'name' => 'Emoticons',
	'status' => 'stable',
	'type' => 'hook',
	'author' => 'Alex Wollangk, Techjar',
	'version' => '1.2.3',
	'update' => '8-13-2009',
	'url' => 'http://www.mediawiki.org/wiki/Extension:Emoticons',
	'description' => 'Enable forum-style emoticon (smiley) replacement within MediaWiki.',
);
 
$wgHooks['ParserAfterStrip'][] = 'fnEmoticons';

// fnStringBetween function
function fnStringBetween( $string, $start, $end ) {
	$string = " ".$string;
	if( strlen( $string ) > strlen( $start ) )
	{
		$ini = strpos( $string, $start );
		if( $ini === false )
		{
			return false;
		}
		else
		{
			$ini = $ini + strlen( $start );   
			$len = strpos( $string, $end, $ini ) - $ini;
			return substr( $string, $ini, $len );
		}
	}
	else
	{
		return false;
	}
}
 
// The callback function for replacing emoticons with image tags
function fnEmoticons( &$parser, &$text, &$strip_state ) {
	global $action; // Access the global "action" variable
	// Only do the replacement if the action is not edit or history
	if(
		$action !== 'edit'
		&& $action !== 'history'
		&& $action !== 'delete'
		&& $action !== 'watch'
		&& strpos( $parser->getTitle()->getPrefixedText(), 'Special:' ) === false
		&& $parser->getTitle()->getNamespace() !== 8
	)
	{
		// Get the list of emoticons from the "MediaWiki:Emoticons" article.
		$title = Title::makeTitle( 8, 'Emoticons' );
		$emoticonListArticle = new WikiPage( $title );
		$content = $emoticonListArticle->getContent();
 
		// If the content successfully loaded, do the replacement
		if ( $content )
		{
			$contentText = ContentHandler::getContentText( $content );
			$emoticonList = explode( "\n", $contentText );
			foreach( $emoticonList as $index => $emoticon )
			{
				$currEmoticon = explode( "//", $emoticon, 2 );
				if( count($currEmoticon) == 2 )
				{
					// start by trimming the search value
					$currEmoticon[ 0 ] = trim( $currEmoticon[ 0 ] );
					// if the string begins with &nbsp;, lop it off
					if( substr( $currEmoticon[ 0 ], 0, 6 ) == '&nbsp;' )
					{
						$currEmoticon[ 0 ] = trim( substr( $currEmoticon[ 0 ], 6 ) );
					}
					// trim the replacement value
					$currEmoticon[ 1 ] = trim( $currEmoticon[ 1 ] );
					// and finally perform the replacement
					$text = str_ireplace( " ".$currEmoticon[ 0 ], " ".$currEmoticon[ 1 ], $text );
					// <nowiki> tag parser
					$a = 0;
					$text2 = array();
					// loop through the <nowiki> tags
					while( ( $nowiki_text = fnStringBetween( $text, "<nowiki>", "</nowiki>" ) ) && $a < 10 )
					{
						// replace the <nowiki> with a 'placeholder' tag
						$text = str_ireplace( "<nowiki>".$nowiki_text."</nowiki>", "[nowiki".$a."]", $text );
						// replace the images with text
						$text2[ $a ] = str_ireplace( $currEmoticon[ 1 ], " ".$currEmoticon[ 0 ], $nowiki_text);
						$a++;
					}
					$a--;
					// now do the <nowiki> replacement, and loop through the $text2 array()
					while( $a > -1 )
					{
						// reinsert the <nowiki> tag
						$text = str_ireplace( "[nowiki".$a."]", "<nowiki>".$text2[ $a ]."</nowiki>", $text );
						$a--;
					}
				}
			}
		}
	}
	// Always a good practice to let the other hooks have their turn ... whenever it make sense.
	return true;
}

Sample MediaWiki:Emoticons[edit]

Here is a sample list of emoticons:

 :D//[[Image:VeryHappy.gif]]
 :-D//[[Image:VeryHappy.gif]]
 :grin://[[Image:VeryHappy.gif]]
 :)//[[Image:Smile.gif]]
 :-)//[[Image:Smile.gif]]
 :smile://[[Image:Smile.gif]]
 :(//[[Image:Sad.gif]]
 :-(//[[Image:Sad.gif]]
 :sad://[[Image:Sad.gif]]
 :o//[[Image:Surprised.gif]]
 :-o//[[Image:Surprised.gif]]
 :eek://[[Image:Surprised.gif]]
 :shock://[[Image:Shocked.gif]]
 :?//[[Image:Confused.gif]]
 :-?//[[Image:Confused.gif]]
 :???://[[Image:Confused.gif]]
 8)//[[Image:Cool.gif]]
 8-)//[[Image:Cool.gif]]
 :cool://[[Image:Cool.gif]]
 :lol://[[Image:Laughing.gif]]
 :x//[[Image:Mad.gif]]
 :-x//[[Image:Mad.gif]]
 :mad://[[Image:Mad.gif]]
 :P//[[Image:Razz.gif]]
 :-P//[[Image:Razz.gif]]
 :razz://[[Image:Razz.gif]]
 :oops://[[Image:Embarassed.gif]]
 :cry://[[Image:CryingorVerySad.gif]]
 :evil://[[Image:EvilorVeryMad.gif]]
 :twisted://[[Image:TwistedEvil.gif]]
 :roll://[[Image:RollingEyes.gif]]
 :wink://[[Image:Wink.gif]]
 ;)//[[Image:Wink.gif]]
 ;-)//[[Image:Wink.gif]]
 :!://[[Image:Exclamation.gif]]
 :?://[[Image:Question.gif]]
 :idea://[[Image:Idea.gif]]
 :arrow://[[Image:Arrow.gif]]
 :|//[[Image:Neutral.gif]]
 :-|//[[Image:Neutral.gif]]
 :neutral://[[Image:Neutral.gif]]
 :mrgreen://[[Image:Mr.Green.gif]]

Bugs[edit]

This extension does not seem to work for included pages. Is this 'generic' or specific maybe caused by some extension we use. Any help?

Does not work with mediawiki 1.12.[edit]

see discussion

About the Code[edit]

(If you don't care about how this extension was written, ignore the following section.)

When writing this extension the biggest challenge I had was accessing the MediaWiki:Emoticons article. I wanted to use the existing framework rather than use SQL to help insure that it would continue to work even if the database structure is updated. A fair amount of searching did not come up with many hints on how to do this, however. At one point I tried to access the article through the global $mediaWiki object, but that object has not been instantiated when LocalSettings.php is included and so extensions do not have access to it. I finally made the decision to manually instantiate an "Article" which requires instantiating a "Title" and use that "Article" to load the appropriate page.

A few other notes:

  • I started out referring to the MediaWiki namespace using the NS_MEDIAWIKI constant, but saw a reference that said that this constant would not work in non-english Wikis and so used the integer '8' instead.
  • I disabled emoticon replacement in most actions other than just viewing the page to keep things dynamic. If the replacement is done when editing a page the substitution will happen to the text in the textarea so that the replaced text will end up in the database. At that point if that emoticon is updated, since the original text was replaced, that page will not reflect the new emoticon.
  • I saw a suggestion made to a different programmer that instead of accessing the "m" fields that they use the associated getter and setter function. In several cases I am accessing the "m" fields as well, but this is only because I could not find a related getter or setter in the code documentation.
  • Since the values are trimmed before replacements are made, if you want to replace text ending with a forward slash ("/") or replace something with text beginning with a forward slash, all you need to do is put a space between the double forward slashes used as a separator and the forward slash in the search or replacement text. If you want to replace text ending with two double slashes replace something with text beginning with two double slashes, you need to come up with a different separator. Once you have figured out what you want to use, make sure you are using it in the MediaWiki:Emoticons file and replace the "//" in extensions/emoticons.php (in: "$currEmoticon = explode( "//", $emoticon, 2 );") with that separator as well.
  • This extension may be useful if you want to do other replacements as well, but be careful as it will replace any instance of the search text before other wiki formatting gets a chance to run, unless you wrap it in <nowiki> and </nowiki> tags (although only 10 of these are respected for load-time reasons). For instance, if you set up ":D" to be replaced with a smiley face and somewhere in the wiki someone wants to indent a line beginning with "D" like this ":Details of this transaction..." it will be rendered as a big smiley followed by "etails of this transaction..."