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

Add parameters injections to ViewRenderer + minor refactoring #122

Merged
merged 26 commits into from
Sep 14, 2020

Conversation

vjik
Copy link
Member

@vjik vjik commented Aug 8, 2020

Q A
Is bugfix?
New feature? ✔️
Breaks BC?
Fixed issues #123
  1. Move adding of "csrf" parameters to external class CsrfViewInjection. This change will allow without changing ViewRenderer class add any parameters to view or layout.

  2. Add class ApplicationViewInjection to add params, meta- and link-tags to views.

  3. Method getName() make static and added cache by object class name.

Idea of next steps:

  • Move ViewRenderer to package (separately or yiisoft/view or yiisoft/web)
  • Move CsrfViewInjection to package (separately or yiisoft/view or yiisoft/web)
  • ApplicationViewInjection use in App for add parameters, meta and link tags to views.

Example of config:

'viewRenderer' => [
	'viewBasePath' => '@views',
	'layout' => '@views/layout/main',
	'injections' => [
		Reference::to(CsrfViewInjection::class),
		Reference::to(ApplicationViewInjection::class),
	],
],

Example of ApplicationViewInjection:

class ApplicationViewInjection implements
    LayoutParamsInjectionInterface,
    MetaTagsInjectionInterface,
    LinkTagsInjectionInterface
{

    private User $user;
    private UrlMatcherInterface $urlMatcher;

    public function __construct(
        User $user,
        UrlMatcherInterface $urlMatcher
    ) {
        $this->user = $user;
        $this->urlMatcher = $urlMatcher;
    }

    public function getLayoutParams(): array
    {
        return [
            'user' => $this->user->getIdentity(),
            'currentUrl' => (string)$this->urlMatcher->getLastMatchedRequest()->getUri(),
            'brandLabel' => 'Yii Demo',
        ];
    }

    public function getMetaTags(): array
    {
        return [
            [
                '__key' => 'generator',
                'name' => 'generator',
                'value' => 'Yii',
            ],
        ];
    }

    public function getLinkTags(): array
    {
        return [
            [
                '__key' => 'favicon',
                'name' => 'icon',
                'value' => 'favicon.ico',
            ],
        ];
    }
}

@samdark
Copy link
Member

samdark commented Aug 9, 2020

That looks overcomplicated for the problem it solves.

@vjik
Copy link
Member Author

vjik commented Aug 16, 2020

Made it a little simpler (merge contentInjections and layoutInjections), and create ApplicationInjection — this is convenient for add parameters, meta and link tags to App views.

@xepozz xepozz requested a review from a team August 16, 2020 08:44
src/ViewRenderer/CsrfViewInjection.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ContentParamsInjectionInterface.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
@samdark samdark added the status:code review The pull request needs review. label Aug 17, 2020
Copy link
Member

@samdark samdark left a comment

Choose a reason for hiding this comment

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

I like that layout parameters are separated from content parameters. Still, I think that overall it can be simpler.

src/Contact/ContactController.php Outdated Show resolved Hide resolved
public function getLayoutParams(): array
{
return [
'user' => $this->user->getIdentity(),
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

In defaultParameters set to both: content and layout.
If need only for layout defaultParameters not suitable.

Copy link
Member

Choose a reason for hiding this comment

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

I've meant that such configuration is way more exposed to end user and simpler than modifying ApplicationViewInjection itself. It could be generalized and made configurable.

{
return [
[
'__key' => 'favicon',
Copy link
Member

Choose a reason for hiding this comment

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

That's static. It's better to have it in HTML directly.

Copy link
Member Author

@vjik vjik Aug 19, 2020

Choose a reason for hiding this comment

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

I didn't understand... Return HTML, for example <link rel="icon" type="image/png" href="/myicon.png"> ?

Copy link
Member

Choose a reason for hiding this comment

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

I mean there's no reason to inject it. It could be just a line of HTML in layout like https://github.com/yiisoft/yii-demo/blob/master/views/layout/main.php#L32

{
return [
[
'__key' => 'generator',
Copy link
Member

Choose a reason for hiding this comment

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

That's static. It's better to have it in HTML directly.

src/ViewRenderer/ViewRenderer.php Outdated Show resolved Hide resolved
use Yiisoft\Strings\Inflector;
use Yiisoft\View\ViewContextInterface;
use Yiisoft\View\WebView;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\Yii\Web\Middleware\Csrf;
use Yiisoft\Yii\Web\User\User;

final class ViewRenderer implements ViewContextInterface
Copy link
Member

Choose a reason for hiding this comment

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

Can part of these changes such as having defaults for parameters / layout be applied to yiisoft/view package directly?

Copy link
Member

Choose a reason for hiding this comment

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

Also do you plan to move this class somewhere out of the application?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also do you plan to move this class somewhere out of the application?

https://github.com/yiisoft/yii-view

Copy link
Member Author

Choose a reason for hiding this comment

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

Can part of these changes such as having defaults for parameters / layout be applied to yiisoft/view package directly?

This can be partially done. For link and meta tags.
For content/layout params this it's impossible: in yiisoft/view there is no division into content and layout.

Copy link
Member

Choose a reason for hiding this comment

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

Let's add default link and meta-tags to yiisoft/view.

@vjik
Copy link
Member Author

vjik commented Aug 19, 2020

Moved ViewRenderer and interfaces to yiisoft/yii-view.

Where to move CsrfViewInjection:

  1. to yiisoft/yii-web (add dependences yii-view, data-response, view, files, html, json);
  2. to separately package.

?

@samdark
Copy link
Member

samdark commented Aug 20, 2020

  1. Definitely no.
  2. Likely it should stay in the application (this package).

@vjik
Copy link
Member Author

vjik commented Aug 20, 2020

  1. Likely it should stay in the application (this package).

But CsrfViewInjection doesn't require changes to be used in any applications.

Advantages separately package:

  1. reuse in any apps
  2. default config for container (common.php):
CsrfViewInjectionInterface::class => CsrfViewInjection::class,

Maybe create package, for example, yiisoft/yii-csrf-view-injection or yiisoft/yii-csrf and additional move yii-web/src/Middleware/Csrf.php to him?

@samdark
Copy link
Member

samdark commented Aug 20, 2020

How about having it in yii-view?

@vjik
Copy link
Member Author

vjik commented Aug 20, 2020

How about having it in yii-view?

This added dependences for yii-view from router and yii-web. It's ok?

@samdark
Copy link
Member

samdark commented Aug 20, 2020

Yes since it's yii- packages are framework specific.

@vjik
Copy link
Member Author

vjik commented Aug 20, 2020

Ok, I make it.

@samdark
Copy link
Member

samdark commented Sep 6, 2020

Should be adjusted since https://github.com/yiisoft/csrf is there now.

@samdark samdark added status:under development Someone is working on a pull request. and removed status:code review The pull request needs review. labels Sep 6, 2020
@vjik
Copy link
Member Author

vjik commented Sep 8, 2020

Should be adjusted since https://github.com/yiisoft/csrf is there now.

See yiisoft/csrf#2

…erer

# Conflicts:
#	config/common.php
#	src/Blog/Post/PostController.php
#	src/ViewRenderer/ViewRenderer.php
@vjik
Copy link
Member Author

vjik commented Sep 14, 2020

@samdark samdark merged commit 07b88b6 into yiisoft:master Sep 14, 2020
@vjik vjik deleted the view-renderer branch September 15, 2020 15:47
@TiaNex-Com
Copy link

TiaNex-Com commented Sep 16, 2020

please merge these functions to one,thanks

/**
* @param object $injection
* @return self
*/

public function withAddedInjections(array $injections): self
{
$new = clone $this;
$new->injections = array_merge($this->injections, $injections);
return $new;
}

/**
 * @param object $injection
 * @return self
 */
public function withAddedInjection($injection): self
{
    return $this->withAddedInjections([$injection]);
}

/**
 * @param object[] $injections
 * @return self
 */
public function withInjections(array $injections): self
{
    $new = clone $this;
    $new->injections = $injections;
    return $new;
}

@vjik
Copy link
Member Author

vjik commented Sep 16, 2020

please merge these functions to one,thanks

This is different functions.

  • withInjections replace current injections to new injections.
  • withAddedInjections merge current injections with new injections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:under development Someone is working on a pull request. status:under discussion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants