nikosdion / joomla_extensions_development

Joomla Extensions Development: a reference book
GNU Free Documentation License v1.3
11 stars 1 forks source link

Add a section on Libraries #4

Closed Irata closed 2 years ago

Irata commented 2 years ago

This is a request for an additional section explaining Libraries, my particular interest is how to install a Library that can be used by multiple extensions to do common tasks and be a part of the autoloader and having a namespace, however more useful background and understanding of Libraries in Joomla 4 would be good.

I have a particular issue with at the moment that I don't find even the basics to understand what I should be doing under Joomla 4. I have asked my question here, https://joomla.stackexchange.com/questions/32451/joola4-how-to-add-own-classes-to-libraries-vendor and the only documentation that I think should be relevant but isn't is this official doc, https://docs.joomla.org/J4.x:Namespace_Conventions_In_Joomla which I suspect should have another section on what namespace Libraries should have.

Thank you.

nikosdion commented 2 years ago

Libraries are glorified files packages which always install under the libraries folder.

Yes, you can register a namespace for your library packages. There is no convention to be used. This is by definition for a library. You use whichever prefix works for you but it makes sense to follow a convention similar to CompanyName\Library\LibraryName or CompanyName\LibraryName.

Beyond that, there is really nothing to document. Do you think it's worth it? I thought it follows. If you tell me it was unclear, sure, I'll add a section for this as well.

Regarding using Composer, don't mess with Joomla's Composer dependencies! I have already documented how to use Composer with your extension in https://www.dionysopoulos.me/book/advice-composer.html I believe I did that after last time you raised this subject.

Irata commented 2 years ago

I think it is something that does need some understanding and example(s) of how a 3rd party developer can add their libraries as the process is different to the Joomla 3 approach and one of the good aspects of your documentation is where you explain how/why things were done in Joomla 3 followed by how to do the same or more in Joomla 4.

I have finally managed to get something that works this morning by falling back to the usual method of finding another extension that was doing something similar and adapting their method to my own code. That in itself has shown me some of where I was going wrong and answered a few of my questions along with some of the hints you have shared with me.

Now that I have something that works I can change/break my code to see the affect to better understand the process and perhaps work out if the approach I have followed of the other developer is the best approach for my extension.

One aspect where I was getting things wrong was I was looking at a clean Joomla 4 installation, following what little I had been able to find for Joomla 4 and placing my actual library code in /libraries/vendor/ as the official documentation led me to believe that is where 3rd party libraries go in Joomla 4. I also wasn't seeing my entry, or any other entries, in autoload_psr4.php which had me looking for some other step in the process, like falling back to the Joomla 3 approach with registering the library via a plugin, which I was sure wasn't required, but still I was second guessing myself.

There are other things you have mentioned that I need to get my head around such as there is no convention for namespaces and that you imply namespaces are optional for libraries at least, but maybe that will be clearer once I understand the process better.

Yes you did set me straight on Compsoer earlier and I have read your recent addition on Composer in your documentation so I knew to stay away from it in this instance, thank you.

nikosdion commented 2 years ago

Neither library packages nor Composer dependencies work differently than Joomla 3. In Joomla 4 you can add a namespace to your library package (I need to confirm it actually works) whereas in Joomla 3 you shipped your own autoloader.

One aspect where I was getting things wrong was I was looking at a clean Joomla 4 installation, following what little I had been able to find for Joomla 4 and placing my actual library code in /libraries/vendor/ as the official documentation led me to believe

Nope, that's NOT what the documentation tells you. If anything, even contributors are told to not mess with this folder or the composer.json file (unless permission is given), and to never run composer update. The vendor folder is where third party dependencies pulled in through Composer are placed. Its autoloader is included as part of the boot process, hence no need to have anything in autoload_psr4.php which is only for extensions.

I also wasn't seeing my entry, or any other entries, in autoload_psr4.php which had me looking for some other step in the process, like falling back to the Joomla 3 approach with registering the library via a plugin, which I was sure wasn't required, but still I was second guessing myself.

Remember that there are three autoloaders in Joomla:

The first has been around since at least Joomla 1.5. The second has been in service since Joomla 3.2 or thereabouts, when Joomla started using Composer. The latter was introduced in Joomla 4.0.

You can understand all of that by going through Joomla's libraries/bootstrap.php file. That's the file which sets up the execution environment so anything at all can be loaded.

I will check if the library package does register a namespace. If it doesn't you will need to load the library either with a plugin (bad idea, your software can fail miserably if the user disables it) or by including a file. FOF was doing the latter; it preserved everyone's sanity.

There are other things you have mentioned that I need to get my head around such as there is no convention for namespaces and that you imply namespaces are optional for libraries at least, but maybe that will be clearer once I understand the process better.

Libraries are, by definition, their own thing. The only requirement is that their namespace doesn't clash with any of the code shipped with Joomla itself and other third party extensions. You CAN NOT enforce a namespace convention for libraries. People wouldn't follow it. They would just include their library as a Composer dependency in their plugin and we'd end up with library clashes which are even worse. Think about it.

The goal of namespaces in Joomla 4 is not to introduce a hard bureaucratic process which dissuades developers. To the contrary, it is meant to make developing software for Joomla easier by having the code in components, plugins, and modules load automatically without having to include specific files like we are stuck in 2001 or WordPress (which is apparently stuck in 2001 for the most part…).

Libraries are a special thing, they can have autoloading code or not. In many cases what I mentioned about Composer dependencies would need to be shared across multiple extensions by the same vendor. It doesn't make sense including the same dependencies in every extension. It is both a waste of space AND a source of trouble (you can't load two different classes with the same fully qualified name). It would therefore make more sense to ship that vendor folder as a library extension and have your other extensions load its autoloader (which is uniquely namespaced, automatically, when you run composer install when preparing your library for release). You wouldn't have Joomla load anything automatically, nor should you automatically load your Composer dependencies on every page load outside of your components which use them (because you could clash with other 3PDs using the same dependencies in THEIR components).

Irata commented 2 years ago

I can answer the part about Library package registering a name space, it does and it updates autoload_psr4.php, and that means it loads for me without the need for a separate plugin or any auto loader of my own which supports what you say about Joomla 4 making it easier, it just wasn't obvious how to do it.

The entry in the autoload_psr4.php when installing the Library extension is

'Bricks\\Library\\' => [JPATH_LIBRARIES . '/bricks/src'],

while these are the two lines in the manifest that are used to construct the above line.

    <libraryname>bricks</libraryname>
    <namespace path="src">Bricks\Library</namespace>
Irata commented 2 years ago

Thank you for including the section on Libraries.