jbowens / jBBCode

A lightweight but extensible BBCode parser
http://jbbcode.com
MIT License
164 stars 32 forks source link

Support for CodeDefinition aliasing #17

Closed Art4 closed 9 years ago

Art4 commented 10 years ago

Hi,

I have created a class Definition_Video extending CodeDefinition to support the [video] tag. The Definition_Video parse urls from vimeo.com, dailymotion.com and youtube.com.

Now I want support the [youtube] tag for BC and I created the Definition_Youtube class:

class Definition_Youtube extends Definition_Video
{

    public function __construct()
    {
        parent::__construct();

        $this->setTagName('youtube');
    }

}

and add the classes to the parser.

$parser->addCodeDefinition(new Definition_Video());
$parser->addCodeDefinition(new Definition_Youtube());

This works fine for me, but I have a lot more tag aliases and have to create a lot of classes. I wish to do something like this:

$definition = new Definition_Video();
$defintion->addAliasTagName('youtube');

$parser->addCodeDefinition($definiton);

I have also seen the deprecated CodeDefinition::setTagName() method, that allows easy aliasing as well:

$definition = new Definition_Video();
$parser->addCodeDefinition($definiton);

$defintion->setTagName('youtube');
$parser->addCodeDefinition($definiton);

Is there a reason why CodeDefinition::setTagName() method is marked as deprecated? Or is it possible to add an aliasing funtionality?

jbowens commented 9 years ago

CodeDefinition::setTagName() was deprecated in a shift to make CodeDefinition objects immutable. They should be constructed through a CodeDefinitionBuilder and then never modified. There's no way to achieve aliasing currently, but I'll look into how it might be added.

Dijky commented 9 years ago

You could easily add the tag name property as a constructor parameter for your CodeDefinition class:

class Definition_Video extends JBBCode\CodeDefinition
{
  public function __construct($tagName = 'video')
  {
    parent::__construct();
    $this->setTagName($tagName);
  }
}

Now just create two instances of Definition_Video with different tag names:

$parser->addCodeDefinition(new Definition_Video());
$parser->addCodeDefinition(new Definition_Video('youtube'));

I didn't test this, but it should work fine.

CodeDefinition::setTagName() was misleading here, because it changed the tag name of the same CodeDefinition instance. Hence, it changed the tag name, not returned a new instance with a different tag name.
It is cleaner to define the tag name once per instance in the constructor, so that each instance is immutable after construction.