No Code Attached Yet
avatar maggus
maggus
29 Apr 2023

Is your feature request related to a problem? Please describe.

Currently, to my knowledge, it is not possible to place a new webasset at the beginning of head's script tags

  • when using WebAssetManager
  • in onAfterDispatch event
  • in a plugin.

But there might be some situations in which this is necessary (i.e. privacy/consent tools).

Describe the solution you'd like

Currently I'm using a workaround to place Joomla! 4 integrated scripts after my own scripts that have been "registered" and "used" before this code.

$app = Factory::getApplication();
$document = Factory::getDocument();
$webassets = $document->getWebAssetManager();

// Places 'media/system' and 'media/vendor' scripts after consent tools
$assets = [
	'diff',
	'accessibility',
	'short-and-sweet',
	'awesomplete',
	'cropperjs',
	'choicesjs',
	'focus-visible',
	'dragula',
	'hotkeysjs',
	'jquery',
	'metismenujs',
	'skipto',
	'qrcode',
	'joomla.batch-copymove',
	'core',
	'field.color-slider'
];

foreach($assets as $asset) {
	if ($webassets->getAssetState('script', $asset) !== 0) {
		$webassets
			->disableAsset('script', $asset)
			->useAsset('script', $asset);
	}
}
unset($asset);

What does this script do? It disables and re-enables certain scripts so that they are placed later in the WebAssetManager. "Certain scripts" means that only scripts WITHOUT any dependency get reordered. All other dependent assets seem to be attached after these scripts even when asset state changes from '2' to '1' by this method.

Additional context

I would like to get feedback if

  • this solution might break the WebAssetManager in certain situations
  • there is an upcoming feature in Joomla! 4 Roadmap that addresses this problem.
avatar maggus maggus - open - 29 Apr 2023
avatar joomla-cms-bot joomla-cms-bot - change - 29 Apr 2023
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 29 Apr 2023
avatar maggus maggus - change - 29 Apr 2023
The description was changed
avatar maggus maggus - edited - 29 Apr 2023
avatar maggus maggus - change - 29 Apr 2023
The description was changed
avatar maggus maggus - edited - 29 Apr 2023
avatar maggus maggus - change - 29 Apr 2023
The description was changed
avatar maggus maggus - edited - 29 Apr 2023
avatar maggus maggus - change - 29 Apr 2023
The description was changed
avatar maggus maggus - edited - 29 Apr 2023
avatar maggus maggus - change - 29 Apr 2023
The description was changed
avatar maggus maggus - edited - 29 Apr 2023
avatar maggus maggus - change - 29 Apr 2023
The description was changed
avatar maggus maggus - edited - 29 Apr 2023
avatar richard67 richard67 - change - 29 Apr 2023
Labels Added: ?
avatar richard67 richard67 - labeled - 29 Apr 2023
avatar dgrammatiko
dgrammatiko - comment - 29 Apr 2023

Currently, to my knowledge, it is not possible to place a new webasset at the beginning of head's script tags

How are you registering your assets?
Using $document->addScript() or similar, will always append the asset AFTER the ones registered with WebAssetManager
Using HTMLHelper::script() or similar will always append the asset AFTER the ones registered with WebAssetManager

So, to register something at the very beginning you have to:

  • make sure you use the WebAssetManager for the assets
  • Call Register and Use functions on an early stage (ie onAfterRoute)

In sort, the old functions will ALWAYS append the assets after the ones from the WAM...

Lastly, I guess this is for v5 (@HLeithner), all the old APIs for the scripts/stylesheets should be deprecated but in the mean time they should proxy to the respected WAM ones

avatar maggus
maggus - comment - 29 Apr 2023

@dgrammatiko
I register the assets with $wa->registerAndUseScript() on onAfterDispatch event.

Using onAfterRoute would be one system event earlier right? But how can I register assets without instantiating the Document object? This also seems to be bad practice, according to this document.

avatar Fedik
Fedik - comment - 29 Apr 2023

What you are doing is changing FIFO order.
You can adjust it for specific Asset with:

$wa->getAsset('script', 'potato-consent')->setOption('weight', -1);

However it does not guarante to be first, especialy when the asset have a dependency, or someone else already doing the same.

In the end I would not recommend to abuse this option. If possible better use @dgrammatiko suggestion but with onAfterDispatch event.
I closing the issue, the feature already exists.

avatar Fedik Fedik - close - 29 Apr 2023
avatar Fedik Fedik - change - 29 Apr 2023
Status New Closed
Closed_Date 0000-00-00 00:00:00 2023-04-29 17:12:42
Closed_By Fedik
avatar Fedik Fedik - change - 29 Apr 2023
Labels Removed: ?
avatar Fedik Fedik - unlabeled - 29 Apr 2023
avatar maggus
maggus - comment - 30 Apr 2023

Thank you both (@dgrammatiko, @Fedik) for the detailed feedback!

I was not aware that there is an option you can use to request a change of the assets order. I have already tried the approach with WAM and onAfterDispatch event but this hasn't led to a stable result as system and component assets might be enabled before.

Therefore I have created the workaround shown at the beginning but this approach only generates workload without a stable result either. To change the weight of a certain asset seems to be the lightest solution with highest success. Of course, this can be overwritten again but it might suit to most of the scenarios considered.

Add a Comment

Login with GitHub to post a comment