Ron Northcutt
Sr. Solutions Architect
drupal list
drupal generate:module
drupal generate:entity:content
drush en thingy -y
* Use asset_injector in D8
Generate module and custom entity.
Modify Entity - add Base Field Definitions
$fields['content'] = BaseFieldDefinition::create('string_long')
->setLabel(t('Asset file content'))
->setDescription(t('Enter the code that will be stored in this asset.'))
->setRequired(TRUE)
->setRevisionable(TRUE)
->setDefaultValue('')
->setDisplayOptions('form', [
'type' => 'string_textarea',
'weight' => -1,
'settings' => ['rows' => 25,]
])
->setDisplayConfigurable('view', TRUE);
Modify Entity - add Base Field Definitions
$fields['type'] = BaseFieldDefinition::create('list_string')
->setLabel(t('Asset type'))
->setDescription(t('Select the type of Asset that this should be.'))
->setRequired(TRUE)
->setTranslatable(FALSE)
->setRevisionable(FALSE)
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => -3,
])
->setSetting('allowed_values', [
'css' => 'CSS',
'js' => 'JS',
])
->setDisplayConfigurable('form', FALSE);
Modify Entity - add Base Field Definitions
$fields['uri'] = BaseFieldDefinition::create('uri')
->setLabel(t('URI'))
->setDescription(t('The URI to access the Asset file.'))
->setRequired(TRUE)
->setTranslatable(FALSE)
->setRevisionable(FALSE)
->setSetting('max_length', 255)
->setSetting('case_sensitive', TRUE)
->addConstraint('FileUriUnique');
Modify Interface - add methods
/**
* Returns the type of the Asset file
*
* @return string
* The file type, e.g. css.
*/
public function getType();
/**
* Returns the name of the Asset file
*
* @return string
* Name of the file
*/
public function getFileName();
/**
* Returns the URI of the Asset file
*
* @return string
* The URI of the file, e.g. public://asset/css/custom.css
*/
public function getFileUri();
Modify Entity - add interface methods
/**
* {@inheritdoc}
*/
public function getType() {
return $this->get('type')->value;
}
/**
* {@inheritdoc}
*/
public function getFileName() {
$name = $this->get('name')->value;
$extension = '.' . $this->getType();
$filename = strtolower($name);
$filename = preg_replace('/[^a-z0-9_]+/', '_', $filename);
return $filename . $extension;
}
/**
* {@inheritdoc}
*/
public function getFileUri() {
$filename = $this->getFileName();
$type = $this->getType();
return "public://asset/$type/$filename";
}
Make sure folder structure will exist (or not)
Create asset.install file
Make sure folder structure will exist (or not)
/**
* Implements hook_install().
*
* See /core/modules/image/image.install for example
*/
function asset_install() {
// Create the asset directories and ensure they're writable.
$directory = file_default_scheme() . '://asset';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
$directory = file_default_scheme() . '://asset/css';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
$directory = file_default_scheme() . '://asset/js';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
}
Make sure folder structure will exist (or not)
/**
* Implements hook_uninstall().
*/
function asset_uninstall() {
// Remove the asset directory and generated images.
file_unmanaged_delete_recursive(file_default_scheme() . '://asset');
}
Modify Entity - add asset entity methods
/**
* Saves the Asset code as a file.
*/
public function saveFile() {
$new_uri = $this->getFileUri();
$content = $this->get('content')->value;
file_unmanaged_save_data($content, $new_uri, FILE_EXISTS_REPLACE);
}
Modify Entity - add asset entity methods
/**
* Deletes the Asset file.
*
* @param string
* The URI for the file to delete, or use the auto generated one.
*/
public function deleteFile($uri = '') {
if (!$uri) {
$uri = $this->getFileUri();
}
file_unmanaged_delete($uri);
}
Modify Entity - add asset entity methods
/**
* Clear the CSS and JS caches
*
* See drupal_flush_all_caches() in common.inc.
*/
public function clearFileCache() {
// Flush Asset file caches.
\Drupal::service('asset.css.collection_optimizer')->deleteAll();
\Drupal::service('asset.js.collection_optimizer')->deleteAll();
_drupal_flush_css_js();
}
Modify Entity - extend base entity methods
/**
* {inheritdoc}
*/
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
$this->saveFile();
$this->clearFileCache();
}
Modify Entity - extend base entity methods
/**
* {inheritdoc}
*/
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
foreach ($entities as $entity) {
$entity->deleteFile();
}
}
Modify the asset.module file to attach code to pages
use Drupal\asset\Entity\Asset;
Create the library array (no yaml)
/**
* Implements hook_library_info_build().
*/
function asset_library_info_build(){
$libraries = [];
$libraries['asset-files'] = [
'dependencies' => [],
'js' => [],
'css' => [
'theme' => [],
],
];
$assets = Asset::loadMultiple();
foreach ($assets as $asset) {
$type = $asset->getType();
$path = $asset->getFileUri();
switch ($type) {
case 'css':
$libraries['asset-files']['css']['theme'] += [$path => []];
break;
case 'js':
$libraries['asset-files']['js'] += [$path => []];
break;
}
}
return $libraries;
}
Attach CSS/JS to page
/**
* Implements hook_page_attachments_alter().
*/
function asset_page_attachments_alter(array &$page) {
$page['#attached']['library'][] = 'asset/asset-files';
}
Modify Entity - garbage collection
/**
* Remove old file if the name changed.
*/
public function dedupeFile() {
// Check if the filename changed so we can delete the old one
$old_uri = $this->get('uri')->value;
$new_uri = $this->getFileUri();
if ($old_uri !== $new_uri) {
$this->deleteFile($old_uri);
}
}
Modify Entity - add to presave
// Run the dedupe in case the file name changed
$this->dedupeFile();
$this->set('uri', $this->getFileUri());
The best way to learn is to jump in and start creating.
Get off the fence. All you need is an hour or two.
Start simple. Build complexity and add functionality as you go along.
Create and test a basic entity
Port a module or create your own
Review other webinars, tutorials, and videos
Use a custom entity in your next project