Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RTM] Draft of Contao controllers #1376

Merged
merged 14 commits into from
Jun 11, 2018

Conversation

aschempp
Copy link
Member

@aschempp aschempp commented Feb 18, 2018

Abstract controllers that implement the same features as the abstract ContentElement and Module classes did.

@leofeyer leofeyer requested a review from Toflar February 18, 2018 21:42
@leofeyer leofeyer changed the base branch from 4.5 to master February 20, 2018 14:11
@leofeyer leofeyer changed the base branch from master to 4.5 February 20, 2018 14:11
@leofeyer leofeyer added this to the 4.6.0 milestone Feb 20, 2018
@leofeyer
Copy link
Member

The PR should be targeted against the master branch.

@leofeyer leofeyer changed the base branch from 4.5 to master February 21, 2018 08:30
@leofeyer leofeyer changed the title Draft of Contao controllers [WIP] Draft of Contao controllers Feb 21, 2018
@leofeyer leofeyer removed this from the 4.6.0 milestone Feb 21, 2018
@aschempp aschempp force-pushed the feature/abstract-controller branch from 6bf2b11 to f3d6796 Compare April 9, 2018 11:58
@aschempp
Copy link
Member Author

aschempp commented Apr 9, 2018

I have just updated this PR to make our fragments actually useful. The problem of inline fragment renderer is that it creates a subrequest without any of the current request information. It create a GET request even if the master request is POST, respectively drops POST parameters and much more.

Our fragments work different than the Symfony core, that's why it makes sense to inherit the master request in our case. It is still very much possible to keep the existing behavior by simply overriding the renderer in the tag configuration.

@Toflar
Copy link
Member

Toflar commented Apr 9, 2018

Our fragments work different than the Symfony core, that's why it makes sense to inherit the master request in our case. It is still very much possible to keep the existing behavior by simply overriding the renderer in the tag configuration.

That's correct. Reviewed and concept approved. But tests need to be fixed 😄

@aschempp aschempp changed the title [WIP] Draft of Contao controllers [RFC] Draft of Contao controllers Apr 10, 2018
@aschempp
Copy link
Member Author

@contao/developers any other feedback? Can we agree that we want this implementation before I spend more time on fixing tests?

@Toflar
Copy link
Member

Toflar commented Apr 10, 2018

I've got it on my list, will review today :)

Copy link
Member

@Toflar Toflar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed. Excellent work and definitely must be merged. I've added a few comments that I think should be addressed first though 😄


$template->inColumn = $section;

if (is_array($classes = $request->attributes->get('classes'))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\is_array()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a task of php-cs-fixer, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jup… see 5cdc39a


$template = new BackendTemplate('be_wildcard');

$template->wildcard = '### ' . strtoupper($GLOBALS['TL_LANG']['FMD'][$this->getType()][0]) . ' ###';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use our translator here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in 9059847

@@ -77,6 +78,10 @@ protected function registerFragments(ContainerBuilder $container, string $tag):
$preHandlers[$identifier] = $reference;
}

if (is_a($definition->getClass(), AbstractFragmentController::class, true)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That just kills the possibility to have a custom controller that needs to know the fragment options but does not want to extend the AbstractFragmentController. I mean, the purpose of the fragments is that they are fully independent controllers so I think we should work with a FragmentOptionsAwareInterface here, wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I second that. We should use small(!) interfaces for these tasks.
Brings also the benefit of being able to deprecate one way (old interface) and introduce a new way without changing the API. I guess we will have to alter the mechanics in the future which is easier by adding another interface than having version_compares() and the like.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 43b042d

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;

class ForwardFragmentRenderer extends InlineFragmentRenderer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great if you could add some docs here and explain why this is needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 5523f84

@dmolineus
Copy link
Contributor

It's a great simplification of such attract controllers would be provided.

I'd prefer not to depend on the Contao template classes though. We could extend the symfony template engine wrapping the Contao templates. Then it's up to the developer to decide which template to use. Migrating later to twig templates would be really easy then.

For example following template syntax could be used:

  • contao:be:be_main.html5
  • contao:fe:fe_page.html5

I know it's off topic here but it would be nice to have this feature included when merging this pr.

If you like the idea I'd love to contribute the code. (I already do it in my toolkit library, https://github.com/netzmacht/contao-toolkit/blob/master/src/View/Template/ToolkitTemplateEngine.php)

*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getBackendWildcard(ModuleModel $module, Request $request)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should actually be also available for content elements, as some of them may display dynamic data as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not be in the parent class for sure, because the generated URL is different for different types. Also, none of the core elements have wildcards. What's the reason not to show dynamic data?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what's the reason to show backend wildcard for frontend modules?

Copy link
Member Author

@aschempp aschempp Apr 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

¯\(ツ)

I guess it's also a quick link to edit the module, which does not make sense for an element. There are content elements that change their appearance in the backend, but never to a wildcard. The YouTube element does not generate an iframe but a link to the video for example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes the content element (frontend module as well) relies on the frontend page settings, has some jQuery scripts in the template or simply a pagination that is useless in backend. There are also the cases were generated data may simply be not necessary to render in the backend.

The backend wildcard should also be available for content elements. It must not be enabled by default but I don't see a reason why not offer it for developer at all.

@aschempp aschempp force-pushed the feature/abstract-controller branch from d920e2a to 5c68bf9 Compare May 14, 2018 09:02
@aschempp
Copy link
Member Author

I have updated the PR. Most important change is to disable ignore_errors by default. If errors are ignores, it is not possible to handle ResponseException and fragments simply don't show up in the response. I noticed this because I had my own element that tried so use Controller::sentFileToBrowser.

@Toflar
Copy link
Member

Toflar commented May 14, 2018

Good find!

@leofeyer leofeyer added this to the 4.6.0 milestone May 31, 2018
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

abstract class AbstractFrontendModuleController extends AbstractFragmentController
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realize that the classes are called ContentElement and Module in Contao, therefore this class should be renamed to AbstractModuleController, shouldn't it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think so, because there is also a backend module. Imho the old naming is „wrong“.

@aschempp aschempp changed the title [RFC] Draft of Contao controllers [RTM] Draft of Contao controllers Jun 9, 2018
@leofeyer leofeyer merged commit 5b64c9e into contao:master Jun 11, 2018
@leofeyer
Copy link
Member

Thank you @aschempp.

@christian-kolb
Copy link
Contributor

@leofeyer @aschempp @fritzmg @Toflar @qzminski @dmolineus Has someone of you already implemented a frontend module with this or the previous controller in a public repository? I think it would be great to have this linked from the 4.6.0 release blog post. This way more people would get a kickstart and we might see more bundles using it faster 🙂

@bytehead
Copy link
Member

bytehead commented Sep 21, 2018

Something like this?

# app/config/services.yml

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

    # Content Elements
    app.content_element.acme_element:
        class: AppBundle\ContentElement\AcmeElement
        tags:
            - { name: contao.content_element, category: myCategory }
        calls:
            - [ setContainer,[ '@service_container' ] ]

    # Modules
    app.frontend_module.acme_module:
        class: AppBundle\Module\AcmeModule
        tags:
            - { name: contao.frontend_module, category: myCategory }
        calls:
            - [ setContainer,[ '@service_container' ] ]
// src/AppBundle/ContentElement/AcmeElement.php

<?php

declare(strict_types=1);

namespace AppBundle\ContentElement;

use Contao\CoreBundle\Controller\ContentElement\AbstractContentElementController;
use Contao\ModuleModel;
use Contao\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class AcmeElement extends AbstractContentElementController
{
    protected function getResponse(Template $template, ContentModel $model, Request $request): Response
    {
        $template->title = "AcmeElement";

        return new Response($template->parse());
    }
}
// src/AppBundle/Module/AcmeModule.php

<?php

declare(strict_types=1);

namespace AppBundle\Module;

use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
use Contao\ModuleModel;
use Contao\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class AcmeModule extends AbstractFrontendModuleController
{
    protected function getResponse(Template $template, ModuleModel $model, Request $request): Response
    {
        $template->title = "AcmeModule";

        return new Response($template->parse());
    }
}

@qzminski
Copy link
Member

@bytehead looks good and similar to mine, I am just not sure if setContainer call in services.yml is really needed. I would rather use service injection here 🤔

@bytehead
Copy link
Member

@qzminski
Copy link
Member

You sure? The class extends Controller which should already have container in it https://github.com/contao/contao/blob/master/core-bundle/src/Controller/AbstractFragmentController.php#L23

@bytehead
Copy link
Member

Yes, just tested. Probably because AbstractFrontendModuleController is abstract?

@qzminski
Copy link
Member

Ok that's strange, I would rather expect it to automatically have container set just like described in Symfony docs https://symfony.com/doc/3.4/controller.html#the-base-controller-class-services

Ping @aschempp

@aschempp
Copy link
Member Author

aschempp commented Sep 25, 2018

¯\(ツ)
I don't know… I guess you should debug that. I'm not very familiar with autowiring and autoconfiguration …

@aschempp aschempp deleted the feature/abstract-controller branch September 25, 2018 09:24
leofeyer added a commit that referenced this pull request Feb 21, 2020
Description
-----------

The PR partly reverts 43b5b45c1cb7f246c67026500dc20e8fa6d1593b and fixes the margin of the submit container.

Commits
-------

8a857d55 Adjust the login screen again 🤷‍♂️
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants