Welcome! » Log In » Create A New Profile

Set target="_blank" on all links

Posted by Emmett 
Set target="_blank" on all links
January 17, 2008 12:23AM

People have been requesting that all their links target off the page; I'd like to set target="_blank" for them on all links. I presume there's an easy way to do this with HTML Purifier, but I can't quite figure it out.

Thanks, Emmett

Re: Set target="_blank" on all links
January 17, 2008 12:29AM

Oops. Immediately after posting this, I realized there's a solution that should work...I think...as soon as I figure out how to do $def->getElement('a'), which doesn't actually exist.

$config = HTMLPurifier_Config::createDefault();
$config->set('AutoFormat', 'Custom', array('AddParam'));
//a modification of my existing script to allow flash in purified html...
//flash specific code snipped...
$config->set('HTML', 'DefinitionID', 'allow flash movies'); 
$config->set('HTML', 'DefinitionRev', 1);
$config->set('Core', 'DefinitionCache', null); 
$def =& $config->getHTMLDefinition(true);

class HTMLPurifier_AttrTransform_AValidator extends HTMLPurifier_AttrTransform
{
	var $name = 'Link validation';
	
	function transform($attr, $config, &$context) {
		$attr['target'] = '_blank';
		return $attr;
	}
}
$a =& $def->getElement('a');
$a->attr_transform_post[] = new HTMLPurifier_AttrTransform_AValidator();

$purifier = new HTMLPurifier();
$clean_html = $purifier->purify($_SERVER['argv'][1], $config);

Alternatively, I tried:

$def->addAttribute('a', 'target', 'Enum#_blank');

But while that compiles and runs, it doesn't seem to do anything.

Re: Set target="_blank" on all links
January 17, 2008 05:07PM

You need to create a blank element and then add that in. Something like...

$a =& $def->addBlankElement();
$a->attr_transform_post[] = new HTMLPurifier_AttrTransform_AValidator();

P.S. If you ended up doing some searching, please don't use http://htmlpurifier.org/phorum/read.php?3,660,660#msg-661 — while it works, it's outdated.

Re: Set target="_blank" on all links
January 17, 2008 05:22PM

Nevermind, reading the post you linked to makes that obvious.

=== What's $this? Does $this == $def?

Thanks for your help, Emmett

Re: Set target="_blank" on all links
January 17, 2008 05:23PM

Yes. (Whoops, I did it again--post edited accordingly).

Re: Set target="_blank" on all links
January 17, 2008 05:45PM
Fatal error: Call to undefined method: htmlpurifier_htmldefinition->addblankelement() 
in /Users/eshear/code/jtv2/script/sanitize.php on line 33

Line 33:

$a =& $def->addBlankElement('a');

Looking up addBlankElement in the documentation (and my codebase) it looks like it belongs to HtmlPurifier_HtmlModule...

Sorry, I just don't really know PHP very well, so it's hard for me to track down what's going wrong.

Re: Set target="_blank" on all links
January 17, 2008 05:46PM

What version of HTML Purifier are you using?

Re: Set target="_blank" on all links
January 17, 2008 05:48PM

Version 2.1.2

Re: Set target="_blank" on all links
January 17, 2008 05:49PM

The method I'm referring to was added in 2.1.3. Upgrade! (Preferably to 3.0.0, but it looks like you're still on PHP4).

Re: Set target="_blank" on all links
January 17, 2008 05:52PM

OK, I can upgrade. Will the rest of my script be backwards compatible?

	require_once 'lib/htmlpurifier-2.1.2/library/HTMLPurifier.auto.php';
	require_once 'lib/htmlpurifier-2.1.2/library/HTMLPurifier/AttrTransform.php';
	
	$config = HTMLPurifier_Config::createDefault();
	$config->set('AutoFormat', 'Custom', array('AddParam'));
	$config->set('HTML', 'DefinitionID', 'allow flash movies');
	$config->set('HTML', 'DefinitionRev', 1);
	$config->set('Core', 'DefinitionCache', null); //remove this later
	$def =& $config->getHTMLDefinition(true);
	
	$param =& $def->addElement(
		'param',
		false, //only appears in object tags, remove elsewhere
		'Empty',
		false,
		array(
			'name' => 'Text', 
			'value' => 'Text'
		)
	);
	
	class HTMLPurifier_AttrTransform_AValidator extends HTMLPurifier_AttrTransform
	{
		var $name = "Link validation";
		
		function transform($attr, $config, &$context) {
			$attr['target'] = '_blank';
			return $attr;
		}
	}
	$a =& $def->addBlankElement('a');
	$a->attr_transform_post[] = new HTMLPurifier_AttrTransform_AValidator();
	//$def->addAttribute('a', 'target', 'Enum#_blank');
	
	class HTMLPurifier_AttrTransform_ParamValidator extends HTMLPurifier_AttrTransform 
	{
		var $name = "Paramter validation";
		var $uri;
		
		function HTMLPurifier_AttrTransform_ParamValidator() {
	        $this->uri = new HTMLPurifier_AttrDef_URI();
	    }
		
		function transform($attr, $config, &$context) {
		        switch (strtolower($attr['name'])) {
		            case 'allowscriptaccess':
		                $attr['value'] = 'never';
		                break;
					case 'allownetworking':
						$attr['value'] = 'internal';
						break;
		            case 'wmode':
						if ($attr['value'] != 'window' && $attr['value'] != 'transparent') {
		                	$attr['value'] = 'window';
						}
		                break;
					case 'enablehref':
						$attr['value'] = 'false';
						break;
		            case 'enablejsurls':
		                $attr['value'] = 'false';
		                break;
		            case 'movie':
		                $attr['value'] = $this->uri->validate($attr['value'], $config, $context);
		                break;
					case 'flashvars':
						break;
					case 'allowfullscreen':
						$attr['value'] = 'true';
						break;
		            // probably more
		            default:
						$attr['value'] = "removed";
		        }
		        return $attr;
		    }
	}
	$param->attr_transform_post[] = new HTMLPurifier_AttrTransform_ParamValidator();
	
	$object =& $def->addElement(
		'object',
		'Inline',
		'Optional: param | embed | #PCDATA',
		false,
		array(
			'type' => 'Enum#application/x-shockwave-flash',
			'width*' => 'Pixels',
			'height*' => 'Pixels',
			'data'	=> 'Text'
		)
	);
	
	class HTMLPurifier_AttrTransform_ObjectValidator extends HTMLPurifier_AttrTransform
	{
	    var $name = "ObjectValidator";

	    function transform($attr, $config, &$context) {
	        #if (!isset($attr['type'])) $attr['type'] = 'application/x-shockwave-flash';
	        return $attr;
	    }
	}
	$object->attr_transform_post[] = new HTMLPurifier_AttrTransform_ObjectValidator();
	
	$embed =& $def->addElement(
		'embed',
		'Block',
		'Empty',
		false,
		array(
			'type*' => 'Enum#application/x-shockwave-flash',
			'width*' => 'Pixels',
			'height*' => 'Pixels',
			'src*' => 'URI',
			'flashvars' => 'Text',
			'allowscriptaccess' => 'Enum#never',
			'allownetworking' => 'Enum#internal',
			'enablejsurls' => 'Enum#false',
			'enablehref' => 'Enum#false',
			'bgcolor' => 'Text',
			//these will all be ignored by the injector
			'wmode' => 'Text',
			'pluginspage' => 'URI',
			'saveembedtags' => 'Text',
			'salign' => 'Text',
			'scale' => 'Text',
			'name' => 'Text'
		)
	);

	class HTMLPurifier_AttrTransform_EmbedValidator extends HTMLPurifier_AttrTransform 
	{
		var $name = "Embed validation";
	
		function transform($attr, $config, &$context) {
			$attr['allowscriptaccess'] = 'never';
			$attr['allownetworking'] = 'internal';
			$attr['enablejsurls'] = 'false';
			$attr['enablehref'] = 'false';
			return $attr;
		}
	}
	$embed->attr_transform_post[] = new HTMLPurifier_AttrTransform_EmbedValidator();


	class HTMLPurifier_Injector_AddParam extends HTMLPurifier_Injector
	{
	    var $name = 'AddParam';
	    var $needed  = array('object', 'param');
	    function handleElement(&$token) {
	        if ($token->name == 'object') {
	            $token = array(
	                $token,
	                new HTMLPurifier_Token_Start('param', array('name' => 'enablejsurls', 'value' => 'false')),
					new HTMLPurifier_Token_Start('param', array('name' => 'enablehref', 'value' => 'false')),
					new HTMLPurifier_Token_Start('param', array('name' => 'allownetworking', 'value' => 'internal')),
					new HTMLPurifier_Token_Start('param', array('name' => 'allowscriptaccess', 'value' => 'never'))
	            );
	        }
	    }
	}
			
	$purifier = new HTMLPurifier();
	$clean_html = $purifier->purify($_SERVER['argv'][1], $config);
	echo $clean_html . "\n";
Re: Set target="_blank" on all links
January 17, 2008 06:47PM

Only a few slight compatibility changes are necessary if you upgrade to PHP 5: replace all &$context parameter definitions to $context. This should not be done if you upgrade to 2.1.3. Everything else should still be compatible.

Re: Set target="_blank" on all links
January 17, 2008 06:51PM

Great, thanks. I'll upgrade to PHP5.0 whenever I get a chance.

Author:
Your Email:

Subject:

HTML input is enabled. Make sure you escape all HTML and angled brackets with < and >.

Auto-paragraphing is enabled. Double newlines will be converted to paragraphs; for single newlines, use the pre tag.

Allowed tags: a, abbr, acronym, b, blockquote, caption, cite, code, dd, del, dfn, div, dl, dt, em, i, ins, kbd, li, ol, p, pre, s, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, var.

For inputting literal code such as HTML and PHP for display, use CDATA tags to auto-escape your angled brackets, and pre to preserve newlines:

<pre><![CDATA[
Place code here
]]></pre>

Power users, you can hide this notice with:

.htmlpurifier-help {display:none;}

Message: