Buy
Buy

KnpMarkdownBundle & its Services

Scroll down to the "Why do Asteroids Taste like Bacon" article and click to see it. Here's the goal: I want the article body to be processed through markdown. Of course, Symfony doesn't come with a markdown-processing service... but there's probably a bundle that does! Google for KnpMarkdownBundle and find its GitHub page.

Installing a Bundle

Let's get this installed: copy the composer require line. Then, move over to your terminal, paste and... go!

composer require knplabs/knp-markdown-bundle

Notice that this is a bundle: you can see it right in the name. That means it likely contains two things: First, of course, some PHP classes. And second, some configuration that will add one or more new services to our app!

And.... installed! It executed one recipe, which made just one change:

git status

Yep! It updated bundles.php, which activates the bundle:

... lines 1 - 2
return [
... lines 4 - 10
Knp\Bundle\MarkdownBundle\KnpMarkdownBundle::class => ['all' => true],
];

Finding the new Service

So... what's different now? Run:

./bin/console debug:autowiring

and scroll to the top. Surprise! We have a new tool! Actually, there are two interfaces you can use to get the same markdown service. How do I know these will give us the same object? And which should we use? We'll talk about those two questions in the next chapter.

But since it doesn't matter, let's use MarkdownInterface. Open ArticleController. In show(), create a new variable - $articleContent - and set it to the multiline HEREDOC syntax. I'm going to paste in some fake content. This is the same beefy content that's in the template. In the controller, let's markdownify some stuff! Add some emphasis to jalapeno bacon ands let's turn beef ribs into a link to https://baconipsum.com/:

... lines 1 - 11
class ArticleController extends AbstractController
{
... lines 14 - 24
public function show($slug)
{
$comments = [
... lines 28 - 30
];
$articleContent = <<<EOF
Spicy **jalapeno bacon** ipsum dolor amet veniam shank in dolore. Ham hock nisi landjaeger cow,
lorem proident [beef ribs](https://baconipsum.com/) aute enim veniam ut cillum pork chuck picanha. Dolore reprehenderit
labore minim pork belly spare ribs cupim short loin in. Elit exercitation eiusmod dolore cow
turkey shank eu pork belly meatball non cupim.
Laboris beef ribs fatback fugiat eiusmod jowl kielbasa alcatra dolore velit ea ball tip. Pariatur
laboris sunt venison, et laborum dolore minim non meatball. Shankle eu flank aliqua shoulder,
capicola biltong frankfurter boudin cupim officia. Exercitation fugiat consectetur ham. Adipisicing
picanha shank et filet mignon pork belly ut ullamco. Irure velit turducken ground round doner incididunt
occaecat lorem meatball prosciutto quis strip steak.
Meatball adipisicing ribeye bacon strip steak eu. Consectetur ham hock pork hamburger enim strip steak
mollit quis officia meatloaf tri-tip swine. Cow ut reprehenderit, buffalo incididunt in filet mignon
strip steak pork belly aliquip capicola officia. Labore deserunt esse chicken lorem shoulder tail consectetur
cow est ribeye adipisicing. Pig hamburger pork belly enim. Do porchetta minim capicola irure pancetta chuck
fugiat.
EOF;
... lines 51 - 57
}
... lines 59 - 70
}

Pass this into the template as a new articleContent variable:

... lines 1 - 11
class ArticleController extends AbstractController
{
... lines 14 - 24
public function show($slug)
{
... lines 27 - 32
$articleContent = <<<EOF
Spicy **jalapeno bacon** ipsum dolor amet veniam shank in dolore. Ham hock nisi landjaeger cow,
lorem proident [beef ribs](https://baconipsum.com/) aute enim veniam ut cillum pork chuck picanha. Dolore reprehenderit
labore minim pork belly spare ribs cupim short loin in. Elit exercitation eiusmod dolore cow
turkey shank eu pork belly meatball non cupim.
Laboris beef ribs fatback fugiat eiusmod jowl kielbasa alcatra dolore velit ea ball tip. Pariatur
laboris sunt venison, et laborum dolore minim non meatball. Shankle eu flank aliqua shoulder,
capicola biltong frankfurter boudin cupim officia. Exercitation fugiat consectetur ham. Adipisicing
picanha shank et filet mignon pork belly ut ullamco. Irure velit turducken ground round doner incididunt
occaecat lorem meatball prosciutto quis strip steak.
Meatball adipisicing ribeye bacon strip steak eu. Consectetur ham hock pork hamburger enim strip steak
mollit quis officia meatloaf tri-tip swine. Cow ut reprehenderit, buffalo incididunt in filet mignon
strip steak pork belly aliquip capicola officia. Labore deserunt esse chicken lorem shoulder tail consectetur
cow est ribeye adipisicing. Pig hamburger pork belly enim. Do porchetta minim capicola irure pancetta chuck
fugiat.
EOF;
return $this->render('article/show.html.twig', [
... lines 53 - 55
'articleContent' => $articleContent,
]);
}
... lines 59 - 70
}

And now, in the template, remove all the old stuff and just print {{ articleContent }}:

... lines 1 - 4
{% block body %}
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="show-article-container p-3 mt-4">
... lines 11 - 25
<div class="row">
<div class="col-sm-12">
<div class="article-text">
{{ articleContent }}
</div>
</div>
</div>
... lines 33 - 71
</div>
</div>
</div>
</div>
{% endblock %}
... lines 78 - 83

Let's try it! Go back to our site and refresh! No surprise: it's the raw content. Now it's time to process this through Markdown!

Using the Markdown Service

In ArticleController, tell Symfony to pass us the markdown service by adding a type-hinted argument. Let's use MarkdownInterface: MarkdownInterface $markdown:

... lines 1 - 4
use Michelf\MarkdownInterface;
... lines 6 - 12
class ArticleController extends AbstractController
{
... lines 15 - 25
public function show($slug, MarkdownInterface $markdown)
{
... lines 28 - 60
}
... lines 62 - 73
}

Now, below, $articleContent = $markdown-> - we never looked at the documentation to see how to use the markdown service... but thanks to PhpStorm, it's pretty self-explanatory - $markdown->transform($articleContent):

... lines 1 - 4
use Michelf\MarkdownInterface;
... lines 6 - 12
class ArticleController extends AbstractController
{
... lines 15 - 25
public function show($slug, MarkdownInterface $markdown)
{
... lines 28 - 33
$articleContent = <<<EOF
... lines 35 - 50
EOF;
$articleContent = $markdown->transform($articleContent);
... lines 54 - 60
}
... lines 62 - 73
}

Un-escaping Raw HTML

And that's it! Refresh! It works! Um... kind of. It is transforming our markdown into HTML... but if you look at the HTML source, it's all being escaped! Bah!

Actually, this is awesome! One of Twig's super-powers - in addition to having very stylish hair - is to automatically escape any variable you render. That means you're protected from XSS attacks without doing anything.

If you do know that it's safe to print raw HTML, just add |raw:

... lines 1 - 4
{% block body %}
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="show-article-container p-3 mt-4">
... lines 11 - 25
<div class="row">
<div class="col-sm-12">
<div class="article-text">
{{ articleContent|raw }}
</div>
</div>
</div>
... lines 33 - 71
</div>
</div>
</div>
</div>
{% endblock %}
... lines 78 - 83

Try it again! Beautiful!

So here is our first big lesson:

  1. Everything in Symfony is done by a service
  2. Bundles give us these services... and installing new bundles gives us more services.

And 3, Twig clearly gets its hair done by a professional.

Next, let's use a service that's already being added to our app by an existing bundle: the cache service.

Leave a comment!

  • 2018-09-28 Abelardo León González

    Thanks for your tips!

    Brs.

  • 2018-09-28 Victor Bocharsky

    Hey Abelardo,

    Thanks for sharing it with others, though I'm a bit lost in your problem :) But there're a few quick ideas:

    First of all, we do not allow to paste images in DIsqus comments, that's our Disqus configuration, so if you want to share a screenshot - upload it to any image storage like imgur.com and paste a link to it in a comment.

    You also can wrap your code with pre and then code tags to tell Disqus that the text should be highlighted instead of rendered.

    And br tag is needed when you want to render a new line in browser, because \ n is used to make a new line in source code only and browsers do not consider it.

    Cheers!

  • 2018-09-28 Abelardo León González

    I pasted the whole text which appears inside the video and the following are the conclusions:
    1) You can't put " and start in the following line; the text should be started in the first line, after the "
    2) To create a new line, you should put " < b r > " and not " \ n ". If you don't put them, a new line won't be created.
    3) Don't forget to end with ".

  • 2018-09-28 Abelardo León González

    I wrote this line:

    $articleContent = " **negrita** [enlace](https://baconipsum.com/) ";

    and...IT WORKS!

    Note that "<<<eof...eof;" doesn't="" exist.="" ;)="">

  • 2018-09-28 Abelardo León González

    I dumped this information:

    array:5 [▼
    "title" => "Why Asteroids Taste Like Bacon"
    "articleContent" => """

        **negrita** [enlace](https://baconipsum.com/)\n

    \n
    """
    "slug" => "why-asteroids-taste-like-bacon"
    "comments" => array:3 [▶]
    "app" => AppVariable {#201 ▶}

    The 'articleContent''s content is surrounded by "< p r e >" and "< c o d e >" tags.

  • 2018-09-28 Abelardo León González

    Hi everyone,

    I have an issue with the Michelf\MarkdownInterface service.

    I have written a dummy text in order to test it: **negrita** [enlace] (...) but it doesn't work.

    What's wrong?

    I don't why Disqus doesn't allow me paste pictures. ¿?

    Best regards,

    Abelardo.

  • 2018-08-15 Diego Aguiar

    Probably you missed it because PHPStorm adds imports automatically :)

  • 2018-08-14 C Alongi

    No but it seems quite important lol. For being a literal make or break line if code he sure does gloss over it!

  • 2018-08-13 Diego Aguiar

    Hey C Alongi

    Did you import the service in your controller?


    // someController.php

    use Michelf\MarkdownInterface;

    ...

    Cheers!

  • 2018-08-13 C Alongi

    I watched this video twice and looked at my code very carefully but I still get this error. Cannot determine controller argument for "App\Controller\ArticleController::show()": the $markdown argument is type-hinted with the non-existent class or interface: "App\Controller\MarkdownInterface". Did you forget to add a use statement?

  • 2018-06-13 Diego Aguiar

    Hey Jacob Nijgh

    If you install a non-symfony library, then you can't just type-hint any of its classes and expect it to automatically works. You have a couple of choices:

    - Implement a factory service which will be reponsible of instantiating and returning any of the library's classes.

    - Implement your own dependency injection extension, this topic is a bit more advance, but you can find good examples from any common Symfony bundle (just look inside "src/DependencyInjection" folder), or you can watch our tutorial about creating your own Symfony bundle.
    Docs: https://symfony.com/doc/cur...
    Tutorial: https://knpuniversity.com/s...

    Cheers!

  • 2018-06-12 Jacob Nijgh

    Hi Ryan,

    Does this mean that we always need bundles to use services, or is it also possible for instance to pull in a package from composer and setup the service in the services.yml file for example to use it as type-hinted classes in methods. If so how can this be done and is this a best practice?

  • 2018-06-06 toporovvv

    Packagist is for all the php-packages. You also could search bundles special for Symfony at http://knpbundles.com/

  • 2018-04-19 Petru Lebada

    Hey weaverryan ,

    It seem like it was exactly what you said.I've deleted the content and simply wrote a few lines by hand, with the same markups and it rendered it just fine.... Thank a lot.

  • 2018-04-18 Petru Lebada

    Sure thing: https://ibb.co/c36A47

  • 2018-04-18 weaverryan

    Hey Petru Lebada!

    It all looks fine to me. Except... *maybe* for one minor thing. It may have just been caused by how the code pasted into the comment (I looked at the source of the code you posted), but it looks like the $articleContent text is indented. Here's what I'm talking about: https://gist.github.com/wea...

    IF this is true, then when the content is parsed through markdown, I think that markdown may think (due to the indentation) that this is some "literal" content, or possibly a blockquote. And so that may be causing the odd parsing. If I'm incorrect and your code is NOT indented, could you post a screenshot of the page with the raw content?

    Cheers!

  • 2018-04-18 Petru Lebada

    {% extends 'base.html.twig' %}

    {% block title %}Read{% endblock %}

    {% block body %}


    <div class="container">
    <div class="row">
    <div class="col-sm-12">
    <div class="show-article-container p-3 mt-4">
    <div class="row">
    <div class="col-sm-12">
    <img class="show-article-img" src="{{ asset('images/asteroid.jpeg') }}">
    <div class="show-article-title-container d-inline-block pl-3 align-middle">
    {{ title }}


    <img class="article-author-img rounded-circle" src="{{ asset('images/alien-profile.png') }}"> Mike Ferengi
    4 hours ago

    5

    </div>
    </div>
    </div>
    <div class="row">
    <div class="col-sm-12">
    <div class="article-text">
    {{ articleContent|raw }}
    </div>
    </div>
    </div>
    <div class="row">
    <div class="col-sm-12">

    Share:


    </div>
    </div>
    <div class="row">
    <div class="col-sm-12">
    <h3>{{ comments|length }} Comments</h3>
    <hr>

    <div class="row mb-5">
    <div class="col-sm-12">
    <img class="comment-img rounded-circle" src="{{ asset('images/astronaut-profile.png') }}">
    <div class="comment-container d-inline-block pl-3 align-top">
    Amy Oort
    <div class="form-group">
    <textarea class="form-control comment-form" id="articleText" rows="1"></textarea>
    </div>
    <button type="submit" class="btn btn-info">Comment</button>
    </div>
    </div>
    </div>

    {% for comment in comments %}

    <div class="row">
    <div class="col-sm-12">
    <img class="comment-img rounded-circle" src="{{ asset('images/alien-profile.png') }}">
    <div class="comment-container d-inline-block pl-3 align-top">
    Mike Ferengi


    {{ comment }}

    Reply


    </div>
    </div>
    </div>

    {% endfor %}

    </div>
    </div>
    </div>
    </div>
    </div>
    </div>




    {% endblock %}

    {% block javascripts %}
    {{ parent() }}

    <script src="{{ asset('js/article_show.js') }}"></script>
    {% endblock %}
  • 2018-04-18 Petru Lebada

    namespace App\Controller;


    use App\Service\MarkdownHelper;
    use Psr\Log\LoggerInterface;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\HttpFoundation\Response;

    class ArticleController extends AbstractController
    {


    private $isDebug;

    public function __construct(bool $isDebug)
    {


    $this->isDebug = $isDebug;

    }

    /**
    * @Route("/", name="app_homepage")
    */
    public function homepage()
    {

    return $this->render('article/homepage.html.twig');

    }

    /**
    * @Route("/news/{slug}", name="article_show")
    */
    public function show($slug, MarkdownHelper $markdownHelper)
    {

    $articleContent = <<<eof spicy="" **jalapeno="" bacon**="" **ipsum**="" dolor="" amet="" veniam="" shank="" in="" dolore.="" ham="" hock="" nisi="" landjaeger="" cow,="" lorem="" proident="" [beef="" ribs](https:="" baconipsum.com="" )="" aute="" enim="" veniam="" ut="" cillum="" pork="" chuck="" picanha.="" dolore="" reprehenderit="" labore="" minim="" pork="" belly="" spare="" ribs="" cupim="" short="" loin="" in.="" elit="" exercitation="" eiusmod="" dolore="" cow="" turkey="" shank="" eu="" pork="" belly="" meatball="" non="" cupim.="" laboris="" beef="" ribs="" fatback="" fugiat="" eiusmod="" jowl="" kielbasa="" alcatra="" dolore="" velit="" ea="" ball="" tip.="" pariatur="" laboris="" sunt="" venison,="" et="" laborum="" dolore="" minim="" non="" meatball.="" shankle="" eu="" flank="" aliqua="" shoulder,="" capicola="" biltong="" frankfurter="" boudin="" cupim="" officia.="" exercitation="" fugiat="" consectetur="" ham.="" adipisicing="" picanha="" shank="" et="" filet="" mignon="" pork="" belly="" ut="" ullamco.="" irure="" velit="" turducken="" ground="" round="" doner="" incididunt="" occaecat="" lorem="" meatball="" prosciutto="" quis="" strip="" steak.="" meatball="" adipisicing="" ribeye="" bacon="" strip="" steak="" eu.="" consectetur="" ham="" hock="" pork="" hamburger="" enim="" strip="" steak="" mollit="" quis="" officia="" meatloaf="" tri-tip="" swine.="" cow="" ut="" reprehenderit,="" buffalo="" incididunt="" in="" filet="" mignon="" strip="" steak="" pork="" belly="" aliquip="" capicola="" officia.="" labore="" deserunt="" esse="" chicken="" lorem="" shoulder="" tail="" consectetur="" cow="" est="" ribeye="" adipisicing.="" pig="" hamburger="" pork="" belly="" enim.="" do="" porchetta="" minim="" capicola="" irure="" pancetta="" chuck="" fugiat.="" eof;="" $comments="[" 'i="" ate="" a="" normal="" rock="" once.="" it="" did="" not="" taste="" like="" bacon!',="" 'woohoo!="" i\'m="" going="" on="" an="" all-asteroid="" diet!',="" 'i="" like="" bacon="" too!="" buy="" some="" from="" my="" site!="" bakinsomebacon.com',="" ];="" $articlecontent="$markdownHelper-">parse(
    $articleContent
    );

    return $this->render('article/show.html.twig', [
    'title' => ucwords(str_replace('-', ' ', $slug)),
    'articleContent' => $articleContent,
    'slug' => $slug,
    'comments' => $comments,
    ]);

    }


    /**
    * @Route("/news/{slug}/heart", name="article_toggle_heart", methods={"POST"})
    */
    public function toggleArticleHeart($slug, LoggerInterface $logger)
    {
    // TODO -actually heart/unheart the article!

    $logger->info('Article is being hearted');

    return new JsonResponse(['hearts' => rand(5, 100)]);
    }
    }
  • 2018-04-18 weaverryan

    Hey Petru Lebada!

    Ah, yea, super weird! I'm sure it's something really subtle - like cache as Diego suggested. Ok, let's do this so we can debug: can you post your code: specifically your controller and Twig template. That might help us spot any issues :).

    Cheers!

  • 2018-04-18 Petru Lebada

    Max {#242 ▼
    #features: array:19 [▼
    "header" => true
    "list" => true
    "horizontal_rule" => true
    "table" => true
    "foot_note" => true
    "fenced_code_block" => true
    "abbreviation" => true
    "definition_list" => true
    "inline_link" => true
    "reference_link" => true
    "shortcut_link" => true
    "images" => true
    "block_quote" => true
    "code_block" => true
    "html_block" => true
    "auto_link" => true
    "auto_mailto" => true
    "entities" => true
    "no_html" => false
    ]
    +fn_id_prefix: ""
    +fn_link_title: ""
    +fn_backlink_title: ""
    +fn_link_class: "footnote-ref"
    +fn_backlink_class: "footnote-backref"
    +fn_backlink_html: "↩︎"
    +table_align_class_tmpl: ""
    +code_class_prefix: ""
    +code_attr_on_pre: false
    +predef_abbr: []
    +hashtag_protection: false
    #footnotes: []
    #footnotes_ordered: []
    #footnotes_ref_count: []
    #footnotes_numbers: []
    #abbr_desciptions: []
    #abbr_word_re: ""
    #footnote_counter: 1
    #id_class_attr_catch_re: "\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}"
    #id_class_attr_nocatch_re: "\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}"
    #block_tags_re: "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure"
    #context_block_tags_re: "script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video"
    #contain_span_tags_re: "p|h[1-6]|li|dd|dt|td|th|legend|address"
    #clean_tags_re: "script|style|math|svg"
    #auto_close_tags_re: "hr|img|param|source|track"
    #em_relist: array:3 [▶]
    #strong_relist: array:3 [▶]
    #em_strong_relist: array:3 [▶]
    +empty_element_suffix: " />"
    +tab_width: 4
    +no_markup: false
    +no_entities: false
    +hard_wrap: false
    +predef_urls: []
    +predef_titles: []
    +url_filter_func: null
    +header_id_func: null
    +code_block_content_func: null
    +code_span_content_func: null
    +enhanced_ordered_list: true
    #nested_brackets_depth: 6
    #nested_brackets_re: "(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[\])*\])*\])*\])*\])*\])*"
    #nested_url_parenthesis_depth: 4
    #nested_url_parenthesis_re: "(?>[^()\s]+|\((?>[^()\s]+|\((?>[^()\s]+|\((?>[^()\s]+|\((?>\)))*(?>\)))*(?>\)))*(?>\)))*"
    #escape_chars: "\`*_{}[]()>#+-.!:|"
    #escape_chars_re: "[\\`\*_\{\}\[\]\(\)\>#\+\-\.\!\:\|]"
    #urls: []
    #titles: []
    #html_hashes: []
    #in_anchor: false
    #in_emphasis_processing: false
    #document_gamut: array:6 [▶]
    #block_gamut: array:8 [▶]
    #span_gamut: array:9 [▶]
    #list_level: 0
    #em_strong_prepared_relist: array:9 [▶]
    #utf8_strlen: "mb_strlen"
    }

  • 2018-04-17 Diego Aguiar

    Hmm, even weirder :p
    Can you dump the markdown object just to be sure that you are getting passed the right parser?

  • 2018-04-17 Petru Lebada

    Uhm, the content is exactly the one from the video , containing *** and the link markdown.Now i do have a cache, the symfony default cache service, because im further wit hthe videos,but at that time i didnt.Anyway, i did cache:clear just in case and still no result.

  • 2018-04-16 Diego Aguiar

    Hey Petru Lebada

    That's weird, are you using some sort of cache? Or probably your content does not contain any MD tags?

  • 2018-04-16 Petru Lebada

    Hey Ryan,

    Got a problem with transform() method from Michelf's class MarkdownInterface ... it returns the plain text.I did a bit of debugging to check if it reaches the method(which it does) but further debugging will take a while and since this service isn't so important to me maybe you have seen this problem before and can suggest a quick resolve? Thank you

  • 2018-03-21 Tess Hsu

    Hi weaverryan,

    greate yes your anwsers are all my questions, cheers

  • 2018-03-20 weaverryan

    Hey Tess Hsu!

    Great questions :). First, to find bundles, yea... it seems simple, but I mostly use Google or search GitHub as you mentioned :). It's easy to find bundle (e.g. "Symfony markdown bundle"). The more important part is to judge whether the bundle you've found is "decent". The most important things to look at are the number of stars on GitHub & also the date of the last commit (to make sure it's not abandoned). You can also search on packagist and see how many downloads a package has. It's not an exact science. Oh, and you can also filter packagist to show you only bundles - https://packagist.org/?q=&p... (the "symfony-bundle" type on the right is selected).

    > so it is means every bundles, service has theiry own definition class method which means need to read every doc?
    Or once installed, the phpStorm will auto-writing hit method for us?

    I don't think I understand this question - can you ask again? What do you mean by "definition class method"? Are you wondering how you know which method (like transform) that you can call on each service? Or are you wondering how you know which type-hint (like MarkdownInterface) you should use? If you're wondering about the method (like transform), then yep! PhpStorm auto-completes that. As soon as you type-hint the argument (like MarkdownInterface), PhpStorm will very confidently auto-complete all methods available.

    Cheers!

  • 2018-03-19 Tess Hsu

    hi knp team,

    just courious, how could I find out those bundles? all through github?
    https://github.com/search?u...

    so it is means every bundles, service has theiry own definition class method which means need to read every doc?
    Or once installed, the phpStorm will auto-writing hit method for us?

    thank you

  • 2018-02-19 Diego Aguiar

    Hey AdFlorin

    Nice to see you again :)
    You can use a serializer third party library like "jms/serializer-bundle", you can watch Ryan using it in this chapter
    https://knpuniversity.com/s...
    and if you want to see more, you can check this other chapter for advanced usage of it
    https://knpuniversity.com/s...

    If you want to learn more about Doctrine, we have a couple of courses about it (but we use Symfony3):
    https://knpuniversity.com/s...
    https://knpuniversity.com/s...

  • 2018-02-19 AdFlorin

    how do i do that :) ? you don't have complex tutorials with doctrine :(

  • 2018-01-25 Diego Aguiar

    Hey AdFlorin

    Well, you can't just pass an object to the transformer, you have to serialize it first, or code a function that create a summary of that object.

    Cheers!

  • 2018-01-25 AdFlorin

    how do i transform this ?

    /**
    * @Route("/advert/{slug}", name="show_advert")
    */
    public function show($slug, MarkdownInterface $mk)
    {
    $adv = $this->getDoctrine()
    ->getRepository(Advert::class)
    ->findOneBy(array('slug' => $slug));

    $MDadv = $mk->transform($adv);

    return $this->render('advert/show.html.twig', [
    'adv' => $MDadv,
    ]);
    }

    obviously i get Catchable Fatal Error: Object of class App\Entity\Advert could not be converted to string ...