4

I want to include the YAMM!3 CSS library in my Drupal 8 site. To that end, I wrote a custom module following the instructions in this answer. Although that answer is in regards to a php library, I thought it would also work for a CSS library.

This is the composer.json from my custom module:

{
  "name": "drupal/my_yamm3",
  "type": "drupal-module",
  "require": {
    "geedmo/yamm3": "*"
  }
}

In the composer.json in the root of my Drupal codebase, I have this:

"extra": {
    ...
    "merge-plugin": {
        "include": [
            "core/composer.json",
            "modules/custom/my_yamm3/composer.json"
        ],
    ...

I updated my codebase with this commands:

$ composer update
$ composer dumpauto

And I noticed this line in composer's output:

> Drupal\Core\Composer\Composer::vendorTestCodeCleanup
  - Installing geedmo/yamm3 (1.1.0): Loading from cache

Which is confirmed by an examination of the filesystem:

$ ls vendor/geedmo/yamm3/
bower.json  composer.json  demo/  gulpfile.js  index.html  LICENSE.txt  package.json  README.md  yamm/

I've enabled the my_yamm3 module on my site, and under admin/config/development/performance, I've disabled css aggregation.

However, when I load the page, I do not see the yamm libraries being loaded in the network tab in my browser.

Am I using the correct method to load a third-party css library? What am I doing wrong?

EDIT osman asked for some confirmation of the state of my environment. In my drupal project root, while I do have /composer.json and the directories /drush/ and /vendor/, I don't have /scripts/ nor /web/. I guess that means I am not using the drupal-composer/drupal-project project.

Regarding his recommended additions to composer.json, this is what I had:

"extra": {
    "installer-paths": {
        "core": ["type:drupal-core"],
        "modules/contrib/{$name}": ["type:drupal-module"],
        "profiles/contrib/{$name}": ["type:drupal-profile"],
        "themes/contrib/{$name}": ["type:drupal-theme"],
        "drush/contrib/{$name}": ["type:drupal-drush"],
        "modules/custom/{$name}": ["type:drupal-custom-module"],
        "themes/custom/{$name}": ["type:drupal-custom-theme"]
    }
},

So again it looks like I don't have the composer project?

  • You were already on the right way. composer-merge-plugin plus custom-installer. Then you define a location for third party theme libs like for example web/themes/custom/MYTHEME/libs/{$name}. And in your custom module's composer.json you reference the library directly from GitHub tagging it with the custom-installer type defined before. See step-by-step drupal.stackexchange.com/a/260766/15055 – leymannx May 27 '18 at 0:10
  • Ah OK, sorry, now I see your main problem actually is that all you've forgotten is to bind the lib from MYMODULE.libraries.yml and then simply attach it to every page with hook_page_attachments from within MYMODULE.module. See Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module. – leymannx May 27 '18 at 0:51
2

Fundamentals

To bind a CSS library into your Drupal installation, it should be defined and exposed via a *.libraries.yaml file.

For example (taken from core's classy theme):

book-navigation:
  version: VERSION
  css:
    component:
      css/components/book-navigation.css: {}

defines that there is a library called book-navigation that when included in a page will deliver the css/components/book-navigation.css css file.

Using composer with 3rd-party CSS libraries

Composer works easily and reliably for PHP dependencies, using the merge-plugin in the way you started working in the OP. But, CSS and Javascript libraries, especially when some preprocessing or building step is required, are a different story. This is an open and unsolved (to my knowledge and to the date) problem, you can read this issue to get an idea of what problems arise:

The main problem is, that when you import the library as a composer dependency, as you did, the library is installed inside the vendor directory wherever that is located. So, you cannot assume much inside your *libraries.yaml file about the file path to the CSS/JS file(s) you want to use.

Alternative (A) without composer: using CDN / externally hosted libraries definitions

For you case, and taken that you want to include this file:

https://raw.githubusercontent.com/geedmo/yamm3/master/yamm/yamm.css

you could define it inside your *libraries.yaml file as an externally hosted library (see #external):

my_module.yamm3:
  remote:  https://raw.githubusercontent.com/geedmo/yamm3/master/yamm/yamm.css
  version: VERSION
  license:
    name: MIT
    url: https://github.com/geedmo/yamm3/blob/master/LICENSE.txt
    gpl-compatible: true
  css:
    theme:
      https://raw.githubusercontent.com/geedmo/yamm3/master/yamm/yamm.css : { type: external }

N.B.: This approach should always deliver the latest yamm.css version.

Alternative (B) without composer: keeping a local copy in your own module's folder

If you place the CSS file inside your module's folder, e.g. css/yamm.css, you will be able to use the following yaml definition in your *.libraries.yaml file in order to be able to use it:

my_module.yamm3:
  version: VERSION
  css:
    theme:
      css/yamm.css : {}

Attaching a library to page(s)

Finally, after you are done defining your library, you can start using it.

This is documented extensively here (https://www.drupal.org/docs/8/creating-custom-modules/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-module) and I would recommend reading that if you haven't already.

Good luck!

| improve this answer | |
  • for Alt. B, is one of the css lines supposed to be the name of my current theme? I used hook_page_attachments_alter and I'm getting this User warning: The following theme is missing from the file system: css in drupal_get_filename() (line 268 of core\includes\bootstrap.inc). drupal_get_filename('theme', 'css') (Line: 291) drupal_get_path('theme', 'css') (Line: 394) ... Drupal\Core\Asset\LibraryDiscovery->getLibraryByName('css', 'yamm.css') (Line: 54) ... – user1359 Apr 24 '18 at 20:41
  • Nope, this approach is theme independent. Can you give an example of how you call hook_page_attachments_alter? – Stefanos Petrakis Apr 29 '18 at 2:31
  • Looke like this: function my_yamm3_page_attachments_alter(&$build) { $build['#attached']['library'][] = 'css/yamm.css'; } – user1359 May 1 '18 at 19:29
  • That should be $build['#attached']['library'][] = 'my_module/my_module.yamm3';: you need to use the machine name of the module and the library, not the filepaths or filenames. See drupal.org/docs/8/creating-custom-modules/… – Stefanos Petrakis May 2 '18 at 7:26
1

More likely your vendor directory is off of the web root. Could you confirm that?

If you by any chance using drupal-composer/drupal-project project, it would have a folder structure like this:

/composer.json
/drush/
/scripts/
/vendor/
/web/
/web/core/
/web/libraries/
/web/modules/
/web/profiles/
/web/sites/
/web/themes/
...

The libraries folder is the folder you need your YAMM!3 CSS library placed in. So that it could be accessible via web also.

In my composer.json file I have Drupal specific folders defined in extra.installer-paths:

...
"extra": {
    "installer-paths": {
        "web/core": ["type:drupal-core"],
        "web/libraries/{$name}": ["type:drupal-library"],
        "web/modules/contrib/{$name}": ["type:drupal-module"],
        "web/profiles/contrib/{$name}": ["type:drupal-profile"],
        "web/themes/contrib/{$name}": ["type:drupal-theme"],
        "drush/contrib/{$name}": ["type:drupal-drush"]
    }
}

With the help of composer/installers package and the configuration in extra, each package required by composer is copied to their own dedicated folders. So, yours could be copied into libraries folder.

Check out the code and documentation at https://github.com/drupal-composer/drupal-project

It should provide all the details for you to update your project to support what you need. Otherwise come back for more :)

| improve this answer | |
  • I made an update to my question, from what I understand, it looks like I don't have the drupal-composer project. Is that necessary for this to work? Is there another way to install a CSS library? – user1359 Apr 24 '18 at 18:52
  • Hi user1359, is the real issue not being able to install YAMM!3 CSS library via composer, or once installed not being able to load the library on required pages? – osman Apr 24 '18 at 18:56
  • of course, my ultimate goal is to get the YAMM!3 library loaded. How I do that, I don't really care. I googled how to do that, and found the instructions that I linked, and the only way I can tell whether it worked or not is if the library loads or fails to load. I am not aware of any other way to test that. – user1359 Apr 24 '18 at 19:00
  • 1
    Thanks for clarifying. Loading a (CSS or JS) library would easily be done via implementing hook_page_attachments() hook. This could be done more easily if you define a yourmodule.libraries.yml file for the YAMM!3 library. @Stefanos Petrakis's answer covers that part. And my answer was focusing on how to define an external Composer package as a dependency and install it as a library item. – osman Apr 24 '18 at 19:16
  • thanks for taking the time to write out this very detailed answer and help me understand my situation : ) – user1359 Apr 25 '18 at 13:47
1

Drupal 8 does not allow for an easy way to set up libraries that use files in the vendor directory. To get around this, I just created the Vendor Stream Wrapper module, which creates a vendor:// stream wrapper, allowing for linking to files in the vendor folder, even if it is outside the webroot.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.