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

Load CSS files / Specify theme path in config / coding standards #11

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# attach-library-twig-extension
Twig function that lets Pattern Lab use a simple version of Drupal's [attach_library](https://www.drupal.org/docs/8/creating-custom-modules/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-module#twig) function to add javascript files per component.
Twig function that lets Pattern Lab use a simple version of Drupal's [attach_library](https://www.drupal.org/docs/8/creating-custom-modules/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-module#twig) function to add CSS or JavaScript files per component.

## Requirements

To use in Pattern Lab, simply place in the `_twig-components/functions` directory. Since this function is specifically for Pattern Lab (Drupal has its own), it is namespaced with `pl_` so if you're using the [Unified Twig Extensions](https://github.com/drupal-pattern-lab/unified-twig-extensions/) module, it will ignore it when syncing functions between Drupal and Pattern Lab.
1. Place the `pl_attach-library.function.php` file in the `pattern-lab/source/_twig-components/functions` directory.
2. Add `themePath: '/themes/my-awesome-theme` into the `pattern-lab/config/config.yml` configuration file. Modify the path to point to the root of your theme.

Since this function is specifically for Pattern Lab (Drupal has its own), it is namespaced with `pl_` so if you're using the [Unified Twig Extensions](https://github.com/drupal-pattern-lab/unified-twig-extensions/) module, it will ignore it when syncing functions between Drupal and Pattern Lab.

## Usage

Simply add `{{ attach_library(MODULE/FILENAME) }}` to any component Twig file using the same syntax as Drupal. Pattern Lab will then locate the theme's `*.libraries.yml` file and load the JavaScript file from the path in that library whenever that component is loaded. Since this function uses the same syntax as Drupal, nothing else needs to be done when loading the component in Drupal. It will work as it always did!
Simply add `{{ attach_library(THEME/LIBRARYNAME) }}` to any component Twig file using the same syntax as Drupal. Pattern Lab will then locate the theme's `*.libraries.yml` file and load the file from the path in that library whenever that component is loaded. Since this function uses the same syntax as Drupal, nothing else needs to be done when loading the component in Drupal. It will work as it always did!

## Current Limitations

This function is limited to loading the js file referenced in the library. It will not load other assets and will not load any dependencies either. If you need to load a dependency or other file in Pattern Lab, it can be done as usual in `/meta/foot.twig`. See the commented out parts in [Emulsify's file](https://github.com/fourkitchens/emulsify/blob/develop/components/_meta/_01-foot.twig) for examples of how to do this.
This function will not load dependencies. If you need to load a dependency or other file in Pattern Lab, it can be done as usual in `/meta/foot.twig`. See the commented out parts in [Emulsify's file](https://github.com/fourkitchens/emulsify/blob/develop/components/_meta/_01-foot.twig) for examples of how to do this.
62 changes: 43 additions & 19 deletions pl_attach-library.function.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,58 @@
use Symfony\Component\Yaml\Yaml;

$function = new Twig_SimpleFunction('attach_library', function ($string) {
$path_to_theme = \PatternLab\Config::getOption('themePath');

if (empty($path_to_theme)) {
throw new Exception('Missing themePath config option within PatternLab\'s config.yml. Please see the attach-library-twig-extension README.md.');
}

// Get Library Name from string.
$libraryName = substr($string, strpos($string, "/") + 1);
$library_name = substr($string, strpos($string, "/") + 1);

// Find Library in libraries.yml file.
$yamlFile = glob('*.libraries.yml');
$yamlOutput = Yaml::parseFile($yamlFile[0]);
$scriptTags = [];
$yaml_file = glob('*.libraries.yml');
$yaml_output = Yaml::parseFile($yaml_file[0]);
$library_tags = [];

// Add appropriate HTML tag to $library_tags array.
$add_library_tag = function ($library_tag) use (&$library_tags) {
$string_loader = \PatternLab\Template::getStringLoader();
$library_tags[] = $string_loader->render(["string" => $library_tag, "data" => []]);
};

// By default prefix paths with a /, but remove this for external JS
// as it would break URLs.
$build_path = function($options, $file) use (&$path_to_theme) {
return (isset($options['type']) && $options['type'] === 'external') ? $file : "$path_to_theme/$file";
};

// For each item in .libraries.yml file.
foreach($yamlOutput as $key => $value) {
foreach($yaml_output as $file => $value) {

// If the library exists.
if ($key === $libraryName) {
$files = $yamlOutput[$key]['js'];
// For each file, create an async script to insert to the Twig component.
foreach($files as $key => $file) {
// By default prefix paths with a /, but remove this for external JS
// as it would break URLs.
$path_prefix = '/';
if (isset($file['type']) && $file['type'] === 'external') {
$path_prefix = '';
if ($file === $library_name) {
$js_files = $yaml_output[$file]['js'];

if (!empty($js_files)) {
// For each file, create an async script to insert to the Twig component.
foreach($js_files as $file => $options) {
$add_library_tag('<script data-name="reload" data-src="' . $build_path($options, $file) . '"></script>');
}
}

$css_groups = $yaml_output[$file]['css'];

if (!empty($css_groups)) {
// For each file, create an async script to insert to the Twig component.
foreach($css_groups as $group => $files) {
foreach($files as $file => $options) {
$add_library_tag('<link rel="stylesheet" href="' . $build_path($options, $file) . '" media="all" />');
}
}
$scriptString = '<script data-name="reload" data-src="' . $path_prefix . $key . '"></script>';
$stringLoader = \PatternLab\Template::getStringLoader();
$scriptTags[$key] = $stringLoader->render(array("string" => $scriptString, "data" => []));
}
}
}
}

return implode($scriptTags);
return implode($library_tags);
}, array('is_safe' => array('html')));