add_to_head.module in Add To Head 8
Same filename and directory in other branches
Add To Head allows arbitrary insertion of code into the head of the page based on path selection.
File
add_to_head.moduleView source
<?php
/**
* @file
* Add To Head allows arbitrary insertion of code into the head of the page
* based on path selection.
*/
use Drupal\Core\Render\Markup;
/**
* Helper to get the settings.
* @param string $scope (Optional) - filter the scopes of the returned settings.
* @return array Array of profiles, including those defined by other modules.
*/
function add_to_head_get_settings($scope = NULL) {
// Fetch the profile information stored in the DB.
$settings = \Drupal::config('add_to_head.settings')
->get('add_to_head_profiles');
$settings = $settings ? $settings : array();
// Allow other modules to alter profile settings. Additional profiles may be added here.
\Drupal::moduleHandler()
->alter('add_to_head_profiles', $settings);
if ($scope) {
$settings = array_filter($settings, function ($profile) use ($scope) {
return $profile['scope'] == $scope;
});
}
return $settings;
}
/**
* Helper to set settings back to the Database
* @param $settings array Array of profiles to store.
*/
function add_to_head_set_settings($settings) {
\Drupal::configFactory()
->getEditable('add_to_head.settings')
->set('add_to_head_profiles', $settings)
->save();
}
/**
* Is this profile visible?
*
* @param $profile
* @return bool
*/
function _add_to_head_profile_visible($profile) {
return add_to_head_match_page($profile) && add_to_head_match_role($profile);
}
/**
* Implements hook_page_attachments_alter().
*/
function add_to_head_page_attachments_alter(array &$attachments) {
// Inject code into the 'head' scope.
$settings = add_to_head_get_settings('head');
// If applicable, append each profile's code to the output.
foreach ($settings as $profile) {
if (_add_to_head_profile_visible($profile)) {
// Add to output
$attachments['#attached']['html_head'][] = [
[
'#type' => 'markup',
'#markup' => \Drupal\Core\Render\Markup::create($profile['code']),
'#suffix' => "\n",
],
'add-to-head--' . $profile['name'],
];
}
}
}
/**
* Implements hook_page_bottom().
*/
function add_to_head_page_bottom(array &$page_bottom) {
// Inject code into the 'scripts' scope.
$settings = add_to_head_get_settings('scripts');
// If applicable, append each profile's code to the output.
foreach ($settings as $profile) {
if (_add_to_head_profile_visible($profile)) {
// Add to output
$page_bottom['add_to_head'][] = [
[
'#type' => 'markup',
'#markup' => Markup::create($profile['code']),
'#suffix' => "\n",
'#cache' => [
'keys' => [
'add_to_head',
],
'contexts' => [
'user.permissions',
],
],
],
'add-to-head--' . $profile['name'],
];
}
}
}
/**
* Implements hook_css_alter().
*/
function add_to_head_css_alter(&$css, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {
$settings = add_to_head_get_settings('styles');
// If applicable, append each profile's code to the output.
foreach ($settings as $profile) {
if (_add_to_head_profile_visible($profile)) {
// @TODO - this does not work yet.
// $css[$profile['code']] = [
// 'type' => 'inline',
// ];
}
}
}
/**
* Determines if code should be displayed on a particular page.
*
* Originally from block_list().
*
* @param array $profile
* The profile to check against
* @param string $path
* Allow injection of non-current path for checking.
*
* @return boolean
* TRUE if the code should be displayed on the page; FALSE otherwise.
*/
function add_to_head_match_page(array $profile, $path = NULL) {
// Determine if the code should be visible on the current page.
$visibility = isset($profile['paths']['visibility']) ? $profile['paths']['visibility'] : 'exclude';
$paths = isset($profile['paths']['paths']) ? $profile['paths']['paths'] : '';
// Get the current path.
if (!isset($path)) {
$path = \Drupal::service('path.current')
->getPath();
}
// Compare with the internal and path alias (if any).
$page_match = \Drupal::service('path.matcher')
->matchPath($path, $paths);
if (!empty($_GET['q']) && $path != $_GET['q']) {
$page_match = $page_match || \Drupal::service('path.matcher')
->matchPath($_GET['q'], $paths);
}
// Check alias
if (!$page_match) {
$alias = \Drupal::service('path_alias.manager')
->getAliasByPath($path);
$page_match = \Drupal::service('path.matcher')
->matchPath($alias, $paths);
}
$visibility = $visibility == 'exclude' ? 0 : 1;
// When $visibility has a value of 0, the code is displayed on
// all pages except those listed in $paths. When set to 1, it
// is displayed only on those pages listed in $paths.
return !($visibility xor $page_match);
}
/**
* Determines if code should be displayed for a particular role.
*
* @param array $profile
* The profile to check against
* @param array $user_roles
* Allow injection of non-current user roles
*
* @return boolean
* TRUE if the code should be displayed on the page; FALSE otherwise.
*/
function add_to_head_match_role($profile, $user_roles = NULL) {
// Determine if the code should be visible given the current user's roles.
$visibility = isset($profile['roles']) && isset($profile['roles']['visibility']) ? $profile['roles']['visibility'] : 'exclude';
$roles = isset($profile['roles']) && isset($profile['roles']['list']) ? $profile['roles']['list'] : array();
if (!isset($user_roles)) {
$user_roles = \Drupal::currentUser()
->getRoles();
}
$common_roles = array_intersect($roles, $user_roles);
if ($visibility == 'exclude') {
// If any common roles, no match.
return empty($common_roles);
}
else {
// Visibility is include. Match on any common roles.
return !empty($common_roles);
}
}
Functions
Name | Description |
---|---|
add_to_head_css_alter | Implements hook_css_alter(). |
add_to_head_get_settings | Helper to get the settings. |
add_to_head_match_page | Determines if code should be displayed on a particular page. |
add_to_head_match_role | Determines if code should be displayed for a particular role. |
add_to_head_page_attachments_alter | Implements hook_page_attachments_alter(). |
add_to_head_page_bottom | Implements hook_page_bottom(). |
add_to_head_set_settings | Helper to set settings back to the Database |
_add_to_head_profile_visible | Is this profile visible? |