Question

New to Symfony2, can someone give me some advice on how to setup tags for a blog site? I've setup tags as it's own entity and will relate tags to the blog entity via ManyToMany relation.

My question is how would I set this up in twig?

In other words, I have a form to entering a new blog, do I setup a new form for just entering tags? Or is there a way to combine entering tags with the blog creation form?

Was it helpful?

Solution

Tags are just a list of unique strings.

Front : I use Select2, there is a really good tag feature : http://ivaynberg.github.io/select2/. It will take/return a string to the server with each "tag" separated by a comma : tag1,tag2,tag3. You can also configure a web-service to research existing tags.

Back : I create a DataTransformer (http://symfony.com/doc/current/cookbook/form/data_transformers.html) as a service and i inject the entity manager in it :

class TagsTransformer implements DataTransformerInterface
{
    private $em;

    /**
     * @param EntityManager $em
     */
    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function transform($value)
    {
        if (null === $value) {
            return '';
        }

        if ($value instanceof Collection) {
            return implode(',', array_map(function (Tag $tag) {
                return (string)$tag;
            }, $value->toArray()));
        }

        return $value;
    }

    public function reverseTransform($value)
    {
        if (empty($value)) {
            return null;
        }

        if (is_string($value)) {
            $values = explode(',', $value);
            foreach ($values as &$value) {
                // Find or create it (create the method)
                $value = $this->em->getRepository('MySuperBundle:Tag')->findOrCreate(trim($value));
            }
            unset($value);

            return $values;
        }

        return $value;
    }
}

The goal of this transformer is to :

  • Transform : take the ArrayCollection of Tags entity from Doctrine, and convert it as a simple comma separated string
  • Reverse : take a simple comma separated string and convert it as an array of unique Tag entity

We then create a Form for tags (again, as a service, with the data transformer in it) :

class TagsType extends AbstractType
{
    private $tagsTransformer;

    /**
     * @param TagsTransformer $tagsTransformer
     */
    public function __construct(TagsTransformer $tagsTransformer)
    {
        $this->tagsTransformer = $tagsTransformer;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addModelTransformer($this->tagsTransformer);
    }

    public function getParent()
    {
        return 'text';
    }
}

Finally, in your form (blog post form for example), you'll have to use your TagsType new "field".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top