Tagging assets automatically
Uploaded assets like images, documents or media files can be assigned to Tags and AssetCollections manually in the Media module. Especially for sites with many assets it is useful to automate this in order to keep files organized.
Asset Collection based on site
Sites can already be assigned to an AssetCollection in the Sites Management module. If that is the case, any asset uploaded to a node within that site will automatically be added to the corresponding AssetCollection. This is especially useful in order to keep files of multi-site installations separated.
For more fine-granular manipulation the ContentController::assetUploaded
signal can be used to
alter assets based on the node they were attached to:
Hooking into the asset creation
In order to hook into the asset creation, a new signal/slot connection has to be established. For this a new Package.php (usually in Packages/Site/The.Site/Classes/) has to be added:
Example: Package.php
<?php
namespace Some\Package;
use Neos\Flow\Core\Bootstrap;
use Neos\Flow\Package\Package as BasePackage;
use Neos\Neos\Controller\Backend\ContentController;
class Package extends BasePackage
{
public function boot(Bootstrap $bootstrap)
{
$dispatcher = $bootstrap->getSignalSlotDispatcher();
$dispatcher->connect(ContentController::class, 'assetUploaded', AssetManipulator::class, 'manipulateAsset');
}
}
Note
If you created a new Package.php
file you need to run ./flow flow:package:rescan in order for Flow to pick it up!
The slot gets called with the following arguments:
The
Asset
instance that is about to be persistedThe
NodeInterface
instance the asset has been attached toThe node property name (
string
) the asset has been assigned to
So the signature of the slot method could look like this:
function theSlot(Asset $asset, NodeInterface $node, string $propertyName)
This allows for manipulation of the asset based on the node property it has been assigned to.
Example: Tagging employee images
Imagine you have a node type Employee with the following setup:
'Some.Package:Employee':
superTypes:
'Neos.Neos:Content': true
ui:
label: 'Employee'
inspector:
groups:
'employee':
label: 'Employee'
properties:
'image':
type: 'Neos\Media\Domain\Model\ImageInterface'
ui:
label: 'Employee profile picture'
reloadIfChanged: true
inspector:
group: 'employee'
editorOptions:
features:
mediaBrowser: false
The following code would automatically tag this with the employee tag (if it exists):
Example: AssetManipulator.php
<?php
namespace Some\Package;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\Annotations as Flow;
use Neos\Media\Domain\Model\Asset;
use Neos\Media\Domain\Repository\TagRepository;
/**
* @Flow\Scope("singleton")
*/
class AssetManipulator
{
/**
* @Flow\Inject
* @var TagRepository
*/
protected $tagRepository;
public function assignTag(Asset $asset, NodeInterface $node, string $propertyName)
{
if (!$node->getNodeType()->isOfType('Some.Package:Employee') || $propertyName !== 'image') {
return;
}
$employeeTag = $this->tagRepository->findOneByLabel('employee');
if ($employeeTag === null) {
return;
}
$asset->addTag($employeeTag);
}
}
Alternatively, the slot could also assign the asset to AssetCollections or alter the asset’s title or caption.