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] Use Symfony asset component for Contao assets #1165

Merged
merged 12 commits into from
Nov 15, 2017

Conversation

aschempp
Copy link
Member

@aschempp aschempp commented Oct 31, 2017

I started using Symfony Encore for our application asset management and stumbled over the Symfony Asset service. I think there are a ton of useful feature for Contao.

  • It knows the path to an asset by asking for the composer package.
  • It automatically adds the TL_ASSETS_URL prefix if configured.
  • It automatically adds the package version to the URL, which results in clever cache busting on updates.

The provided code is totally working, but there are a lot more features we can implement. Missing TODOs:

  • Use asset URLs for TL_JAVASCRIPT and TL_CSS
  • Add support for asset URLs (absolute) to the Contao\Combiner
  • Re-implement Controller::setStaticUrls instead of using constants in the context service.
  • Maybe add Resources/public of all bundles as packages.
  • Maybe add a package for the backend theme
  • Unit Tests


use Symfony\Component\Asset\Context\ContextInterface;

class ContaoContext implements ContextInterface
Copy link
Member

Choose a reason for hiding this comment

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

Nothing should rely on the constants anymore. If you need to access TL_* it's better to find a different way because the constants will not be available in 5 anymore.

Copy link
Member

Choose a reason for hiding this comment

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

The only other way is to read from $GLOBALS in the back end and from global $objPage in the front end, which does not seem less wrong than using the constants to me.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, or we find a new way because apparently we will still need that feature in the future :-)

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 ToDo no. 3 for this. We should probably inject the PageModel and "duplicate" the code from Controller::setStaticUrls.

@aschempp
Copy link
Member Author

aschempp commented Nov 1, 2017

I've added a dependency to https://github.com/terminal42/asset-bundle. This will automatically add all public bundle files as asset packages, completing the new Contao setup.

in Twig templates:

<img src="{{ asset('img/icon.png', 'rock_solid_slider') }}">
<img src="{{ asset('folder.gif', 'terminal42_folderpage') }}">

in Contao templates:

<img src="<?= $this->asset('img/icon.png', 'rock_solid_slider') ?>">
<img src="<?= $this->asset('folder.gif', 'terminal42_folderpage') ?>">

in Contao HTML module/element:

<img src="{{asset::img/icon.png::rock_solid_slider}}">
<img src="{{asset::folder.gif::terminal42_folderpage}}">

@leofeyer leofeyer force-pushed the develop branch 14 times, most recently from 495cb11 to 1358688 Compare November 5, 2017 16:21
@leofeyer
Copy link
Member

leofeyer commented Nov 7, 2017

I think we should finish this PR with the current feature set. The only item from the todo list that needs to be done is "Unit Tests". The rest can be added later.

@aschempp
Copy link
Member Author

aschempp commented Nov 8, 2017

@Toflar I have rewritten the contexts to use the page model, is that how you intended it?

@aschempp aschempp force-pushed the feature/assets branch 2 times, most recently from 91c4372 to 8f4dda4 Compare November 9, 2017 07:28
@aschempp aschempp changed the title [RFC] Use Symfony asset component for Contao assets [RTM] Use Symfony asset component for Contao assets Nov 9, 2017
Copy link
Member

@leofeyer leofeyer left a comment

Choose a reason for hiding this comment

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

Since there are only two contexts ("assets" and "files"), maybe we don't need the $field property. Why not have a ContaoAssetsContext and ContaoFilesContext?

*/
private function getFieldValue(): string
{
if (null === $this->page) {
Copy link
Member

Choose a reason for hiding this comment

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

        if (null !== $this->page) {
            return (string) $this->page->{$this->field};
        }

        /** @var Config $config */
        $config = $this->framework->createInstance(Config::class);

        return (string) $config->get($this->field);

@leofeyer leofeyer added this to the 4.5.0 milestone Nov 11, 2017
@aschempp
Copy link
Member Author

Why not have a ContaoAssetsContext and ContaoFilesContext?

I don't think that would make anything better. It means we need three classes instead of one, including an abstract. Which will be exactly the same, a class that will be configured, just by extending instead of a constructor argument.

Copy link
Member

@leofeyer leofeyer left a comment

Choose a reason for hiding this comment

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

Besides my two comments, I think there are a lot more places in the code where TL_ASSETS_URL is used. Are those not relevant?

{
if (null === $page) {
/** @var Config $config */
$config = $this->framework->createInstance(Config::class);
Copy link
Member

Choose a reason for hiding this comment

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

Why are you using createInstance() instead of getAdapter() here? And shouldn't we initialize the framework first?

Copy link
Member

Choose a reason for hiding this comment

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

Both must be fixed indeed.

@@ -394,7 +394,7 @@ public function mergeRow(array $arrData)
*/
public function markModified($strKey)
{
if (!isset($this->arrModified[$strKey]))
if (!isset($this->arrModified[$strKey]) && isset($this->arrData[$strKey]))
Copy link
Member

Choose a reason for hiding this comment

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

Is this change related to the feature?

@@ -1792,45 +1793,31 @@ public static function addEnclosuresToTemplate($objTemplate, $arrItem, $strKey='
/**
* Set the static URL constants
*
* @param PageModel $objPage An optional page object
* @deprecated Deprecated in Contao 4.5, to be removed in Contao 5. Use the asset contexts instead.
Copy link
Member

Choose a reason for hiding this comment

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

Since we have deprecated the method, we should no longer use it. Otherwise, if we still need to use it, we should not deprecate it. 😉

@leofeyer leofeyer merged commit eed0aea into contao:develop Nov 15, 2017
@leofeyer
Copy link
Member

Thank you @aschempp.

@aschempp aschempp deleted the feature/assets branch November 15, 2017 16:20
@fritzmg
Copy link
Contributor

fritzmg commented Dec 12, 2017

In your examples you are using

<img src="<?= $this->asset('folder.gif', 'terminal42_folderpage') ?>">

however, shouldn't it be

<img src="<?= $this->asset('folder.gif', 'terminal42/contao-folderpage') ?>">

Or what exactly is $packageName?

@Toflar
Copy link
Member

Toflar commented Dec 12, 2017

Yes it is, the example comment was before some more commits ;)

@aschempp
Copy link
Member Author

@fritzmg terminal42_folder is correct. The bundle assets are based on the bundle classname, which in most cases and for correct setups should match the bundle alias for container configuration. We can't use the package name because we don't know which package a bundle belongs to (and a package theoretically can contain multiple bundles).

The diffeference is Contao componentes (assets), where the package name is the composer package (e.g. contao-components/jquery), because these do not have a bundle name.

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.

4 participants