1

I've been following the Documentation on creating custom form types given in the docs: http://symfony.com/doc/master/cookbook/form/create_custom_field_type.html#using-the-field-type

Having the GenderType from the given example, i'd like to "pimp" my entity, which i'm working on with the new FormType.

class Person {

    const GENDER_MALE = "m";
    const GENDER_FEMALE = "f";

    private $gender;

    ....
    /* generated getter/setter  */

    .....

    public function getGenderAsText() 
    {
          return $this->getGender() == self::GENDER_MALE?"male":"female";
    }


} 

My question, maybe has anyone a a good advise.. .how to combine the elegance of the GenderType which handels choice picking the form like a charm with my model, so ease usage in templates etc.. ?

Update

Alex pointed out, how to display a specific field with a self-written gender twig extension.

This works like a charm, when you especially call the extension on the field {{ item.gender|gender }}

I'm having a bunch of objects, using inheritance for the common fields - but there's a bunch of data which are unique for each class. I've written some logic to extract all properties, hand 'em over to the template and a TwigExtension handles rendering:

public function dynamicContractFilter($value)
{
    // handle DateTime
    if ($value instanceof \DateTime) {
        return $value->format('d.m.Y');
    }
    ....
    } elseif (is_bool($value)) {
        return $value ? 'yes' : 'no';
    } else {
        return $value;  // plain string
    }

}

I can't determine if it's a simple string/integer or a "GenderTypedField"..

I guess this is some kind of limitation of PHP itself, as it's typeless.. sight

2
  • 1
    You can make the framework to return a Gender object by creating data transformer for the gender data type. Read about data transformers here – symfony.com/doc/master/cookbook/form/data_transformers.html. Commented Oct 22, 2012 at 7:56
  • Thanks for this hint, going to dig deeper into this issue Commented Oct 24, 2012 at 16:12

1 Answer 1

1

The best approach would be to write a gender twig extension.

That way you could display m as Male and f as Female anywhere, not only in the Person entity. It also provides clear separation between your data and your display code.

Like so:

namespace Acme\DemoBundle\Twig;

class GenderExtension extends \Twig_Extension
{
    const
        MALE   = 'Male',
        FEMALE = 'Female';

    public function getFilters()
    {
        return array(
            'gender' => new \Twig_Filter_Method($this, 'gender'),
        );
    }

    public function gender($token)
    {
        if ('m' === $token)
            return self::MALE;

        if ('f' === $token)
            return self::FEMALE;

        throw new \InvalidArgumentException('Invalid argument, expecting either "m" or "f".');
    }

    public function getName()
    {
        return 'acme_gender_extension';
    }
}

You would then have in your template:

{{ person.gender | gender }}
Sign up to request clarification or add additional context in comments.

3 Comments

Hi Alex, thanks for your detailed response. I've added more information to the initial question, as i'm using it in a more generic way and not accessing the {{ person.gender | gender }} field explicitly atm.
My example isn't just useful for person.gender, any string with m or f could be passed through the gender filter, like so: {{ 'm' | gender }}. That said, if your filter has to do more than just parse a gender, rename it to some generic name and make your twig extension do all the magic (including checking if its a DateTime object, a boolean or otherwise).
You're right, with a defined set of constants like {{ 'dynamicvalue_m' | dynamicTwigExtension }} i could handle lots of dynamic fields i'm rendering in the templates

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.