A: #1400748: Proposal for unified namespace organization introduced a 'core/lib' directory for classed Drupal core base-system code. Currently only the Cache system lives there, but there are patches for the Locking System and for the Database System already, and the idea is to move more and more code over there. External PHP projects (specifically not using the word libraries here) such as Symfony, which is already in core, live in core/vendor. Using such a 'lib' directory is a well-established standard in other PHP (!) projects, so it makes sense to follow that standard.

B: In contrib, there is already a well established standard of the 'sites/all/libraries' folder, in which people can put their jQuery and CSS libraries and which modules can then access with Libraries API. This idea in Libraries API is basically just an extension of the Drupal module/theme system, where a e.g. theme can live in 'core/themes', 'profiles/$profile/themes', 'sites/all/themes', or 'sites/$site/themes'. In just the same way, Libraries API allows libraries to live in 'core/libraries'*, 'profiles/$profile/libraries', 'sites/all/libraries', 'sites/$site/libraries'. Drupal core doesn't put it's JavaScript libraries in 'core/libraries', but that is just because core has always lumped all non-module JavaScript, CSS and images in the mysterious 'core/misc' folder, which is really a mess. If core were following the good example set by contrib there would be a 'core/libraries' folder with jQuery, jQueryUI, etc. (And you could do drupal_get_path('library', 'jquery') just like you can do drupal_get_path('module', 'node').) So really, even if there isn't one now, there really should be a 'core/libraries' folder.

If you put A and B together, you have a 'core/lib' and a 'core/libraries' folder. That sucks, for, I hope, obvious reasons!!!
Alas, discuss.

* Currently there is no 8.x branch for Libraries API, but in 7.x we support the top-level 'libraries' just like the top-level 'modules' is supported by core.

PS: Something that just came into my mind: The above mentioned issue established the distinction between 'core/lib/Drupal/Core' and 'core/lib/Drupal/Component' (see that issue for more info.). For JS we currently also have these pseudo-libraries like tabledrag, etc. which are libraries in the sense that they are stand-alone from any module, but they are specific to Drupal. So they are sort of in the 'Component' realm. So maybe it makes sense to borrow that distinction for JS and other stuff as well. Maybe not, though.

Comments

pounard’s picture

C. Rename sites/all/libraries to sites/all/resources or sites/all/assets

EDIT: I like bikesheding, and I think the libraries folder has such as bad name.

robloach’s picture

I understand the confusion. core/vendor is similar to Libraries, and "core/lib" looks like "Libraries API", but both folders have different goals than what Libraries API is trying to accomplish and it shouldn't be mixed.

core/lib
Drupal Core's PSR-0 PHP auto-loading classes. Check out Crell's blog post on dat.
core/vendor
Drupal Core's third-party vendor packages which have strict version requirements and dependencies. Usually live at core/vendor/[vendor-name]/[package-name]. If PSR-0 compatible (they don't need to be), the PHP code can be auto-loaded.
core/libraries
Should never exist as Drupal core has strict version dependencies on third-party code.

Libraries API aims to be lenient with version dependencies, whereas /core/vendor REQUIRES a specific version to be there. Check out Libraries different version detection. Taking that into consideration, I vote for C and let Libraries API choose where to go.

tstoeckler’s picture

core/libraries
Should never exist as Drupal core has strict version dependencies on third-party code.

I strongly contest that. (Note that sun has a different view on this, I think, so my position is not the "official" Libraries API position, if there is one. :) )
As I wrote in #1400748: Proposal for unified namespace organization, this is a matter of consistency. How often in your live have you overwritten node module with sites/all/modules/node? Probably zero times. And while that is a nice-to-have feature, I think an important point is that you see (more or less!) the same directory structure in sites/all than you have in core. It just makes sense conceptually. And just like there is a use-case for overriding node.module, there is also a use-case for overriding the core jQuery. You just have to supply compatible core scripts for nothing to break. Since basically all of Drupal JS depends on jQuery you might think that is far-fetched. But then take jQuery UI. It is (almost?) not used in core, so upgrading right now shouldn't be a problem at all. So if you weren't familiar with the horribleness that is core/misc I think it would be quite intuitive to put a newer version in sites/all/libraries/jquery.ui and hope stuff to work.

pounard’s picture

Fair enough, the name still is bad, jQuery and CSS librairies are pure resources the browser can download, while the generic "libraries" word can be used for pretty much anything, from system libraries, PHP code, PECL or PEAR packages, JS and CSS frameworks, etc...

tstoeckler’s picture

Hmm... The distinction between client assets (JS/CSS) and server assets (PHP/...) is not something we do in Libraries API currently, but maybe that's not such a bad idea. Hmm...

robloach’s picture

Drupal Core actually has a strict version dependency on jQuery and jQuery UI. Managing it via hook_library_info() means that contrib can upgrade it (and update other dependencies accordingly), but Drupal Core still depends on a certain version of the vendors to be present.

@tstoeckler How often in your live have you overwritten node module with sites/all/modules/node?

This is actually possible now that #375397: Make Node module optional is in ;-).

@pounard Fair enough, the name still is bad, jQuery and CSS librairies are pure resources the browser can download, while the generic "libraries" word can be used for pretty much anything, from system libraries, PHP code, PECL or PEAR packages, JS and CSS frameworks, etc...

Not sure that distinction is important. A strict version dependency is a strict version dependency. You don't care whether the third party code is PHP, JavaScript, or CSS. Sometimes it can even include all three. All you care is that you know what is there, and that is why Drupal Core has strict version dependencies for its vendors.

One thing we could do is rename the /core/lib folder to maybe help reduce the confusion. Crell outlined a few options. The folder name does not matter as it's all just PSR-0 auto-loaded anyway.

Crell’s picture

We already bikeshedded the name to death. We need to stop renaming things at some point. Someone needs to timebox this discussion. catch, we need you!

tstoeckler’s picture

@Rob Loach: I still don't get the point you're trying to make. If I have a contrib module, that depends on an external library, that also has a strict version dependency. Just like core. And just like core, other modules may require other versions and I may update my module to work with a newer version, etc. You claim there is some fundamental difference between core and contrib, but I don't see what that is. The only difference I see is packaging (Drupal core pre-ships the library, whereas contrib doesn't), but that is an infrastructural problem, IMO.

robloach’s picture

Status: Active » Fixed
  • lib holds PHP classes for the project
  • vendor holds version controlled third-party vendor projects
  • libraries is a Drupal-ism, meant to holds third-party libraries and is version agnostic

If #1467126: PSR-0 namespace auto registration for modules goes though, you'll be able to use "lib" or "app" or "src" or whatever you want for your PSR-0 classes. In the end, it really doesn't matter. This is just Drupal trying to adopt to standards adopted by the majority of the PHP world outside of Drupal. We have to document this correctly, so if you could make sure documentation is headed in the right direction over at #1290658: Move all module-provided classes to PHP namespaces (PSR-0 or similar), and autoload them without the registry [policy, no patch], that would be great.

Setting this one to fixed.

tstoeckler’s picture

Status: Fixed » Active

Sorry guys, but this is not fixed.
To explain where I am coming from:
I would like to get drupal_get_path('library', 'jquery') into core (basically Libraries API 1.x) and that currently requires a core/libraries directory.

As stated above core/lib and core/libraries is a WTF.

There are a couple of solutions to this, one of them would be renaming 'lib' to something else, but that is not the only one. And since there is a lot of resistance against that, we should probably do something else. If that is the case (i.e. we leave 'lib' as is), this does not touch any PSR-0 debates at all, but this should be fixed in some way nonetheless.

We can of course decide to simply live with core/lib AND core/libraries, but that has not been really stated above AFAICT.

The obvious other solution would be to rename 'libraries' to something else. Libraries currently house JS, CSS and PHP. It was discussed elsewhere that we could maybe make a distinction between client-side and server-side. So put PHP classes in sites/all/vendor and JS/CSS in sites/all/assets or something. That is really just a proposal of the top of my head, and I don't know if it is all that good.

Long story short: This issue is not fixed.

pounard’s picture

"libraries" is not core, so I see no problem.

webchick’s picture

I think Libraries API just needs to switch to a "vendor" directory in D8. That's the decision that was reached in core about how to handle third-party upstream code, it's standard in other projects (both PHP and non-PHP). Our continued use of "libraries" is a Drupalism, and the fact that core uses /lib for "OO code belonging to this component" is an extra nail in its coffin.

webchick’s picture

But I agree with pounard, I'm not sure why this is a task in Drupal core. This is a task for Libraries API module. The decision in core has been made already.

jstoller’s picture

I see no conceptual problem with having both /core/lib and /core/libraries directories. Given the limited audience of people who should be poking around in the core directory, I don't expect it would be difficult to educate them on the difference. Just based on the connotations in my own head, "lib" sounds more like an internal code thing, while "library" sounds more like an external code thing. I wouldn't change either of those names.

Calling any directory "vendor" sounds wonky to me, but I give /core/vendor a pass, again given the limited audience of people who should be poking around in the core directory. That said, I would ask that we never have a /sites/all/vendor directory.

From a UX standpoint, the directories in /sites/all need to make sense, first and foremost, to real people. Not core developers. "Assets" sounds like it could contain anything. It is so general as to be confusing. Is that where I put my corporate logo? I mean, that's an asset, right? And as I said, "vendor" doesn't make sense at all to me. I just don't know what to put in there. "Libraries," on the other hand, makes perfect sense. The implication is that it contains things which are checked out from other places and can be referenced by code on this site. To me, that fits perfectly! Furthermore, I see no reason to separate server-side code from client-side code, unless it is absolutely necessary from a development standpoint. I don't think any site builders will care about mixing the two in one "libraries" directory, and I expect there could be some libraries that aren't easily classified as one or the other anyway.

Now, I'm getting a little out of my depth here, but if I understand what Rob Loach is saying, the things in /core/vendor cannot just be exchanged for a newer version without also enabling a module to deal with the dependencies built into Core. So, lets take that example of jquery (which presumably will be moving from /core/misc to /core/vendor). If I were to drop a new jquery.js in /sites/all/libraries and that automatically replaced the one in /core/vendor, then my site would break. I need to also enable something like jquery_update.module to handle the bits of Drupal core that depend on jquery and don't know how to deal with the new version. Given that, I agree with Rob that nothing in /sites/all/libraries should automatically override what is now being stored in /core/vendor. I'm not sure I'd go so far as to say there should never be a /core/libraries folder, but I agree it is unlikely.

I think there is a fundamental difference between replacing a core Drupal module with a contrib Drupal module, and replacing a third party library used by Drupal with an updated third party library. @tstoeckler, using your example, overriding node.module seems perfectly reasonable. The new node.module, itself being a Drupal module, can not only override functionality from the old node.module, but it can also deal with dependency issues in other parts of Drupal core. A new jquery.js cannot do that on its own. For any significant update, it needs jquery_update.module to keep things from blowing up. Therefore, I have no problem with disallowing direct drop-in replacements for third party libraries. I think it is reasonable to require a contrib module to recognize a third party library and replace the one in Core.

@tstoeckler: Forgive me if I'm missing something, but doesn't getting drupal_get_path('library', 'jquery') into core just mean updating drupal_get_filename() so it recognizes the "library" type? I assume that could be done in such a way that it would find things in /core/vendors, as well as in /sites/all/libraries. I don't understand why it would require a /core/libraries directory.

sun’s picture

As clarified in #1400748-122: Proposal for unified namespace organization already, PSR-0 and Libraries API are entirely different concepts.

To repeat #9 even more concise:

  • PSR-0: Autoloaded code natively shipped with packages. All dependent code that uses it expects a single version and incarnation only.
  • Libraries API: Code that is not shipped with packages. In an arbitrary version and incarnation. 1 to N otherwise independent extensions may depend on it. None of them can enforce a certain version without possibly breaking N-1 other extensions. That's why Libraries API turns it around, and requires API consumers of the library to be version/API-agnostic.

Libraries API is not really a Drupalism at its core - I'd rather say that the Drupal community is smart enough to attack the problem space (at all). Other systems will simply leave you with a fatal error to figure out yourself. The same applies to a possible sites/all/vendor PSR-0 directory, as any code in there will simply get loaded, no matter what. Thus, 3 extensions in your system might be compatible, but the other 13 are not. Because of that, I've become reluctant to that idea.

In the end, lib and libraries are entirely different concepts. However, we were able to cope with hook_library() and hook_libraries() in D7 already, so I don't think the mere directory name can be any worse. Especially since only "lib" appears in a particular extension - "libraries" only appears outside (e.g., sites/all/libraries).

pounard’s picture

Furthermore, I see no reason to separate server-side code from client-side code, unless it is absolutely necessary from a development standpoint.

For security, consistency, and because client code and server code are not the same thing, they must be separated. Whatever are the name of folders all PHP code files altogether should be considered as the Drupal binary while client code should be considered as physical files the browser can actually fetch, therefore they should always be separated by design. Current Drupal way is terrible because we cannot leave the PHP code outside of the webroot, which is an abberation.

Anyway, sun is right saying that the "libraries" folder, at least, live outside of server code, in the "sites/foo/libraries" folder and is by history physically separated of "core/vendor" and "core/lib" so there is actually no problems at all, this bikeshedding serves no purpose IMHO.

webchick’s picture

Good. So closed (works as designed) then?

Crell’s picture

pounard: Consider there are a number of 3rd party components that we could drop in (some WYSIWYG editors, for instance) that contain both PHP and JS code. Forcing those to get split up to fit our organizational pattern is a non-starter.

pounard’s picture

@Crell Those would probably take their place with client assets for packing related technical reasons. Moreover I'd argue that PHP files of WYSIWYG editors often are more like code sample or fallback for lazzy integrators. We may use such files, and we cannot split because we would break their packaging, this doesn't mean we have to to give up making our own code clean.

EDIT: Anyway, just sayin, "libraries" is not core, and "libraries" lives in the "sites/" folder, not in a theme or a module folder and it won't clash with "vendor" or "lib", so this bikeshed doesn't really have any sense living on core issues right now: keeping this chat is considering that "Library API" module is core, which it isn't. Continuing this issue is a containment issue because it actually taints the core issues, and that's bad. IMHO we should close it or get it into the "Library API" module retitled such as "Core now uses the lib folder, libraries folder name may be redundant with core".

klonos’s picture

...keeping this chat is considering that "Library API" module is core, which it isn't.

Not being core right now doesn't necessarily mean it won't ever be: #1167496: Libraries API in core

sun’s picture

Status: Active » Closed (won't fix)

Obsolete by now.