diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/README.md b/README.md index bcd2bed..a81e226 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/pl_attach-library.function.php b/pl_attach-library.function.php index 00ed98e..21780d5 100644 --- a/pl_attach-library.function.php +++ b/pl_attach-library.function.php @@ -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(''); + } + } + + $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(''); + } } - $scriptString = ''; - $stringLoader = \PatternLab\Template::getStringLoader(); - $scriptTags[$key] = $stringLoader->render(array("string" => $scriptString, "data" => [])); - } + } } } - return implode($scriptTags); + return implode($library_tags); }, array('is_safe' => array('html')));