-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpreface.xml
343 lines (314 loc) · 23.1 KB
/
preface.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright © 2022-2024 Nikolaos Dionysopoulos
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free
Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with
no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included
in the section entitled "GNU Free Documentation License".
-->
<preface
version="5.1" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:trans="http://docbook.org/ns/transclusion"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook"
xml:id="intro">
<title>Introduction</title>
<section xml:id="intro-about">
<title>About this book</title>
<para>I started writing this book in August 2022 as a quick reference
for myself and other third party developers writing Joomla 4 extensions,
or migrating our extensions to Joomla 4's native MVC.</para>
<para>While Joomla 4 has an amazing, rich and powerful architecture and
API it does not have any real developer-facing documentation. The
documentation you will find is outdated, chaotic and leaves you running
for your life.</para>
<para>I am making every effort to make this book approachable to all
levels of developers, from the novice who's barely hacked together their
first plugin to the seasoned expert with dozens of extensions under
their belt. However, to keep things relatively simple and because I am
doing this unpaid, on my limited free time, I decided to take a few
shortcuts here and there. I do not explain every concept in great
detail, I try to explain it in practical detail.</para>
<para>If you want to see what a real world Joomla extension looks like I
urge you to take a look at and dissect the Joomla 4 extensions my
company, Akeeba Ltd, has published free of charge. The simplest
component to start with is Akeeba ContactUs. The most complete
combination of a component, plugins and several modules we have
published is Akeeba Ticket System — even the free of charge version uses
most of the features I am describing in this book.</para>
<para>Hopefully, you will find my approach pragmatic and result-driven
instead of a dry, technical document. If you have suggestions for
improvement or would like to sponsor this work feel free to contact me
through the Contact Me page on <link
xlink:href="https://www.dionysopoulos.me">dionysopoulos.me</link>.</para>
</section>
<section xml:id="about-me">
<title>About the author</title>
<para><mediaobject>
<imageobject>
<imagedata fileref="https://www.gravatar.com/avatar/d8bb182ef0e061a3c4959a2d659e4252.jpg?s=256"/>
</imageobject>
</mediaobject>Hi, I am Nicholas. I am a Mechanical Engineer turned
Software Engineer. I am from and still live in Greece with my wife,
daughter and our two naughty cats.</para>
<para>I've been into computers since I was 11 years olds, at the dawn of
the 1990s. Back then dinosaurs were still walking among us, haircuts
were <emphasis>weird</emphasis>, personal computers were the size of a
small backpack and had <emphasis>far less</emphasis> computing power
than your average smart lightbulb. Only one of the previous statements
is false. I immediately took to programming for, as I said to my parents
at the time, “I want to learn how to make this machine do things for me
so I don't have to do them”. LIttle did I know what I was getting myself
into…</para>
<para>I've been using Joomla as a site integrator and extensions
developer since it was called Mambo, back in 2004. I wrote my first
mass-distributed extension called JoomlaPack in October 2006 while
taking a two week break from my day job at the time as a business
consultant. One thing led to another, JoomlaPack became Akeeba Backup
and I gave up on business consultancy and mechanical engineering to
become a full time software engineer.</para>
<para>I've been actively participating in the Joomla community since
2009. I am a regular Joomla contributor and not just writing code. I've
been involved in community outreach efforts and instigated the events
leading to the beginning of the Joomla 4 effort. I still contribute to
Joomla and, if I want to be honest with myself, I will continue doing
that until Joomla or myself is no more, whichever comes first.</para>
<para>I am neurodivergent (ADHD) and have a particular sense of humour.
I firmly believe that life's too short to take it seriously. You'll see
that a lot in this book. I don't care about writing a dry, boring book,
especially on a subject as dry and boring as writing software.</para>
</section>
<section xml:id="intro-j4-features">
<title>New Joomla 4 features at a glance</title>
<para>Joomla 4 is a smorgasbord of new features, improvements and much
needed changes. Unfortunately, a year into its release you'd be hard
pressed to find any kind of documentation of what these are and how they
can impact your software development practices. I will try to give you
the 30,000-feet overview of what <emphasis>I</emphasis> found to be the
most important changes.</para>
<para><link linkend="concepts-namespaces"><emphasis
role="bold">Namespaces</emphasis></link>. As you may remember, ever
since Joomla 3.3 the legacy class names (e.g. <code>JUri</code>) changed
to a namespaced equivalent (e.g. <code>Joomla\CMS\Uri\Uri</code>). In
Joomla 4 a lot of the legacy classes stopped working. You can find out
these changes neatly codified along with tools to mass convert your
extensions in my <link
xlink:href="http://github.com/nikosdion/joomlatypehints">Joomla Type
Hints</link> repository. In Joomla 4 the namespacing work went even
deeper, having all classes in components, modules, plugins and templates
also support namespaces — if you use the new, Joomla 4 API for
developing extensions. This is a game-changer concept! Namespaced
classes follow the <link
xlink:href="https://www.php-fig.org/psr/psr-4/">PSR-4</link>
specification. Joomla caches and registers the PSR-4 mappings between
namespace prefixes and directories on your site which means that
<emphasis>you can safely use any class of any extension anywhere without
having to use <code>include</code> or <code>require</code> ever
again</emphasis>. This greatly reduces the possibility for bugs and
massively improves the performance of Joomla and its extensions.</para>
<para><emphasis role="bold"><link
linkend="concepts-container">Dependency Injection Container / Service
Locator</link></emphasis>. Joomla 1.x to 3.x inclusive had this annoying
<link xlink:href="https://en.wikipedia.org/wiki/God_object">God
Object</link> called the Joomla Factory (<code>JFactory</code> or
<code>\Joomla\CMS\Factory</code>). It had a very opinionated approach on
instantiating all sorts of globally used services, from the application
itself, to the database, to the user objects, to the mailer object. If
you wanted to write Unit Tests for your extension — or Joomla itself —
it was the bane of your existence. In Joomla 4 we instead have a
Container. It is not a real <link
xlink:href="https://en.wikipedia.org/wiki/Dependency_injection">Dependency
Injection Container</link> as much as it is a <link
xlink:href="https://en.wikipedia.org/wiki/Service_locator_pattern">Service
Locator</link>, meaning that it won't magically instantiate an object
based on the type definitions in its class' constructor but it will let
you retrieve the services you need to inject to your objects. Each
extension — component, module, plugin and template — gets its own
service locator and its own extension object which uses it. This makes
it far easier to write unit tests for your code, especially your Models
(which is where most of your business logic, therefore your code that
needs testing, should already be).</para>
<para><link linkend="concepts-webassetmanager"><emphasis role="bold">Web
Asset Manager</emphasis></link>. In the past, whenever we wanted to load
a JavaScript or CSS file we'd have to load its dependencies and finally
our file. For example we might want to load jQuery, then load some
Bootstrap core JavaScript files, then our JavaScript file. Each
extension would do that and it lead to several chicken and egg problems.
What if file A from extension X depends on files B and C and file B from
extension Y depends on files C and D but D must be loaded before C?
Bummer. The Web Asset Manager codifies the dependencies in a way which
lets Joomla resolve them. It also lets you define alternative
dependencies,e.g. a different JavaScript file to load depending on
whether the user's browser supports <link
xlink:href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules">JavaScript
modules</link> or not, and asset groups, e.g. a collection of CSS and
JavaScript which are meant to be loaded together. This lets you split
your CSS and JavaScript into smaller files which load in the correct
order and improve the performance of your user's site.</para>
<para><emphasis role="bold"><link linkend="com-j3-vs-j4-mvc">A new
MVC</link></emphasis>. The MVC in Joomla 1.5 to 3.10 inclusive had
changed very little. Previous attempts to modernise it failed
ignominiously because they simultaneously failed to go far enough and
maintain <acronym>b/c</acronym> (backwards compatibility). Joomla 4 has
a new MVC model which is based on Dependency Injection and namespaces,
it is more prescriptive, more flexible and more powerful than its
predecessors. You can very easily extend a frontend model from a backend
model instead of writing the same code twice or doing a contortionist
act with PHP Traits. You can easily create custom HTML helpers without
calling static functions, use categories without writing precarious
database code, create object-oriented URL routers and much more which we
will explore in this book.</para>
<para><emphasis role="bold">Hide-able inline help</emphasis>. Remember
how Joomla 3 XML Forms looked like a word vomit with all the inline help
text (field descriptions) being always visible? This was a bad interface
for experienced users. At the same time, Joomla 4.0 removing all inline
help text made the interface inapproachable for newcomers and end
clients meant to use the site. With Joomla 4.1 it is now possible to
have hide-able inline help text in your forms and your component
configuration. The field descriptions are hidden by default and the user
can show them by clicking on the <guibutton>Show Inline Help</guibutton>
button in the interface. Now your extensions' interface can be
simultaneously approachable for both new and experienced users.</para>
<para><emphasis role="bold">Prepared statements</emphasis>. SQL
injection vulnerabilities have been almost <emphasis>de
rigueur</emphasis> for any web software, Joomla extensions being no
exception to that. Sure, Joomla does have some very nifty tools to get
filtered input and escape it when placed inside database queries but not
all input can be escaped sufficiently if you do not know its
<emphasis>type</emphasis> (integer, string, array of one or the other).
Moreover, despite best intentions, accidents can and do happen, e.g.
forgetting to escape one piece of input you assumed it's an integer but
it came through a path which never did check the input type nor did it
try to typecast it to an integer! Joomla 4 introduced <link
xlink:href="https://en.wikipedia.org/wiki/Prepared_statement">prepared
statements</link> which make these oversights and corner cases a thing
of the past. You tell the query builder where you expect potentially
user-originating data in your query, which data to use in there and what
type this data is. You are guaranteed safe execution without worrying
about SQL injection <emphasis>unless you try really hard</emphasis> to
NOT let Joomla use a prepared statement. On the flip side, there are a
few types of SQL queries which cannot execute in the context of prepared
statements and required some code contortion to execute.</para>
<para><link linkend="com-mailtemplates"><emphasis role="bold">Mail
templates</emphasis></link>. In the past there were two ways to handle
email for your extension. You could send plain text only email using
language strings OR you would have to invent your own email template
management. The former led to ugly email messages. The latter required
reinventing a very complex device on each and every of your components.
If you did not have a component, tough luck. Darn! Joomla 4's mail
templates feature allows your users to use the Joomla WYSIWYG editor to
create rich email templates with placeholders to be replaced by data
provided by your extension. This feature looks half-finished in Joomla 4
as it has no obvious way to register or update email templates. Don't
worry, though, we do have a way to work around its shortcomings,
complete with example code.</para>
<para><link linkend="com-scheduled-tasks"><emphasis
role="bold">Scheduled Tasks</emphasis></link>. Many extensions need to
periodically execute some kind of code. For example, sending email
newsletters, updating the prices of thousands of SKUs in an online shop
from an Excel or XML file, running backups, you name it! In the past we
had to reinvent the wheel on each extension we built. For example, we
created ‘special’ URLs in our components or through com_ajax to be
accessed with wget, cURL or a service like WebCRON.org periodically; or
we created CLI scripts to be used with CRON jobs. We almost always
offered more than one way to do things which led to a certain degree of
code duplication. In all cases, the user was responsible for setting up
CRON jobs or the equivalent on a third party service for every single
task they needed to be executed periodically. This was a tall ask!
Joomla 4.1 and later offers a new Scheduled Tasks feature which allows
users to select which tasks they want to be executed, when to execute
them and even configure their execution parameters — all within the
familiar Joomla user interface. It even lets the task scheduler to be
executed three ways: with a command line CRON job, a URL-based CRON job
or automatically based on visitor traffic (lazy scheduling). The end
user has to set up just the one CRON job or, if they are using lazy
scheduling, just flip a switch.</para>
<para><link linkend="com-cli"><emphasis role="bold">CLI
Application</emphasis></link>. In the past we had to create bespoke CLI
scripts for every task each of our extensions needed to allow to be
executed from a command line context, be it a CRON job or a manually
executed CLI helper tool. This required creating a new application and
contend with the two facts that a) the base class changed at least twice
in the last ten years and b) it lacked a lot of methods several core and
third party classes were expecting to be present. This led to a lot of
reinventing the wheel. The Joomla CLI Application is like a built-in
version of WordPress' WP-CLI or Drupal's Drush in that it's based on the
Symfony Console Components and can be easily extended using plugins
which register command classes. Used wisely, it can enhance your
extensions and help your advanced users who can use the CLI to automate
things around their site.</para>
<para><link linkend="com-api"><emphasis role="bold">API
Application</emphasis></link>. Joomla has historically been an HTML-only
application. Yes, sure, you can have JSON, XML, Feed and Raw views but
they feel bolted onto the HTML application; they are not a real API to
your component. Joomla 4 introduced a brand-new application, the
ApiApplication which lives in the <filename>api</filename> directory of
your site. For now it's only accessible to Super Users but it provides a
real RESTful JSON-based API to components which integrate with it.
Integrating your component with the API application is as easy as
creating a Web Services plugin and adding a few easy to create
controllers and views in the API part of your component. That is to say,
your component now has a backend, a frontend and an API side. You don't
<emphasis>have</emphasis> to integrate with the API application but if
you have something which could benefit from automation it is strongly
encouraged to do so.</para>
<para><emphasis role="bold">Dashboards</emphasis>. Between Joomla 1.0
and 3.10 inclusive Joomla only ever offered one dashboard, the main
Control Panel page which loaded when you logged into your site's
backend. In Joomla 1.0 to 1.6 it was hard-coded and inflexible. I added
the ability to use plugins to render custom action buttons in Joomla
1.7, based on my experience with my software. Starting with Joomla 3.0
you could now publish <emphasis>modules</emphasis> to add information
panes to the Control Panel dashboard. If you wanted the same experience
in your extension… tough luck. You would have to reinvent the wheel.
Joomla 4.0 and later allow you to set up <emphasis>one or more dashboard
pages for your own component</emphasis> which appear in the Joomla menu
structure, under your component's menu item, and where you and your end
users can publish any number of modules.</para>
<para><emphasis role="bold">Layouts everywhere</emphasis>. A lot of the
HTML generated by Joomla, even throughout version 3, was statically
coded in the PHP files implementing the business logic, making any kind
of customisation impossible (or, at the very least, requiring a very
judicious application of in-memory code editing, buffer stream wrappers
and Reflection). Let's just say that if you disagreed with how a certain
form field or HTML helper rendered its HTML you were out of luck.
Layouts were introduced in Joomla 3.4 and later versions did make better
use of them in various places but you still had to contend with several
of the same issues. Not anymore! Joomla 4 uses layouts for every kind of
HTML output. If you want to override how some core code renders in your
component or your template you can easily do that by overriding the
layout. Likewise, you are encouraged to use Layouts everywhere you have
reusable HTML output in your extensions to make it easier for end users
to override them in their template.</para>
<para><emphasis role="bold">Media options per component</emphasis>.
Joomla 3.4 introduced an upload checker for all uploaded files based on
the work I had done in Admin Tools. This was a massive leap in security
as we codified the basic upload checks and encapsulated them in a way
that made them run automatically whenever you were handling uploads.
However, this was controlled by the Media component's
(<code>com_media</code>) settings. This was great if your extension only
ever needed static media files to be uploaded. If you wanted to allow
your users to upload non-media files, or files otherwise not acceptable
anywhere else <code>com_media</code> was exposed, such as ZIP, 7Z, and
RAR files in a helpdesk component, you had to modify the Media options,
allowing these files <emphasis>everywhere</emphasis>. The unfortunate
solution to that was that third party component developers chose to
<emphasis>disable</emphasis> the upload checks, undoing the security
improvements we added in Joomla 3.4. This is no longer the case! Joomla
4 allows each component to have its own, private copy of Media settings
for its own uploads. Any upload being handled by your component (not
<code>com_media</code>!) will have these private settings applied. It's
a bit of a chore BUT it lets you provide a much safer option for
uploading files through your extension.</para>
<para>There are many more improvements which I will not cover in this
book. If you found out something cool and you'd like me to write a
section for it, please do let me know. I can't promise it will
definitely make it into the book but I will at least promise to give it
a good thought and most likely a good try.</para>
</section>
</preface>