IntroductionWelcome| 00:04 | Hi! This is Joe LeBlanc with Joomla! 1.7
| | 00:06 | Programming and Packaging Extensions.
| | 00:09 | In this course we will walk through how
to install minimal extensions, create a
| | 00:14 | backend's interface, filter database
results, configure development tools, make
| | 00:20 | URLs human readable, and translate the
user interface, and we will also build
| | 00:26 | the custom component, a module, a
language file and, several plug-ins.
| | 00:30 | Then we will package the final codes
to its installable on any Joomla site.
| | 00:35 | Let's start writing some extensions.
| | Collapse this transcript |
| Course overview| 00:00 | This course is designed to take you
through the creation of a module, component,
| | 00:04 | and several plug-ins for Joomla
| | 00:06 | We will start by installing some extensions
with the bare minimum code necessary to run.
| | 00:10 | After that the extensions will be built
piece by piece until they're fully featured.
| | 00:14 | We're building codes for the Explore
California tourism agency's web site.
| | 00:19 | All tours are organized by activity
and each tour location is shown on a map.
| | 00:24 | The data for each activity is edited
in a standardized form in the backend.
| | 00:28 | Users will be able to login and
keep track of their favorite tours.
| | 00:33 | The site will also have
sidebars to promote the tours.
| | 00:36 | Once these extensions are complete,
Explore California will have everything it
| | 00:40 | needs to manage the web site.
| | Collapse this transcript |
| Taking this course| 00:00 | This course starts with several base Joomla
| | 00:02 | extensions then builds them by piece by piece.
| | 00:05 | Consequently, it's necessary to install
the base extensions first, then proceed
| | 00:08 | with the rest of the course.
| | 00:09 | You can skip between chapters, but
only after installing the base components.
| | 00:13 | You will want to set up your Joomla
| | 00:14 | installation in a specific way to
get the most out of this course.
| | 00:19 | First, you need a copy
of PHP, MySQL, and Apache.
| | 00:23 | If you're using Windows you could use XAMPP
and if you are using Mac you can use MAMP.
| | 00:28 | If you need to learn how to install
XAMPP or MAMP take the installing Apache,
| | 00:32 | MySQL, and PHP Online Training Library Course.
| | 00:37 | Next, we want to install a fresh copy of Joomla
| | 00:40 | When you install this copy of Joomla
| | 00:42 | make sure to set the
Database Table Prefix to jos_.
| | 00:47 | This will allow you to use the Exercise Files.
| | 00:50 | Also, be sure to install Joomla
| | 00:52 | without the sample data. With Joomla
| | 00:54 | installed all you need to do to
continue is install the base extensions.
| | 00:58 | They are available to everyone
as a free download from lynda.com.
| | 01:01 | We will be covering installing
these extensions in another video.
| | 01:04 | In the next video we will be
covering special instructions for using
| | 01:07 | the Exercise Files.
| | Collapse this transcript |
| Using the exercise files| 00:00 | Joseph LeBlanc's course on
Programming Joomla Extensions comes with three
| | 00:04 | sets of Exercise Files.
| | 00:07 | The Free Exercise Files folder
contains a beginning extension for all
| | 00:11 | lynda.com users to download.
| | 00:14 | The beginning extensions give you a
place to start in the course and then build
| | 00:18 | on it as the course proceeds.
| | 00:20 | Their installation is covered in another movie.
| | 00:24 | The Exercise Files for Premium
subscribers to lynda.com contain two separate
| | 00:29 | folder, one for Joomla 1.
7 and one for Joomla 2.5.
| | 00:34 | These folders contain files
for each chapter and each movie.
| | 00:40 | This arrangement assumes that you're
going to take the course in sequence
| | 00:45 | all the way through.
| | 00:47 | If, however, you wish to jump ahead,
then you'll need to update the code and to
| | 00:52 | do this you use the explore
folder that resides in each chapter.
| | 00:57 | It contains the code as of
the ending of the prior chapter.
| | 01:01 | So, for example, if you wanted to go
directly to the last chapter, Chapter 17
| | 01:06 | here, then you would use this
folder to update the extension.
| | 01:11 | In the Mac world here's how you would do that.
| | 01:14 | Open Terminal and then you need to set
your path to that explore folder, the one
| | 01:19 | that you're going to copy.
| | 01:21 | Then you use the cp command to merge
these folders into the like-named folders
| | 01:26 | in the extension and hit
Enter. And you're done.
| | 01:29 | The files are now in the proper
state for you to begin Chapter 17.
| | 01:34 | In the Windows world you simply take
these folders and drop them into the
| | 01:38 | explore folder in the
extension and select merge.
| | 01:43 | Now come back to this movie.
| | 01:45 | Now that we've restored the file
system, let's just store the database.
| | 01:48 | There is an explore.sql file for every movie
that has significant changes to the database.
| | 01:55 | In our example it's here in the
Packaging your extensions folder.
| | 01:59 | You need to upload this file through
phpPMyAdmin to get your Joomla to the
| | 02:04 | correct starting point.
| | 02:06 | Let's restore it now.
| | 02:07 | From phpPMyAdmin select the
database for your Joomla installation and
| | 02:12 | click Import and browse.
| | 02:14 | Go to the Exercise Files and upload the
explore.sql file for the video that you
| | 02:20 | wish to restore and then click Go.
| | 02:23 | You could see here that the
import has been successful.
| | 02:26 | Now go back to the front end of
your Joomla site and hit Refresh.
| | 02:30 | Your database is now set to the correct state.
| | 02:33 | Remember, if you are using database dumps,
you'll need to make sure you're using
| | 02:36 | the ones designed for your version of Joomla.
| | 02:39 | If you use the Joomla 1.7 dumps on a
Joomla 2.5 installation, you will notice
| | 02:45 | inconsistencies in the user
interface, among other possible glitches.
| | 02:50 | If this happens, simply repeat the database
import process using the Joomla 2.5 files.
| | 02:56 | Finally, make sure that the jos_
is the database table prefix in your
| | 03:03 | installation and you'll be all set to go.
| | Collapse this transcript |
|
|
1. Understanding the Joomla! Structure and FrameworkReviewing Joomla! applications| 00:01 | While most people know Joomla
| | 00:01 | as a content management system, Joomla
| | 00:03 | is also a platform where any
number of applications can sit on top.
| | 00:08 | Let's take a look at three
that are prepackaged with the CMS.
| | 00:11 | So first go to the root of
a fresh copy of a Joomla
| | 00:14 | installation and open up index.php.
| | 00:19 | So you will notice down here we are
calling the getApplication function on
| | 00:22 | JFactory and the site
parameter is being passed in.
| | 00:27 | JFactory::getApplication
loads the application in Joomla
| | 00:31 | that is going to be run and the
one for the front end is called site.
| | 00:35 | So the one that runs from index.
php at the root of the Joomla
| | 00:39 | installation is the front end site application.
| | 00:43 | If we go back to administrator,
there is another index.php file.
| | 00:51 | Down here again we are calling
getApplication out of the JFactory class, but
| | 00:55 | this time we are passing
administrator in as the parameter.
| | 00:58 | So this way there is a completely
separate backend from the front end.
| | 01:03 | Then finally if we go back up a level
and then go to the installation folder,
| | 01:08 | open up the index.php file there.
| | 01:13 | If you scroll down all the way to the
bottom you will notice there is yet one
| | 01:16 | more call to getApplication.
| | 01:18 | This time installation is being passed in.
| | 01:21 | The installation application is an
application that helps you can install the Joomla
| | 01:25 | CMS for the first time, and then
you completely remove the installation
| | 01:30 | application once it's done.
| | 01:32 | So after installation, the site and
administrator applications are the ones you
| | 01:36 | are going to work with the most.
| | 01:38 | Whenever you're inside a PHP
file that's running within Joomla
| | 01:41 | you can always tell which
application you're running.
| | 01:44 | To do this, bring in the
application object and then call the isAdmin
| | 01:50 | function on that object.
| | 01:53 | So in this case, we are detecting
whether or not we are we are running the
| | 01:55 | administrator application and if we
could either bail out of this code or do
| | 02:01 | something else as opposed to if
we were running the front end.
| | 02:04 | In addition to the front end and the
backend applications it's also possible to
| | 02:08 | start with the Joomla
| | 02:09 | platform and build your own applications.
| | 02:12 | While that's beyond the scope of
this course, it's definitely something
| | 02:15 | that's worth looking into.
| | 02:16 | Knowing the difference between the
applications will help you run your code
| | 02:19 | in the right place.
| | 02:20 | It may also inspire you to release your own
custom applications based solely on the Joomla
| | 02:24 | platform.
| | Collapse this transcript |
| Defining extension types| 00:00 | Joomla is designed in such a way that you
never have to touch the core files.
| | 00:04 | Aiding in this, Joomla
| | 00:06 | provides five different types of
extensions giving you a wide range of
| | 00:09 | control over how Joomla
| | 00:10 | loads and executes.
| | 00:12 | It's possible to write all five
types of extensions for both the site and
| | 00:15 | administrator applications of Joomla
| | 00:17 | First, there are components.
| | 00:19 | One, exactly one and only one
component loads per each page load in Joomla
| | 00:26 | Components can be very complex and
they're designed to manage records in
| | 00:30 | the database primarily.
| | 00:32 | A good example of a component that you're
probably familiar with is the content component.
| | 00:37 | The content component manages articles in the
database and then displays them in the front end.
| | 00:43 | The next extension type is templates.
| | 00:46 | Templates control the overall
look and feel of your Joomla site.
| | 00:50 | You can only assign one template per page.
| | 00:52 | However, you can have different
templates for different pages.
| | 00:56 | After the templates we have modules.
| | 00:58 | Modules typically make up the sidebars and
the headers and the footers of your web site.
| | 01:02 | Your template will provide multiple
positions for your modules and your modules
| | 01:06 | will have menus and login boxes and
pieces of content that you wanted to display
| | 01:11 | alongside your component.
| | 01:13 | Next, we have plug-ins.
| | 01:15 | Plug-ins typically run in
the background of Joomla
| | 01:17 | They don't always necessarily have a
visual element to them, however you can use
| | 01:22 | them to do things like search and replace
text on the output of your Joomla site.
| | 01:26 | They can also do things like
help you log into your Joomla
| | 01:29 | site and they typically just stay in the
background and wait for a certain event
| | 01:33 | to occur and then just react to that event.
| | 01:36 | Finally, we have language packs.
| | 01:38 | Notice the You are here
message that appears next to Home.
| | 01:42 | This is a user interface
element that Joomla can translate.
| | 01:47 | Notice now that the You are here
message has been translated into French.
| | 01:51 | However, the Home item is still in English.
| | 01:55 | This is because Joomla
| | 01:56 | only translates the user interface
elements and does not translate your content.
| | 02:01 | Let's take a look at this language pack.
| | 02:04 | When you write code for Joomla
| | 02:05 | you can write it as one of these five
extension types without ever touching the
| | 02:08 | code that comes with Joomla
| | 02:10 | In this course we will build a component, a
module, a language file and several plug-ins.
| | 02:14 | For template creation check out Jen
Kramer's Online Trading Library title on
| | 02:18 | Creating and Editing Custom Templates.
| | 02:20 | In the meantime let's start coding.
| | Collapse this transcript |
| Understanding how Joomla! buffers content| 00:00 | In very simple PHP applications, many
people will choose to execute their code
| | 00:05 | in the order the results appear on the screen.
| | 00:07 | On the other hand Joomla
| | 00:08 | runs each module and components separately,
then assembles everything into the template.
| | 00:13 | Let's take a look at some
of the output that Joomla
| | 00:15 | is generating and how it
gets all assembled together.
| | 00:18 | This is the root folder of our
fresh copy of Joomla and first Joomla
| | 00:22 | is going to execute a component.
| | 00:24 | The most common component that's used in Joomla
| | 00:27 | is the content component.
| | 00:28 | So if we go down here to the views folder,
this is where all the output from the
| | 00:32 | content component is going to be generated.
| | 00:34 | If we were viewing a single article,
there is a default.php file under the tmpl
| | 00:39 | folder and that's where the markup for the
article is going to be output. So as Joomla
| | 00:44 | runs the component it's going to load
this default.php file and it's just going
| | 00:48 | to grab all of the output from this
file as Joomla parses through it.
| | 00:53 | Now its not going to display it right
away, it's going to hold it in a PHP
| | 00:57 | output buffer and then save it until
it's ready to display. So after Joomla
| | 01:02 | is done running the component,
next it's going to run the module.
| | 01:06 | So we are going to have the login
module on most of our pages and just like the
| | 01:10 | component the mod_login folder has a
tmpl folder and inside that tmpl folder is
| | 01:16 | another default.php file.
| | 01:18 | This default.php file has all of the markup
that's necessary to generate the login module.
| | 01:23 | And again Joomla
| | 01:24 | is going to run this module, it's
going to gather up all the output that this
| | 01:28 | file is generating and it's going to save it
until it's ready to display it. So finally Joomla
| | 01:34 | loads the template.
| | 01:35 | If we scroll down here to the templates
and take a look at the atomic template,
| | 01:39 | in index.php there are placeholders for
the modules as well as for the component
| | 01:45 | and at this point Joomla
| | 01:47 | is also going to pull in any JavaScript
or CSS files that have been added during
| | 01:52 | the execution of the component in the
modules and it's going to add those CSS
| | 01:57 | and JavaScript files right here in the jdoc:
include type="head" element. And then Joomla
| | 02:03 | is going to backfill all of the module
content and all of the component content
| | 02:07 | into these placeholders.
| | 02:09 | Then finally once it's assembled all
of the content in the template, it still
| | 02:13 | hasn't sent it to the browser yet.
| | 02:15 | After the template has all of the
content assembled inside of it, Joomla
| | 02:19 | is going to output everything
here at the bottom of index.php.
| | 02:24 | So none of the output goes to the browser
before everything has been assembled. Joomla
| | 02:29 | assembles all of the pieces together,
and then it finally echoes everything out
| | 02:32 | at the end, and then you'll notice that
there's an on afterRender event here. Once Joomla
| | 02:37 | has all of the content in place you
have one last chance where you can go
| | 02:42 | and modify that output.
| | 02:43 | Joomla's output buffering makes it
possible to handle output in incremental
| | 02:47 | pieces and if all else fails you
always have one last chance to modify the
| | 02:52 | output before it goes to the browser.
| | Collapse this transcript |
| Understanding the execution flow| 00:01 | When any single request is made to Joomla
| | 00:03 | it always loads and
executes in the same pattern.
| | 00:05 | Once you know how this pattern works
you can make the right decisions on how to
| | 00:09 | design your extensions.
| | 00:11 | So all requests in Joomla
| | 00:13 | either go to index.php at the root,
or they go to the index.php file in the
| | 00:18 | administrator folder.
| | 00:19 | In this case, we're going to take a look at
the index.php file at the root. So first Joomla
| | 00:25 | loads what's known as the bootstrap code.
| | 00:28 | This code is going to load the
configuration file and get the database started
| | 00:33 | and do a few other things to get
everything in place, so that Joomla
| | 00:36 | can execute the rest of the code.
| | 00:38 | Then comes the application which is initialized.
| | 00:41 | In this case, we're getting the site
application and we're just getting it
| | 00:45 | started so that we can begin to
run code on the front end of Joomla
| | 00:50 | Next the application is routed.
| | 00:52 | The router is going to take a look at
the URL that's being passed into Joomla
| | 00:56 | and decide what code it needs to run after that.
| | 00:59 | After the application is routed then Joomla
| | 01:02 | dispatches the application.
| | 01:04 | In this step Joomla
| | 01:06 | is running the component and all the modules.
| | 01:08 | So it's going to run the login module
and the menu modules and it's going to run
| | 01:13 | the component that's going to generate
the article that's going to be displayed.
| | 01:17 | And it's going to gather all the output
from all these different pieces and just
| | 01:22 | hold them in memory for a little bit.
| | 01:24 | Then finally, after it has all the
output from all the different components
| | 01:28 | and modules Joomla
| | 01:30 | is going to load up the template and
then backfill all of the placeholders for
| | 01:34 | the module positions and the component.
| | 01:37 | So now right before the output goes
back to the browser we have one last chance
| | 01:42 | to make any modifications we want.
| | 01:44 | And then finally the output from the
application is sent back to the browser.
| | 01:48 | Even if you want to build something
simple with no template, still go through
| | 01:52 | index.php rather than build your own PHP script.
| | 01:55 | For security it's important that
all PHP requests go through Joomla
| | 01:59 | and not directly to individual scripts.
| | 02:01 | This course will cover techniques for
suppressing the template and getting raw
| | 02:05 | data when you want to
generate output like JSON or XML.
| | 02:08 | Joomla's standard execution flow
gives you ample opportunity for adding code
| | 02:13 | at strategic points.
| | 02:14 | When you understand how Joomla
| | 02:15 | executes you can avoid
needless hacks and workarounds.
| | Collapse this transcript |
|
|
2. Using the Joomla! Coding ToolsChoosing coding tools| 00:00 | When you're editing source code it's
easy to get lost in a sea of unfamiliar
| | 00:04 | syntax, run-on lines, and confusing conventions.
| | 00:07 | Fortunately, a code editor that's aware
of the programming language you're using
| | 00:11 | can be extremely helpful.
| | 00:13 | Now I'm going to show you TextMate,
it is the text editor that I prefer to
| | 00:17 | use on a Macintosh and you can find similar
free alternatives as well as ones for Windows.
| | 00:22 | So first I'm going to take a look
at the PHP context for TextMate.
| | 00:27 | So you can go down here to the bottom of
the screen and you'll notice that there
| | 00:31 | is a pop-up menu here with many
different programming languages and the one that
| | 00:36 | we're going to pick is
not PHP, but actually HTML.
| | 00:39 | What's good about TextMate is that it
will highlight both the HTML and the
| | 00:44 | PHP as you type it.
| | 00:46 | So if I start off with an HTML
document like this, I can just go into PHP.
| | 00:51 | So I hit PHP and hit Tab and it just
pops open the open and close tags for PHP.
| | 00:59 | So first I'm going to type in some
functions and some classes here just to show
| | 01:03 | how the syntax highlighting works.
| | 01:05 | So I'm typing in function and as
soon as I type in the word function out
| | 01:09 | completely it changes that from red to blue,
and then I can type in the function name.
| | 01:13 | I will type in function1 and you'll
notice that that keeps it Red, because
| | 01:18 | that's the name of the function.
| | 01:21 | However, when I begin to type in the
parentheses that make up the function
| | 01:25 | signature there it changes that to a dark blue.
| | 01:29 | We can use some other keywords here
like class and again it will have it in red
| | 01:35 | until I type it out in full.
| | 01:38 | And notice that the name of the
class is underlined when I type it out.
| | 01:42 | In addition to syntax highlighting TextMate
has features where you have Tab completion.
| | 01:48 | So if I just typing letters fun and
then hit Tab it automatically knows that I
| | 01:52 | want to write a function.
| | 01:54 | If I'm doing this within the context
of an object I would want to specify
| | 01:57 | whether it's a public function or a
private one, but I can just Backspace
| | 02:01 | this and hit Tab again, and then it
brings me right to where I want to type
| | 02:05 | in the function name.
| | 02:06 | If I type Tab once more it will bring
me to the argument list and if I hit Tab
| | 02:12 | one more time it brings me
into the body of the function.
| | 02:15 | And there is Tab
completion for the foreach loop.
| | 02:20 | And again it just has Tab stops at
every variable that I need to change.
| | 02:24 | Let's also take a look at how
TextMate will interpret an existing PHP file.
| | 02:29 | This is a PHP file that is included with Joomla
| | 02:33 | and it is very large.
| | 02:35 | It is a code that is used to connect to
the database and you'll notice that we
| | 02:40 | start off with a class with different
properties and the class also has several
| | 02:45 | different functions inside, and this
can be very, very confusing to navigate if
| | 02:50 | you don't know your way around this file.
| | 02:52 | So you'll notice that TextMate has
parsed out not only the name of the database
| | 02:57 | class, but also the name of all the functions.
| | 03:00 | So if there is a function that you
know that is in this class and you want to
| | 03:03 | navigate to it just pick it from the list
and TextMate will automatically take you there.
| | 03:09 | While I'm using TextMate some people
will prefer an Integrated Development
| | 03:12 | Environment, an example of one is Eclipse.
| | 03:16 | An Integrated Development Environment
will have a debugger and other tools that
| | 03:21 | will make it easier for you to write PHP code.
| | 03:24 | I personally find integrated
development environments to be a little bit
| | 03:27 | heavy and sometimes cluttered, but
they still provide the syntax highlighting
| | 03:31 | that I like as well as additional tools that
can make it easier for you to write PHP code.
| | 03:36 | So it's going to good idea to pick up
a good text editor like TextMate, or
| | 03:41 | an Integrated Development Environment
and try both and see which one you're
| | 03:44 | more comfortable with.
| | 03:46 | For the rest of this course,
I'll be using TextMate.
| | 03:48 | A code-aware text editor, or IDE is one
of the most important things to have in
| | 03:52 | your programming toolkit.
| | 03:54 | Syntax highlighting can help you avoid
making mistakes while keyboard shortcuts
| | 03:58 | can call up code in an instant.
| | Collapse this transcript |
| Setting the PHP configuration| 00:00 | Before you start developing PHP
code it's a good idea to check your PHP
| | 00:04 | configuration first.
| | 00:06 | There are few settings that can help
you find and fix bugs more quickly.
| | 00:09 | Since I'm using MAMP, I'm going to open up the
MAMP folder and then go to the htdocs folder.
| | 00:14 | This is the root web folder.
| | 00:17 | Next, I'm going to copy in phpinfo.php.
| | 00:21 | I'm going to use this file to help me
find the PHP configuration file, and
| | 00:26 | you'll notice in this file it's just
an open PHP tag and the command phpinfo.
| | 00:32 | Now I'm going to go to phpinfo in my browser.
| | 00:35 | So you'll notice on this line there is
a section for Loaded Configuration File,
| | 00:40 | it's pointing to /
Applications/MAMP/conf/php5.3/php.ini.
| | 00:47 | This is the PHP configuration file that's been
loaded, so this is the one that I need to change.
| | 00:52 | I'm going to go back to the htdocs
folder and remove the phpinfo.php file.
| | 00:57 | Now let's go to the php.ini file.
| | 01:02 | Go to the conf folder and go to php5.3.
| | 01:05 | Now I'm going to open php.ini.
| | 01:08 | Now look for a setting called error_reporting.
| | 01:11 | Whenever you're running PHP as a
development environment you want to make sure
| | 01:15 | that error_reporting is set to E_ALL.
| | 01:18 | If you don't have error_reporting set
to E_ALL, you won't get all the errors
| | 01:23 | that PHP is generating.
| | 01:25 | PHP will generate a level of error
called a notice, and that will occur whenever
| | 01:30 | you do something like output a
variable that hasn't been set yet.
| | 01:34 | While this isn't a hard and fast
error, it is a bad programming practice.
| | 01:39 | So setting error_reporting to E_ALL
will make noise whenever that happens.
| | 01:45 | Next you're going to want
to set display_errors to on.
| | 01:48 | Now to demonstrate why we want to have
display_errors on I'm going to load up
| | 01:53 | a file that has an error in it
and show what happens when you have
| | 01:56 | display_errors off.
| | 01:58 | Go to the Exercise Files and copy
broken.php and we're going to go back to that
| | 02:04 | htdocs folder and just paste
broken.php into that folder.
| | 02:10 | So you'll notice here I have
function1, function2, and function3.
| | 02:16 | I'm calling function1 which calls
function2 which calls function3 which calls
| | 02:22 | function4, which doesn't exist.
| | 02:24 | So that's going to cause an error.
| | 02:26 | However, if I go to that PHP script right
now, you'll notice that nothing displays.
| | 02:32 | It just displays a blank page and we
have no way of knowing what's going on.
| | 02:37 | So let's change the PHP configuration so
that it gives us an error message on screen.
| | 02:43 | Set display_errors to On and then save
the php.ini file and then restart MAMP.
| | 02:54 | After MAMP has been restarted, Refresh the page.
| | 02:56 | You'll notice now it's giving us Fatal error:
| | 03:00 | Call to undefined function function4.
| | 03:02 | This is much more helpful when you're
writing your PHP code than when you're
| | 03:05 | running it in production.
| | 03:07 | In addition to displaying errors there
is another level that we can take it if
| | 03:11 | you have an extension installed called xdebug.
| | 03:14 | Go back to php.ini and
scroll down to the bottom.
| | 03:17 | While the xdebug extension is pre-installed
with MAMP you may have to install it
| | 03:22 | on your PHP installation.
| | 03:24 | I'm going to uncomment this line
and this will enable xdebug in MAMP.
| | 03:29 | Now save php.ini and restart MAMP.
| | 03:33 | Now let's go back to the
browser and hit Refresh.
| | 03:36 | So now you'll notice we get a little
bit more of a detailed error report.
| | 03:41 | It's showing not only which line it
had the error, but it's giving us a full
| | 03:45 | stack trace of what happened.
| | 03:47 | So it's showing that we started
off in the main file, then we called
| | 03:51 | function1, then we called function2,
and then we called function3 and that's
| | 03:56 | where we hit the error.
| | 03:58 | You can mix and match your php.ini
configuration for the settings that work for you.
| | 04:03 | I'm going to revert everything back
to the MAMP standard php.ini file.
| | Collapse this transcript |
| Inspecting Joomla! output| 00:00 | While there are tools that can help
your PHP development debuggers and
| | 00:03 | inspectors on the browser side
are now also a part of any web
| | 00:07 | developer's toolkit.
| | 00:08 | Let's take a look at the Firebug
extension for Firefox as well as the
| | 00:11 | Inspector in Safari.
| | 00:13 | Firebug is a free download from
getfirebug.com and it installs this toolbar
| | 00:17 | button on the right-hand side of the screen.
| | 00:22 | Now you'll notice we have a console
here that's already telling us a few errors
| | 00:25 | that we have with this site.
| | 00:27 | We've removed the print.css file, but Joomla
| | 00:30 | is still referring to it.
| | 00:32 | So any missing assets like this
are going to show in the console.
| | 00:36 | They're also going to show in this Net tab.
| | 00:39 | So for instance, if we click on All this
will show all of the HTTP requests that
| | 00:43 | Firefox is trying to make.
| | 00:45 | It will highlight any missing assets in
red and also show the HTTP response code.
| | 00:51 | Another thing that you can do with
Firebug is inspect your HTML source.
| | 00:56 | So for instance, if we want to see HTML
markup that's generating this header we
| | 01:00 | can right-click on it and choose Inspect
Element and that will bring us right to the header.
| | 01:05 | We can also adjust the CSS
that is styling this header.
| | 01:10 | So for instance, if we want to remove
this padding we can just remove this line.
| | 01:16 | We can also add lines.
| | 01:17 | So for instance, if I wanted to make
the font bigger I could say font-size
| | 01:23 | and set that to 3ems.
| | 01:24 | I can also remove that by just clicking this.
| | 01:30 | You can also use the Console
to run JavaScript on the fly.
| | 01:35 | Click on this button on the right-hand
side and just type in some JavaScript.
| | 01:43 | Then click Run and you can see that we
can generate an alert just by typing it
| | 01:48 | in and clicking the Run button.
| | 01:50 | This will have access to all the
JavaScript variables that have been
| | 01:53 | initialized, so you can use this
to debug things without necessarily
| | 01:56 | refreshing the page.
| | 01:58 | Also notice on the Net tab
that there is an XHR section.
| | 02:01 | What this will do is whenever you're
making an asynchronous JavaScript request
| | 02:05 | it will appear down here on a line and
then when the response comes back from
| | 02:09 | the server you'll be able to see
exactly what output the server sent.
| | 02:14 | So for instance, if this JavaScript
file was retrieved during an asynchronous
| | 02:18 | request we would be able to browse
the Response that came back from the
| | 02:21 | server on this tab.
| | 02:23 | Now Firefox is not the only browser
that has an inspector like this, all of
| | 02:27 | the major browsers now have an inspector you
can use to debug the front end of your site.
| | 02:33 | Let's take a look at the Inspector in Safari.
| | 02:36 | Go to the Safari menu and open up
Preferences then click on the Advanced tab and
| | 02:41 | check off Show Develop menu in menu bar.
| | 02:45 | Then choose Show Web
Inspector from the Develop menu.
| | 02:49 | You'll notice that it's very similar to Firebug.
| | 02:52 | You can Inspect Elements and there
is a Console that shows when you have
| | 02:58 | missing assets, and just like Firebug
it lists all the assets that have been
| | 03:04 | loaded by the web browser.
| | 03:06 | The Chrome web browser also has a
similar web Inspector, because Chrome and
| | 03:10 | Safari share parts of a code base.
| | 03:13 | The browser side of web
development has improved dramatically.
| | 03:16 | With the increase in web applications
using asynchronous HTTP requests, using a
| | 03:20 | Web Inspection tool is now essential.
| | 03:23 | Web Inspectors also use JavaScript
debugging and notify you of missing assets.
| | Collapse this transcript |
|
|
3. Installing Joomla! ExtensionsInstalling and examining a minimal module| 00:00 | Modules are the quickest way of
getting pieces of PHP code running and
| | 00:03 | displaying on your Joomla site.
| | 00:05 | We'll start by installing a module that
has the bare minimum amount of PHP code
| | 00:09 | necessary for Joomla to run.
| | 00:12 | Let's go to the backend of Joomla
| | 00:13 | to install this module.
| | 00:16 | Log in as admin with password lynda, L-Y-N-D-A.
| | 00:18 | Now, let's go to the Extension
Manager to install the module.
| | 00:25 | Click on the Browse button, and from
here, select the mod_explore.zip file from
| | 00:30 | your Exercise Files.
| | 00:33 | Click Upload & Install and
the module gets installed.
| | 00:36 | However, we still need to publish it,
so that it appears on the front-end.
| | 00:40 | So let's go to the Module Manager.
| | 00:44 | Under Explore Activities, we want to make
sure that we select a position for the module.
| | 00:49 | So, if you're using the beez_20 template,
I recommend selecting position-7, and
| | 00:57 | then we also need to make sure
that the module is set to Published.
| | 01:01 | So select Published as the Status.
| | 01:04 | Finally, we need to make sure that
the module is appearing on all pages.
| | 01:07 | So scroll down and select all
pages as the Module Assignment.
| | 01:13 | Click Save & Close, and then go
back to the front-end and hit Refresh.
| | 01:17 | So now you'll notice that just
underneath the Main menu, the Explore Activities
| | 01:22 | module now appears along
with the Module Content.
| | 01:26 | Let's take a look at the files that got
installed when the module is installed,
| | 01:29 | so that we see where this
Module Content is coming from.
| | 01:34 | This is the root folder of Joomla
| | 01:36 | and let's scroll down to the
modules folder and then at the bottom is
| | 01:40 | the mod_explore folder.
| | 01:43 | This is the folder that got
installed when the Zip file was uploaded.
| | 01:47 | You'll notice the index.html file and
this is just a blank HTML file that's
| | 01:53 | there to discourage Apache from
displaying virtual directories, and then you'll
| | 01:58 | notice the mod_explore.xml file.
| | 02:01 | This is the first most
important file that Joomla
| | 02:04 | is going to look at when it
attempts to install this module.
| | 02:08 | Inside this file, there is a lot of
identification information that tells Joomla
| | 02:13 | what this module is, what it's about, who
wrote it, and why you want it on your system.
| | 02:19 | And all of that is included
in these tags here at the top.
| | 02:23 | Down here at the bottom is the files tag.
| | 02:25 | Any of the files that you want to have
installed with this module have to be
| | 02:29 | listed here in the files section.
| | 02:32 | The very first element here is the file
name for the main module file that gets
| | 02:36 | run when the module is displayed.
| | 02:39 | You'll notice that there is an
attribute of module="mod_explore" and this is
| | 02:44 | important to note, because this tells Joomla
| | 02:46 | that this is the file that you
want to run when this module runs.
| | 02:50 | Next, we have the other two files
that are included in this package.
| | 02:54 | Finally, let's take a look at mod_explore.php.
| | 02:59 | Inside this file, we have the
opening PHP tag along with _JEXEC or die;
| | 03:06 | and what this does is it makes sure
that nobody can go to mod_explore.php
| | 03:11 | directly without first going through Joomla
| | 03:14 | Then underneath that, we have a simple
echo statement Module content which is
| | 03:18 | for writing the content
that is within the module.
| | 03:22 | Note here that you could use
whatever PHP code you want.
| | 03:25 | You could make calls to the database here,
you could go to a third-party web service.
| | 03:29 | You could do any PHP code that's valid in
PHP and just echo the output right here.
| | 03:36 | Modules are the most
straightforward type of Joomla
| | 03:38 | extensions you can build.
| | 03:40 | With the minimal amount of code, you
can start a module and build it out to
| | 03:43 | suit your needs.
| | Collapse this transcript |
| Exploring a bare minimum component| 00:00 | A component is at the heart
of every request to Joomla
| | 00:03 | Let's install a minimal
component and take a look at its pieces.
| | 00:07 | So first, let's log in to the
backend and the username is admin, and
| | 00:10 | the password is lynda.
| | 00:11 | So I am going to go to the
Extension Manager, and browse for the
| | 00:15 | com_explore.zip file.
| | 00:19 | Then I am going to click Upload &
Install and that install the component for us.
| | 00:24 | Now, one thing that you want to note
when you're looking at a component is that
| | 00:28 | there is both a front-end to the
component and a backend to the component.
| | 00:31 | We're already in the backend, let's take
a look at the backend of the component.
| | 00:36 | To do that, just go to the Components
menu and you'll notice that there is
| | 00:39 | already an Explore California menu option here.
| | 00:43 | If you click on this option, it will take you to
what's currently the backend of this component.
| | 00:49 | We don't have a toolbar yet and
we just have the word Backend being
| | 00:53 | displayed down at the bottom.
| | 00:55 | Just like this, we have a front-end
to the component as well.
| | 00:58 | So you'll notice here that index.php?option=
com_explore is the link here in the Backend.
| | 01:05 | It's exactly the same in the front-end,
only we do it at the root rather
| | 01:09 | than /administrator.
| | 01:11 | So let's go to the front-end and go to
index.php?option=com_explore, and again
| | 01:19 | it's just outputting front-end here
with the standard Joomla template.
| | 01:23 | So let's take a look at where this code is
coming from that's generating this content.
| | 01:27 | Let's go to the root folder of Joomla
| | 01:29 | and you'll notice that there is an
administrator folder and a components folder.
| | 01:34 | The component for the front-end is under
components, while the component for the
| | 01:38 | backend is under administrator/components.
| | 01:41 | Let's first go to the front-end, so
go to components, and then com_explore.
| | 01:47 | Inside this folder is the explore.php
file along with an index.html file that's
| | 01:52 | there just to prevent Apache
from doing virtual directories.
| | 01:55 | So let's open explore.php and you'll
notice inside that this is very similar to
| | 02:01 | the module code that we had from before.
| | 02:04 | We have designed _JEXEC or die;
| | 02:06 | which makes sure that this file
is being called from within Joomla
| | 02:10 | and not being accessed directly.
| | 02:11 | Then we have our PHP code that just
says echo "Frontend" and just like the
| | 02:16 | module, we can add any
PHP code here that we want.
| | 02:20 | It's flexible like that where you can
use the model view controller design
| | 02:24 | pattern that we are going to talk about
later, or you can just start writing PHP
| | 02:28 | code that you have on hand.
| | 02:29 | The Backend is very similar.
| | 02:32 | Go back up to the administrator
folder, and then go into the components
| | 02:36 | folder underneath that.
| | 02:37 | Inside there, go to com_explore, and
then here you'll see a few more files.
| | 02:43 | Let's go to explore.php and
again, it's just _JEXEC or die;
| | 02:50 | and then the echo for "Backend".
| | 02:52 | Just like the front-end, you can add
whatever PHP code you want here and it will execute.
| | 02:57 | Joomla's! components allow you to simultaneously
create a backend and a front-end to
| | 03:02 | handle the same data.
| | 03:04 | If you set the option variable in
your URL, you can control which component
| | 03:08 | gets loaded.
| | Collapse this transcript |
| Understanding plug-ins| 00:00 | While other extension types always have
a visual element to them, plugins do not.
| | 00:05 | While they can be used to modify the
output of other extensions, their role is
| | 00:09 | more of a behind-the-scenes one.
| | 00:11 | The plugin we are installing now is
designed to modify the output of the core Joomla
| | 00:15 | content component.
| | 00:16 | So let's install it.
| | 00:17 | Let's go to the Backend and
login with admin and lynda.
| | 00:25 | Just like the other Extensions, go to the
Extension Manager, and then browse for the plugin.
| | 00:30 | Let's pick the activities.
zip file in the Exercise Files.
| | 00:36 | After installing it, go to the Plug-In
Manager and here we are going to enable the plugin.
| | 00:42 | It's a content plug-in and it
appears right here at the top.
| | 00:46 | So click the Enabled button and that has
now published the plugin in the system.
| | 00:52 | Let's go back to the
Frontend and see what happened.
| | 00:55 | If we hit Refresh, you'll
notice that nothing has happened.
| | 00:59 | Installing the plugin does not have
an immediate visual impact on this.
| | 01:04 | What this plugin is designed to do is to
search and replace on content and add a
| | 01:09 | link in automatically.
| | 01:11 | Let's add some content to this site,
so that the plugin has something to do.
| | 01:15 | We are going to go back to the Backend and go
to Content>Article Manager, add New Article.
| | 01:22 | From here, we are going to go to the
Exercise Files and bring in some content
| | 01:26 | for the plugin to work on.
| | 01:31 | The title is going to be something for everyone.
| | 01:33 | We are going to leave it Uncategorized.
| | 01:36 | We are going to set featured to Yes.
| | 01:39 | This will make sure that the article is
published on the front page of the web site.
| | 01:42 | Then finally, we are going to copy
and paste this content directly into
| | 01:48 | the Article Text box.
| | 01:50 | Finally, go back up to the
top, and click Save & Close.
| | 01:54 | Now, if we go back to the Frontend
and go to Home, and hit Refresh, you'll
| | 02:00 | notice that we have the content
that we pasted in, only activity is now
| | 02:05 | highlighted as a link.
| | 02:07 | We didn't add this link when we did the
cut and paste, the plugin created this
| | 02:11 | link after seeing the word activity.
| | 02:14 | So how did it do this?
| | 02:15 | Let's go back to the folder of the Joomla
| | 02:18 | installation and go down to plugins.
| | 02:22 | Under here, we want to go to the
content plugin folder because this was
| | 02:26 | a content plugin that we installed and we
are going to go to the activities folder.
| | 02:31 | Inside here is a PHP file and an XML file.
| | 02:35 | Let's take a look at the PHP file first.
| | 02:38 | You'll notice here that the main thing
that's being defined is a class called
| | 02:42 | plgContentActivities.
| | 02:45 | So the type of plugin that's being defined
is the first thing that comes after the PLG.
| | 02:50 | Then the name of the plugin
itself comes after the plugin type.
| | 02:54 | After that, we have a
function called onContentPrepare.
| | 02:58 | The onContentPrepare function
gets fired at the same time that the
| | 03:01 | onContentPrepare event is fired.
| | 03:04 | Any plugins that have an
onContentPrepare function will get run at that point.
| | 03:10 | All this plugin is doing is searching
for the word activity in the content of
| | 03:15 | the article and replacing that with the
URL that is pointing to the activities
| | 03:19 | view of the Explore component.
| | 03:22 | In addition to the PHP file, there is an
XML file and if we open this, it's just
| | 03:29 | like the modules.xml file.
| | 03:32 | It has things that identify what the
plugin is, who wrote it, and what version it is?
| | 03:38 | And it also has a
description of what the plugin does.
| | 03:41 | You'll notice up here at the top that
the group is specified as the content
| | 03:45 | group of plugins and that the
type of extension is a plugin.
| | 03:50 | Also, down here is a listing of the files
that are included as a part of the plugin.
| | 03:57 | Then finally, there is an
empty element here for config.
| | 04:00 | This element is typically used to
add configuration for the plugin.
| | 04:05 | But at the moment, we just
have a very simple plugin.
| | 04:07 | So we're going to leave it empty.
| | 04:08 | So this plugin is always going to run
whenever the content component runs.
| | 04:13 | Plugins are the best way of
adding code you always want to run.
| | 04:17 | You can have them listen for certain
events, then silently perform tasks in the
| | 04:21 | background at just the right moment.
| | Collapse this transcript |
| Translating essential language strings| 00:00 | Joomla takes internationalization very seriously.
| | 00:04 | Because of this, even if you aren't
planning on translating your component,
| | 00:07 | you're still going to end up
working with a few language strings.
| | 00:10 | Let's take a look at them now.
| | 00:12 | In this example file, we have a call
to Jtext::_ and then an argument that
| | 00:18 | says COM_EXPLORER_TOURS.
| | 00:22 | This is a language string key.
| | 00:25 | If there is a value that goes along
with this key in the language string file,
| | 00:31 | it will use that string in place of this call.
| | 00:34 | If there is no value that goes with
this key, it'll simply display the key on
| | 00:38 | screen, and that's how you know you're
missing a language string. Sometimes Joomla
| | 00:44 | uses this Jtext_function to do
translations, and sometimes it just expects
| | 00:50 | strings based on a certain naming convention.
| | 00:52 | So let's take a look at the
language string files themselves.
| | 00:57 | In the backend of Joomla
| | 00:59 | we have two different language string files;
| | 01:02 | we have com_explorer.ini
and one that's .sys.ini.
| | 01:09 | The difference is the .sys.ini file
contains language strings that are
| | 01:14 | specifically designed for the menu that Joomla
| | 01:18 | generates that includes all of the
components throughout Joomla So, Joomla
| | 01:23 | will pick up the .sys.ini files, so
that it doesn't have to pull the full
| | 01:28 | language string files and that way,
it improves performance a little bit.
| | 01:32 | A lot of these language strings are
not strictly required, but the ones that
| | 01:37 | I have marked here as Required in the .SYS.
INI file and in the .INI file usually are.
| | 01:44 | And even if you're targeting your
component for one language, language strings
| | 01:49 | are going to be a part of your code.
| | 01:50 | When you know how Joomla's!
| | 01:51 | language strings work, you can take care
of the required ones and plan ahead for
| | 01:55 | the level of internationalization you need.
| | Collapse this transcript |
| Touring the component manifest| 00:00 | While every extension in Joomla
| | 00:02 | has a XML manifest file for
installation, but one for components is the
| | 00:06 | most sophisticated.
| | 00:07 | Understanding how this file works and
what you can do with it will save you
| | 00:11 | headaches at installation time.
| | 00:13 | So this manifest files and other XML
file, it's starts off with an install tag
| | 00:18 | and the install tag has
three different parameters on it.
| | 00:23 | The first is its type to specify this
installation file as one for a component.
| | 00:29 | The next is the method which is upgrade.
| | 00:31 | I recommend always using upgrade,
because what it does is it installs the
| | 00:36 | component if it's not already there.
| | 00:37 | And if the component is already there it's
simply copies the new files on top of the old ones.
| | 00:44 | Then the final argument is the version number.
| | 00:47 | This is the minimum Joomla
| | 00:48 | version that this component will work on.
| | 00:52 | Just beneath the install tag are several
tags that are used to identify the component.
| | 00:57 | The most important one is the name tag.
| | 01:00 | This one is currently set to com_explore
and that's the exact same convention
| | 01:06 | that you want to follow for your component.
| | 01:08 | So always name the name with com_ the
name of your component, The rest of the
| | 01:14 | tags down on through description are
more or less for information for the admins
| | 01:19 | just to show who wrote it, when they
wrote it, what license it's under, and what
| | 01:24 | the component is for.
| | 01:25 | The next tag underneath
that is the languages tag.
| | 01:30 | This one specifies the language file to be
used for the front end of the Joomla Component.
| | 01:36 | Then just beneath that is a files tag.
| | 01:39 | This tag specifies all the files
that need to go into the components
| | 01:43 | com_explorer folder on installation.
| | 01:46 | If you don't put the file here in
this list, it will not get installed.
| | 01:51 | You don't have to have a file name for
every single file for instance if you
| | 01:56 | have a folder, you can use a folder tag
instead of file name, but you still do
| | 02:00 | need to list the folders
that you want to install.
| | 02:03 | After the files tag are the
install and uninstall tags.
| | 02:07 | These are two optional tags, you don't
have to put them in your component at all.
| | 02:12 | However, if you do want to install some
MySQL database tables on installation,
| | 02:18 | this is a good place to do it.
| | 02:19 | So let's take a look at the files right now.
| | 02:23 | I'm going to open the install.mysql file
and you'll see there are several CREATE
| | 02:28 | TABLE statements in here.
| | 02:29 | These contain not only the names of the
tables, but also aliases for the tables.
| | 02:34 | So you'll notice #__ at the beginning
of the table names and that's simply an
| | 02:39 | alias for the database
prefix that you are using.
| | 02:43 | In my installation here I have
Jos_ as the database prefix.
| | 02:49 | Down at the bottom of the file here
I have two INSERT INTO statements and
| | 02:54 | these have preloaded content for us to work
with as we build out the rest of the component.
| | 03:00 | There is also an uninstall file.
| | 03:03 | This file includes anything that you want to
have happened when the component is uninstalled.
| | 03:08 | Typically, you would want to
drop the tables that you created
| | 03:12 | during installation.
| | 03:13 | However, this is optional.
| | 03:15 | Many component developers decide not
to do this, because they want to leave
| | 03:19 | the data in the database in the
event that someone has uninstalled the
| | 03:23 | component, because they're having a problem
with it and they just want to try reinstalling it.
| | 03:28 | So it is up to you, you can have an
uninstall file, or you can omit it.
| | 03:34 | So after the install tags
we've an administration tag.
| | 03:38 | This almost looks like all the other
tags that we've had so far just repeated
| | 03:42 | again for the backend of the component.
| | 03:45 | The first one is the languages tag
and again these are just the language
| | 03:49 | files that are going into the backend of the
component rather than the one for the front end.
| | 03:54 | Then next we have menu and submenu tags
and these set up the menu in the backend
| | 04:01 | where the component can be accessed.
| | 04:03 | Let's take a look in the backend
right now and see what this generates.
| | 04:07 | I am typing in admin and lynda and
now under the Components menu is Explore
| | 04:14 | California and Activities and Tours.
| | 04:19 | You'll notice here in the XML file
that the titles for the menu items are
| | 04:24 | appearing as language strings.
| | 04:26 | So these get translated by the language
files that get installed in the tag before it.
| | 04:31 | And then finally we've another files tag.
| | 04:33 | This installs all of the files into the
backend of the component and notice that
| | 04:38 | the manifest.xml file is
also included in this file list.
| | 04:43 | This is very important, because the
manifest file needs to be present on
| | 04:47 | installation and uninstallation.
| | 04:49 | Once you have a component manifest
file under your belt, it serves as a good
| | 04:53 | base for future components.
| | 04:55 | Keep this manifest file handy for this
component as well as for the next one
| | 04:58 | you build.
| | Collapse this transcript |
|
|
4. Creating and Displaying ModulesDisplaying information in modules| 00:01 | Modules are the quickest way to
add PHP code to your Joomla site.
| | 00:04 | In this video we'll pull some data from
our component and display it in a module.
| | 00:09 | So first what we want to do is go
to the Exercise Files and find a
| | 00:13 | mod_explore.php file.
| | 00:16 | Then we also want to find the mod_explore.php
file in the Joomla Installation.
| | 00:21 | So go to the root of your Joomla
| | 00:24 | installation, then go to modules,
then go to mod_explore and you'll
| | 00:29 | see mod_explore.php.
| | 00:32 | So what you want to do is copy the
file from your Exercise Files into that
| | 00:36 | folder and then just replace that file
and then if we go back to the front end
| | 00:41 | and hit Refresh, you'll notice that now
we've the titles of several activities
| | 00:45 | that you can do when you're in California.
| | 00:47 | Now let's take a look at the
file that we just replaced.
| | 00:50 | So at the top of the file we still
make sure that we are within Joomla
| | 00:54 | We don't want people to go
directly to mod_explore.php.
| | 00:58 | Next, we are calling the
JFactory::getDBO function.
| | 01:02 | What this function does is it gets an
object that represents the database that Joomla
| | 01:07 | is currently connected to.
| | 01:09 | After we have our database object
we can call to getQuery method on it.
| | 01:13 | In this case we are passing the
parameter true into the function.
| | 01:16 | What this does is it returns
a fresh database query object.
| | 01:21 | If we omit true from this call what
it will do is it will return the last
| | 01:26 | database query that was
executed in the database.
| | 01:29 | We've really don't want that.
| | 01:30 | We want our fresh ones that we can
build our own query to get some records
| | 01:34 | out of the database.
| | 01:36 | Then next we are building our SQL statement.
| | 01:38 | Rather than just typing out an SQL
statement as at long string what we are doing
| | 01:44 | is we are calling different
functions on the query object.
| | 01:48 | So that way we can build
our query very incrementally.
| | 01:52 | In this case it's very straightforward.
| | 01:55 | We are just selecting the activity_name
from the activities table, but in more
| | 01:59 | complicated cases this functionality
could be very useful for building your
| | 02:04 | query incrementally rather than just outright.
| | 02:06 | We are setting the query object into
the database object and what that does is
| | 02:12 | it just takes the query and places it
into the database object and gets it
| | 02:16 | ready to be executed.
| | 02:18 | Then finally we are calling the
LoadObjectList function on the database object.
| | 02:23 | That takes the query, runs the query,
and then loads all of the data from that
| | 02:28 | query into an array and that array contains
objects that each represent a row in the database.
| | 02:34 | Once we have our rows, we can cycle
over them using the foreach statement.
| | 02:39 | This foreach statement is simply
building an unordered list and we are just
| | 02:43 | outputting the activity name for
each activity that's in the database.
| | 02:48 | So this is a very simple module and
it's a way that you can just get some
| | 02:52 | information out of the database
and display it on the front end.
| | 02:55 | When you want start
displaying information in Joomla
| | 02:57 | without a lot of work, modules are good choice.
| | 03:00 | They are simple and can
pull any data stored in Joomla
| | Collapse this transcript |
| Configuring through parameters| 00:01 | Module parameters give site
administrators a way of configuring your module
| | 00:04 | without digging into PHP code.
| | 00:06 | They also give your module a level of
reusability as different model instances
| | 00:10 | can have different settings for the parameters.
| | 00:13 | Let's add a parameter to the
explore California module now.
| | 00:16 | We are going to go to the Exercise Files
and open up mod_explore.xml and in this
| | 00:23 | file we have a config section that
we're going to add to the existing XML file.
| | 00:28 | So I am going to copy that and open
up the one that's inside of Joomla
| | 00:32 | already and just paste it right in.
| | 00:35 | So I am going to make a little room
and paste it and then save that file.
| | 00:40 | So you'll notice in this XML we have a
config element and then a fields element
| | 00:45 | with a name of params and this tells Joomla
| | 00:48 | that these are the parameters that we
want to use to configure the module.
| | 00:52 | Inside params we have a
field set with a name basic.
| | 00:56 | You can also have an advanced section,
but for the moment we were just going to
| | 00:59 | keep it at basic and then inside the
field set is a field and this allows us to
| | 01:04 | define what the name of the field is
going to be, what type it is, whether or
| | 01:08 | not we have a default value and how we
want to label and describe the parameter.
| | 01:13 | So now let's go to the PHP file and
we're going to add a piece of code that
| | 01:18 | allows us to get the value of the
parameter and display it in the front end.
| | 01:23 | So open up the mod_explore.php file
from the Exercise Files and the only
| | 01:29 | difference between this file and the
one that's already there is this paragraph
| | 01:33 | tag with the params get call.
| | 01:36 | So I am going to copy this and paste it
into the file that's already in Joomla
| | 01:44 | So you'll notice here there is already
an object that's named params and all we
| | 01:48 | have to do is call the get function
and pass in the name of the variable, in
| | 01:53 | this case message, that
we want to get an echo out.
| | 01:57 | Params is automatically
defined whenever you load a module.
| | 02:00 | So to see this in action we need
to go to the backend and adjust the
| | 02:06 | configuration for our module.
| | 02:08 | So we are going to login into the backend.
| | 02:10 | Our User Name is admin
and the Password is lynda.
| | 02:15 | Go to Extensions>Module Manager and then
choose Explore Activities from the list.
| | 02:21 | You'll notice on the right here under
Basic Options we have Message and if we
| | 02:26 | mouse over you see a description
of what message is intended to be.
| | 02:31 | So in this box we are going to type
Explore all California has to offer.
| | 02:35 | Then we are going to click Save & Close.
| | 02:38 | If we go back to the front end and
hit Refresh you now see Explore all
| | 02:43 | California has to offer!
| | 02:44 | listed right above the list of all the
different activities that are in California.
| | 02:49 | Let's also create another instance of
this module just to see the difference.
| | 02:54 | So for instance if we go back here
and click New, we can choose Explore
| | 02:59 | Activities as the module type.
| | 03:00 | We are going to call this Second Copy and
we're going to Select position-7 from this list.
| | 03:09 | We're going to leave the Status as
Published, and then we are going to also
| | 03:14 | leave the Module Assignment as On All Pages.
| | 03:17 | Than we click Save & Close and we go
back to the front end and hit Refresh.
| | 03:22 | So you'll notice that Second Copy
does not have the message while Explore
| | 03:26 | Activities does have the message.
| | 03:28 | That's because, we have not set the
parameter for Second Copy, but we have set
| | 03:32 | it for the original.
| | 03:34 | So in that way you can reuse the
module over and over again with different
| | 03:38 | settings for different situations.
| | 03:41 | Parameters transform your module
from hard coded PHP into configurable
| | 03:45 | reusable packages of code.
| | 03:47 | You can use parameters to keep site
administrators away from PHP and focused
| | 03:51 | on managing the site.
| | Collapse this transcript |
| Styling with layouts| 00:01 | Depending on the needs of the site
webmasters may want different ways of
| | 00:04 | displaying the output from your module.
| | 00:06 | This can be accomplished through module layouts.
| | 00:09 | Let's give our webmasters a
selection of layouts to choose from.
| | 00:12 | First let's go to the XML
that's in the Exercise Files.
| | 00:15 | Go to mod_explore and Open it and there is
an additional field for the configuration.
| | 00:22 | Just Copy this field and we're going
to Paste it into the XML file that is
| | 00:27 | already in the installation.
| | 00:29 | So right here within the field set just
Paste the field in and we'll save the file.
| | 00:36 | You'll notice a few things;
| | 00:39 | first the name of this parameter is
different from the other parameter.
| | 00:42 | This one is called Layout well the first
one is called message and this one is a
| | 00:47 | list parameter rather than a text parameter.
| | 00:50 | This is because we want to provide a
list of values that the admins can choose
| | 00:54 | from and we don't want them just
entering in whatever text they want.
| | 00:57 | We want them to choose just from these values.
| | 01:00 | Next we have a default value that is
one of the values that is available from
| | 01:04 | the list, so that way it's already
selected and people don't have to worry about
| | 01:10 | setting a value already, it'll just be there.
| | 01:12 | And then we have a label and a
description for the field that will display just
| | 01:16 | like the other parameter.
| | 01:17 | Finally, we have three options one for
a Plain List which is the current layout
| | 01:21 | that we use, and then we have an
Ordered List and Paragraph Tags as other
| | 01:26 | options for layouts.
| | 01:27 | So now let's also Copy the tmpl folder
into the mod_explore folder on the site.
| | 01:34 | If you go into the tmpl folder you'll
notice there is default, ordered and
| | 01:38 | paragraphs and these are the three
layouts that we are going to offer
| | 01:41 | webmasters as choices.
| | 01:43 | So if you go to default.php it's the same
output that we have in the current module.
| | 01:50 | Notice that the defined JEXEC or die
statement is still up at the top and this
| | 01:54 | is necessary because this is a php file
and we don't want people going directly
| | 01:59 | to this file, we want people to
only load this file through Joomla.
| | 02:04 | ordered.php is similar except we're
putting everything within an ordered list
| | 02:09 | rather than an unordered list.
| | 02:12 | And then paragraphs.php again just
cycles over all the records, but this time it
| | 02:17 | puts each of them in paragraph
tags rather than as a part of a list.
| | 02:21 | Now before we attempt to display this
on the front end we still need to make
| | 02:24 | one more adjustment.
| | 02:26 | We need to adjust mod_explore.php to
choose from one of these layouts rather
| | 02:31 | than trying to display all the output itself.
| | 02:34 | So let's go back to the Exercise Files
and Open mod_explore.php and Copy this
| | 02:40 | require statement this JmoduleHelper
call will make it possible for Joomla
| | 02:45 | to select from one of the layouts
rather than attempt to do all of the output
| | 02:50 | here from the php file.
| | 02:53 | So if I Open mod_explore.php in the Joomla
| | 02:56 | installation and remove all of the
current output, I can replace it with this
| | 03:00 | require statement and this will allow
us to get all of the output from one of
| | 03:05 | the layouts rather than do
it right here in the php file.
| | 03:09 | Now there is one more thing we want to
do before we display this on the front
| | 03:13 | end, we want to go back to the back
end and make sure that these values are
| | 03:17 | set, so that Joomla
| | 03:19 | displays them appropriately.
| | 03:20 | So let's go back to the admin type
admin as the User Name and lynda as the
| | 03:25 | Password and then go to the Module Manager.
| | 03:30 | We have Second Copy as one of the
modules from before and I just want to delete
| | 03:34 | that, because we are not going to use it again.
| | 03:37 | And now let's go to Explore
Activities and set this Layout.
| | 03:42 | We have Plain List that's set as the
default, so let's just keep it there and
| | 03:47 | click Save and this brings
us back to the editing screen.
| | 03:50 | We are going to come back and do some
other settings here so, keep this handy.
| | 03:54 | Go back to the front end and hit
Refresh and you'll notice that the second
| | 03:58 | module is gone because we deleted it
and the Explore Activities module still
| | 04:03 | displays the same as it did before.
| | 04:05 | Now let's choose one of the other
Layouts let's go back and choose Ordered List
| | 04:10 | as one of layouts and hit Save and
then go back to the front end and hit
| | 04:15 | Refresh and you'll notice now that the module
numbers all of the items that are being output.
| | 04:21 | Finally, let's try the Paragraph Tags Layout.
| | 04:24 | Select Paragraph Tags from the list,
click Save, then hit Refresh and you'll
| | 04:31 | notice that the same list appears as
before only they are in Paragraph Tags, so
| | 04:36 | you have a little bit of
clearance between the different items.
| | 04:38 | So module layouts make it possible for us
to give webmasters a variety of layouts.
| | 04:44 | Additionally they help separate the
presentation of your module away from the data logic.
| | 04:48 | With started out as a simple PHP
script is becoming a powerful and flexible
| | 04:53 | reusable mighty module.
| | Collapse this transcript |
| Overriding layouts| 00:01 | Let's face it, everyone has an
opinion about HTML markup especially
| | 00:05 | template designers.
| | 00:06 | Fortunately, changing the output of
your module layouts, does not require
| | 00:10 | modifying the original code.
| | 00:11 | A module layout override is
possible and preferable, to changing the
| | 00:15 | module layout directly.
| | 00:16 | So let's add and override.
| | 00:18 | First what we want to do is set the
module layout back to the original one.
| | 00:24 | So let's go back to the backend in the
administrator, I am logging in as admin
| | 00:28 | and lynda and go to Module Manager and
then in Explore Activities we want to set
| | 00:36 | the Layout back to Plain List.
| | 00:39 | Hit Save & Close and then go back to
the front end, hit Refresh and you'll
| | 00:43 | notice the original layout that we had.
| | 00:46 | So now we are going to add a template
override, this template override when we
| | 00:51 | pull it up in our Text editor, it's
simply adding an em tag around the message,
| | 00:57 | that's going to make it appear as
italicized text rather than just the
| | 01:01 | plaintext is currently there.
| | 01:03 | So to add the template override we
want to go to the templates folder and on
| | 01:08 | this site I'm using the beez_2O template,
so click that and you'll notice there
| | 01:13 | is this HTML folder that's in place,
if your template does not have an HTML
| | 01:18 | folder, go ahead and create it,
because this is where the overrides go.
| | 01:21 | So next you'll notice there is a modules.php
file and an index.html file in the
| | 01:28 | folder and if you've create this folder
it will just be blank, in this case we
| | 01:32 | want to add a new folder for our module.
| | 01:35 | So add a New Folder and call it mod_explore
and then all we need to do is copy
| | 01:43 | the default.php file into this folder.
| | 01:48 | So after we've copy that file in, we
can hit Refresh and you'll now notice that
| | 01:53 | it's using the markup from the override
rather than the markup from the original module.
| | 01:59 | Since we've done the layout override
rather than touching the original file we
| | 02:04 | can remove and add this override as we please.
| | 02:08 | So if we entirely remove this folder
and then hit Refresh again it reverts back
| | 02:13 | to the original markup.
| | 02:15 | So, that way you can make changes to
the module output without touching the
| | 02:19 | original source code.
| | 02:20 | In addition to giving output choices
module layouts make it possible for
| | 02:24 | template designers, to override
your output without touching the code,
| | 02:27 | always use module layouts, to give
your module maximum flexibility with the
| | 02:31 | minimal effort.
| | Collapse this transcript |
|
|
5. Model-View-Controller (MVC) CodingDefining MVC| 00:00 | Joomla makes the use of design patterns to
enforce consistency, reusability, and
| | 00:05 | familiarity across the code base.
| | 00:06 | Most of the code that you want to write
for the components will fit nicely into
| | 00:09 | the model View Controller
also known as MVC design pattern.
| | 00:13 | Let's take a look at what MVC
is and why it's used in Joomla
| | 00:16 | So first what is model View Controller?
| | 00:19 | model View Controller is a design pattern.
| | 00:22 | It's not a specific piece of code as
much as it is a way of organizing code into
| | 00:28 | familiar reusable pieces.
| | 00:30 | Design patterns are designed to do just
that just to take your code and break it
| | 00:35 | down into reusable parts that are
interchangeable so that no one part is really
| | 00:40 | depending on the other too much.
| | 00:42 | The concept of design patterns that
computer science has is taken directly from
| | 00:48 | the world of Build architecture.
| | 00:50 | There's a book called A Pattern
Language that came out in the 70s and there's a
| | 00:55 | quote from it that really sums up what
design patterns are and why you use them.
| | 01:00 | Each pattern describes a problem
that occurs over and over again in our
| | 01:03 | environment and then describes the
core of the solution to that problem in
| | 01:07 | such a way that you can use the
solution a million times over without ever
| | 01:11 | doing it the same way twice.
| | 01:12 | And you are going to find in computer
science that this is extremely true no
| | 01:18 | two frameworks out there implement the
model View Controller design pattern
| | 01:22 | in the same way and you're going to
find design patterns out there in code that
| | 01:27 | are quite like the ones that you saw the
last piece of software that you wrote code for.
| | 01:31 | So how does model View Controller work?
| | 01:35 | model View Controller splits your
application into three primary tasks.
| | 01:39 | The one task for the controller is to
receive the user input all it to doing is
| | 01:45 | receiving the user input and then
telling the view and the model what to do.
| | 01:49 | So after you've receive the user
input then you have your model which is
| | 01:54 | processing any data this is typically
where you're going to talk to your database
| | 01:58 | if you have one or where you're going
to pull data in for a third-party source
| | 02:02 | and the only thing the model is doing
is processing that data and getting it
| | 02:08 | ready for either the database or the
view and then finally the view is primarily
| | 02:14 | concerned with displaying output.
| | 02:16 | You pretty much want to keep just view
code in your view and you don't want to
| | 02:21 | do any data processing in there
because that really is the model's job.
| | 02:25 | Unfortunately a lot of PHP scripts that
you'll find out there do the opposite of this.
| | 02:30 | You'll have a piece of code up at the
top that's connecting to the database and
| | 02:34 | trying to validate the data and do all
of these things in the event that a form
| | 02:39 | has been submitted and then at the
bottom of that file you'll find a bunch of
| | 02:44 | HTML markup that's a form that's the
one that people are submitting to and it's
| | 02:50 | all in one big script.
| | 02:52 | And it just becomes a huge mess
because it's impossible to maintain and you
| | 02:56 | have designers that try to come in and
change the markup and you run the risk
| | 03:02 | that they are going to break the data
processing that's happening up at the top of the file.
| | 03:07 | So for your Web applications you
really want to use something like model View
| | 03:11 | Controller, because it breaks it out
into the separate parts that don't have to
| | 03:16 | rely on each other directly.
| | 03:18 | Let's take a look at some pseudo code
PHP examples of how you might write model
| | 03:23 | View Controller code.
| | 03:24 | So first there is the controller and
all its doing is taking in user input and
| | 03:30 | it gives the user a selection of
different things that can be done.
| | 03:35 | So functions for this controller you
can either save or delete records and
| | 03:40 | all the controller is doing is getting
the data from the user and passing it
| | 03:45 | right along to the model.
| | 03:47 | That's the most that this controller
is doing and you really want to have
| | 03:50 | same controllers, so that all of the
controller is doing, is focusing on
| | 03:55 | receiving the user input.
| | 03:57 | So next we have the model and the
model is going to receive the data and then
| | 04:02 | connect with the database and
either save it or delete it or modify it.
| | 04:06 | Anytime we want to connect to the
database you really want to use a model
| | 04:11 | because you don't want your controller
to be responsible for working with the
| | 04:15 | data in the database
| | 04:17 | And then finally there is a view.
| | 04:19 | the view is primarily concerned with
the HTML output that goes back to the
| | 04:23 | browser and you don't want to connect
to the database at all here you just want
| | 04:28 | to focus on the HTML markup.
| | 04:30 | So another way of thinking of the
model View Controller design pattern is an
| | 04:34 | entertainment system in your home.
| | 04:36 | Consider your remote control,
your television, and your DVD player.
| | 04:41 | Your remote control is solely interested
in receiving input from what channel or
| | 04:46 | what DVD you want to watch it's not
storing the actual movie or the television
| | 04:52 | program and it is not displaying
anything it's just receiving your input and
| | 04:56 | talking to the DVD player and the television.
| | 04:58 | So then you have the DVD player itself
and the DVD player is just concerned with
| | 05:03 | the reading data from the DVD and
sending it to the television, it also receives
| | 05:09 | some commands from the remote control
that you have and it will either turn on
| | 05:13 | or stop or play or start depending on
what the controllers is telling it to do.
| | 05:19 | And then finally you have your
television which acts as the view, the television
| | 05:22 | does not contain the television program
or the movie that you're watching it's
| | 05:27 | simply displays what the DVD
player, the model is feeding it.
| | 05:31 | So I'll can take some getting used to MVC
is an excellent way of organizing a Joomla
| | 05:35 | component.
| | 05:36 | The MVC style libraries included in Joomla
| | 05:39 | make it easy to take your
component from concepts to working code.
| | Collapse this transcript |
| Choosing with controllers| 00:00 | After Joomla begins to load your component
it needs to know where to go.
| | 00:04 | A controller makes it easy to
define a list of places where Joomla
| | 00:07 | can take a request, so let's add a
controller now go to the Exercise Files and
| | 00:11 | you'll notice that there's a controller.php
file is ready, go to be components
| | 00:18 | and com_explore folder in your Joomla
Installation and Copy the controller.php
| | 00:23 | file from the Exercise Files into this folder.
| | 00:28 | Let's take a look at this
controller.php file now, you'll notice that
| | 00:32 | first we're importing the library
that has all the controller code through
| | 00:36 | this jimport function.
| | 00:38 | You'll notice that this jimport function here
at the top is being used to pull in a library.
| | 00:44 | This function is used throughout Joomla
| | 00:46 | to do just that pull in libraries
that you want to use in this file.
| | 00:50 | Next we've a class definition and first
the name of the class is Explorer which
| | 00:57 | matches the name of our component and
then that's followed by controller and
| | 01:01 | this is a convention, so that Joomla
| | 01:03 | knows how to name the controller that
it's trying to load when it's trying to
| | 01:08 | load it and this class extends the
JController class that's the base class that Joomla
| | 01:14 | has its available for controllers.
| | 01:16 | And then we have two different
functions in this controller, we have one call
| | 01:20 | the save, and then we have one call
Delete and in each case we're doing
| | 01:25 | something very basic, we're just echoing
out what we're doing we're not actually
| | 01:29 | saving or deleting any records at this point.
| | 01:32 | So next to make sure that this
controller gets executed we need to change the
| | 01:39 | explored.php code that's currently on
the site, so that it loads the controller
| | 01:45 | rather than having our current output.
| | 01:48 | Our current output looks like this.
| | 01:49 | If you go to index.php option=com_explore
it just says front end.
| | 01:56 | This is the output that we bundled
with the original installation package, so
| | 02:01 | let's replace this with code
that loads the controller instead.
| | 02:06 | So open up explore.php from the
Exercise Files and then open up the export.php
| | 02:14 | file that's currently installed in Joomla
| | 02:19 | Remove the echo statement that's
currently just saying Frontend and then go to
| | 02:23 | the exercise file version and copy all
of the code from here to there notice.
| | 02:29 | Notice again where importing the
controller class and this is because we're
| | 02:33 | calling the JController class
directly using to get instance function.
| | 02:39 | What this is going to do is it's
going to get an instance of the controller
| | 02:43 | that's in the other file.
| | 02:45 | Once it gets an instance of the
controllers that's in the other file and it gets
| | 02:49 | the one that's prefixed with explore
we're going to call the execute function on
| | 02:54 | the controller object.
| | 02:56 | We pass the value of task into
this execute function that way Joomla
| | 03:01 | knows what value to use when choosing
the function that it needs to run and then
| | 03:07 | finally at the end we're calling the
redirect function on the object and what
| | 03:12 | this does is if at any point in the
controller we set a redirect to say when the
| | 03:19 | request is done go to this other page,
this redirect function is going to take
| | 03:23 | us to any other page we set.
| | 03:26 | In this case we haven't done that
yet but it will come into play later.
| | 03:30 | So let's fire off some tasks.
| | 03:32 | We have the Save task and the Delete task.
| | 03:35 | To fire off these tasks all we need to
do is add a variable to our URL called
| | 03:41 | task and match the name of the
function to the variable in the URL.
| | 03:45 | So we're going to add &task=save and hit
Enter and now it's says saving tour and
| | 03:55 | if we change this to
delete it shows deleting tour.
| | 03:59 | So you notice we have save and delete.
| | 04:02 | If I try another task say open it gives
us a 500 error because we don't have a
| | 04:08 | task defined for open and this is
very powerful, because we can use our
| | 04:13 | controller to restrict exactly what
people can and cannot do with our component.
| | 04:18 | So controllers make clear what
tasks your component can perform.
| | 04:22 | The controller only executes one task
at a time, so you don't have to worry
| | 04:26 | about running the wrong code and
whenever you need a new task it's as easy as
| | 04:31 | adding a new function.
| | Collapse this transcript |
| Looking at views| 00:00 | Most requests to Joomla
| | 00:02 | will end up displaying
HTML formatted information.
| | 00:05 | The components you build will most
likely consist of several screens of
| | 00:08 | information that you want
to display. Views in Joomla
| | 00:11 | gives us a clean way of separating
out these screens so that they are
| | 00:15 | independent of the others.
| | 00:16 | Let's take a look at the way that Joomla
| | 00:18 | handles views in
conjunction with the controller.
| | 00:21 | So first, right now with the
controller in place, if we go to the Explore
| | 00:26 | Component without specifying a task
and without specifying anything else, we
| | 00:30 | get a 500 error, and this error is because
since we haven't specified a task, Joomla
| | 00:36 | is by default calling the
display function in the controller.
| | 00:40 | The display function then looks for a
view in our request, and if it can't find
| | 00:45 | one, it just gives us this error.
| | 00:48 | We could override this function if we wanted to.
| | 00:50 | Let's go to the current controller.
php file and override the display
| | 00:56 | function temporarily.
| | 00:57 | We're writing a new function here, and
it's just going to be called Display.
| | 01:10 | We're going to save the file.
| | 01:11 | So now when we go back and hit Refresh,
you'll notice that I did not add a task
| | 01:16 | variable to this URL.
| | 01:18 | It's still just calling the Explore
component and it's now displaying the output
| | 01:24 | from our display function.
| | 01:26 | That's because if you don't specify a
task for your controller, by default it's
| | 01:30 | going to call the display function.
| | 01:32 | Let's remove this function because we
want to use the default display function
| | 01:36 | that is included in J controller
instead of one that we defined.
| | 01:40 | Now, let's add some views.
| | 01:42 | To do this, copy the Views folder from
your Exercise Files into the com_explore
| | 01:48 | folder of your component
that's already installed in Joomla
| | 01:53 | So that folder contains two more folders;
| | 01:55 | one for activities and one for tours.
| | 02:00 | We can call up these views by
simply adding them to the URL.
| | 02:04 | So if want to view the activities,
just add ampersand and view=activities.
| | 02:12 | Now, you see California
Activities is displayed as a header.
| | 02:16 | If we go back to the files that are on
disk, you'll notice there is default.php,
| | 02:23 | and that is what's outputting that
California Activities header, but you'll also
| | 02:27 | notice that there is this view.html.php file.
| | 02:32 | This file is what Joomla
| | 02:33 | looks at first before it
calls that default.php file.
| | 02:37 | This file gives us a chance to
add any data we want to the view
| | 02:42 | before displaying it.
| | 02:43 | In this case, we don't want to add any
data, so we're just defining our view as
| | 02:48 | ExploreViewActivities.
| | 02:50 | So Explore is the name of our component,
Activities is the name of our view, and
| | 02:55 | View is in the middle.
| | 02:56 | That's the naming convention
that we want to use for this class.
| | 02:59 | If we didn't want to display
data, we can do so by adding it to
| | 03:03 | that view.html.php file.
| | 03:05 | So for instance, notice here in Tours,
in the view.html.php file here, we have a
| | 03:11 | display function, and this display
function allows us to add data to the view
| | 03:16 | before we display it.
| | 03:18 | So we have a protected class member here
called Header and we're setting it down
| | 03:21 | here in the display function, and then
we're calling the parent display function
| | 03:25 | to go pull the default.php file for Tours.
| | 03:29 | Then if we go to the default.php file
for Tours, and open it, you'll notice that
| | 03:36 | we're just echoing out this header, and
that's pulling the data that we set in
| | 03:41 | the view.html.php file.
| | 03:43 | So if we go to view=tours, that now
shows California Tours as the header.
| | 03:50 | Views handles something that you do over
and over again when building web application;
| | 03:54 | that give you a chance to get
data, then present it in HTML.
| | 03:58 | Views keep your Presentation layer in
a consistent place without getting it
| | 04:02 | mixed in with code that processes data.
| | Collapse this transcript |
| Modeling data| 00:00 | models are intended to handle
a component's data processing.
| | 00:03 | This usually although not exclusively involves
storing and retrieving data from the database.
| | 00:09 | Let's take a look at how a model
could be used to retrieve records from the
| | 00:12 | database so that they
can be displayed in a view.
| | 00:15 | First, we're going to go to the
Exercise Files and copy the models folder from
| | 00:19 | the Exercise Files into
our Joomla installation.
| | 00:24 | Copy it right here into the com_explore folder.
| | 00:28 | Once you have that pasted in, go to
the models folder, and open up the
| | 00:32 | tours.php file inside.
| | 00:34 | So this is a model file.
| | 00:36 | We have a class here defined and it's
called ExploremodelTours and that follows
| | 00:40 | the convention of the component
name model and the name of the model.
| | 00:44 | It's extending the J model List class.
| | 00:46 | J model List is specifically designed
for pulling a list of records from the
| | 00:50 | database, so that they can
be displayed in the front-end.
| | 00:53 | Next, we define the getListQuery function.
| | 00:56 | This function is one that J model List
is going to look for and it's going to
| | 01:01 | call this function and expect to get
back a query object, so that it can run it
| | 01:05 | against the database.
| | 01:06 | If you call the getListQuery function
that just comes with J model List by
| | 01:10 | default, you get back a database
query object that's fresh and ready to go.
| | 01:15 | That's exactly what we want.
| | 01:16 | Once we have that query object, we
call the select, and from, and where
| | 01:20 | functions, so that we can
build our database query.
| | 01:23 | So we just want the tour_name
from all the published tours.
| | 01:27 | Once we've built that query
object, we just return it.
| | 01:30 | So this is all we need for our model
to get the tour_name from all of the
| | 01:34 | published tours in the database.
| | 01:37 | In order to display those tours, we need
to make a few adjustments to our tours view.
| | 01:41 | So go to Views, and Tours,
and edit view.html.php.
| | 01:51 | Go back to the Exercise Files
and pull up view.html.php there.
| | 01:57 | We're going to copy the line where we
define the items property, and we're going
| | 02:02 | to paste that here into the View.
| | 02:03 | Then we're also going to copy
this line where we get the items.
| | 02:08 | Notice that this is a get method for
JView and it's not the actual get method
| | 02:14 | that's in the model.
| | 02:16 | This is because Joomla
| | 02:17 | does not let JView directly touch the model.
| | 02:21 | It does this abstraction to make sure
that we're not trying to pull anything
| | 02:25 | directly from the model
that we shouldn't be doing.
| | 02:28 | So after saving the view.html.php file,
we need to edit the layout file as well
| | 02:34 | so that it actually displays the records.
| | 02:36 | So go into tmpl, and open up default.php
and then do the same in the Exercise Files.
| | 02:46 | We're going to copy and paste this
unordered list directly into the View, and
| | 02:53 | now with this in place, we can
load this view in the front-end.
| | 02:59 | Go to index.php?option=com_
explore and then view=tours.
| | 03:04 | So now you'll notice in addition to
the header that we had before, all the
| | 03:09 | database code is in the model while all of
the display code is right here in the View.
| | 03:15 | That way, we don't have the two
mixing with each other and if we want to
| | 03:19 | adjust the view, we don't have to
worry about disturbing the model and
| | 03:23 | breaking something.
| | 03:24 | So models allow you to interact with the
database completely separate from views.
| | 03:28 | Because of the separation, you can
work on HTML output in the View without
| | 03:32 | worrying about accidentally
breaking your database queries.
| | Collapse this transcript |
| Joomla! MVC vs. the world| 00:00 | Because model-View-Controller is a
design pattern and a specific piece of code,
| | 00:04 | different coders choose to
implement it in different ways. Joomla
| | 00:07 | is no exception.
| | 00:09 | While Joomla's implementation of MVC
holds to the same general pattern as other
| | 00:12 | frameworks, there are a
few noteworthy differences.
| | 00:15 | First, let's take a look at view.html.php.
| | 00:18 | You may have noticed that view.html.php
loads the view and the model in the same file.
| | 00:24 | Most other frameworks out there that you will
find often try to do this in the controller.
| | 00:29 | Joomla views are responsible
for getting the model data.
| | 00:32 | In many other frameworks, you will
find that the controller will load the
| | 00:36 | model and then load up the data and then pass
that data over to the view, while in Joomla
| | 00:42 | that's all handled in this view.html.php file.
| | 00:45 | So you can really think of view.html.
php as a sort of mini-controller that's
| | 00:51 | just focused on doing things
for the view. This way Joomla
| | 00:54 | controllers stay very small and that's
very desirable because you'll often find
| | 00:59 | people talk about MVC and say that you
want to have lean controllers and fat
| | 01:05 | models and this way, your controllers
stay very, very lean and the views are
| | 01:11 | just fed directly from the models.
| | 01:13 | Another difference is that there
is a completely separate backend and
| | 01:17 | frontend of your component.
| | 01:19 | This is great from a security standpoint
because when you have your code in that
| | 01:23 | administrator/component/common_name of
your component, you know that that code
| | 01:29 | is not at all ever going to be
displayed or used on the frontend.
| | 01:33 | So it's great in separating out code
that's only for admins as opposed to code
| | 01:38 | that's for public consumption.
| | 01:40 | Unfortunately, this is a trade-
off because it is lousy from a
| | 01:44 | reusability standpoint.
| | 01:45 | You will have instances where you want
to display a list of records from the
| | 01:50 | database and that code is generally
going to be the same in the frontend as in
| | 01:54 | the backend may be with one
or two small slight changes.
| | 01:58 | Unfortunately, you end up having to
duplicate all this bliss code because the
| | 02:04 | code is completely separate in
the backend from the front end.
| | 02:07 | Another difference you will find is that
a lot of other frameworks are concerned
| | 02:12 | with what's known as the front controller.
| | 02:15 | A lot of people talk about the front
controller problem and what they're saying
| | 02:20 | is that when you load up your web
application, you need to come up with a way of
| | 02:25 | telling the framework which
controller you want to load and Joomla
| | 02:29 | handles this elegantly.
| | 02:31 | You can either specify which component
you want to load in the URL using that
| | 02:35 | option variable, or you can create a
menu item link and that menu item link will
| | 02:40 | determine which component gets loaded.
| | 02:42 | So your component ends up acting as
the front controller because then Joomla
| | 02:47 | will just load whichever component
you specify, and then it will load the
| | 02:50 | controller for that component. However, Joomla
| | 02:53 | also supports multiple controllers
per component and when you get into
| | 02:58 | multiple controllers then you have
to choose which controller in that
| | 03:01 | component you want to use and Joomla
| | 03:04 | handles this by overloading
the task variable into two parts.
| | 03:08 | The first part is the name of the
controller, and then you have a period, and
| | 03:12 | then you have the name of the task.
| | 03:14 | So if you have a task that is ever in
that format where you have a title and
| | 03:18 | then a period and then another title, Joomla
| | 03:21 | is automatically going to break that
out and assume the first part is the name
| | 03:25 | of the controller and the second part
is the name of the task you want to run.
| | 03:29 | Another difference between Joomla
| | 03:31 | and many other frameworks is that the
MVC design pattern is not even required.
| | 03:36 | You can just do a quick script in that
PHP file where your component starts and
| | 03:42 | never load a model, a view, or a controller.
| | 03:45 | You can just write
straight a PHP and go with it.
| | 03:48 | This is really good for when you're
trying to do maybe a data import, or you
| | 03:52 | just try to test something out very quickly.
| | 03:55 | It's nice to be able to just start
writing PHP and not have to worry about MVC
| | 03:59 | while you get something working.
| | 04:01 | You can also just pull in the
pieces of MVC that you want.
| | 04:05 | You don't have to pull in a model,
a view, and controller every time.
| | 04:09 | A lot of other frameworks will force you
to have the output in the view and that
| | 04:16 | really makes them kind of brittle when
you want to do something, it's a little
| | 04:20 | bit simpler, for instance,
when you're getting JSON data.
| | 04:23 | Let's take a look at some examples here.
| | 04:24 | So in Joomla, we have a controller
here where we're getting tour data in JSON
| | 04:30 | format and we're just getting the
tour's model, we are getting the items from
| | 04:35 | the tour's model, and then we are
immediately outputting in JSON format the tour data.
| | 04:41 | And this way we are only doing one
line of code here that's producing output.
| | 04:46 | So it's very compact and it gets
to the point. It's what we want;
| | 04:50 | we just want JSON data back out of the browser.
| | 04:53 | We are not going to lay this out in
a specific way and it's very simple
| | 04:57 | and straightforward.
| | 04:58 | So this is a really good feature that lets
you output that JSON without a lot of trouble.
| | 05:04 | However, what you will find with other
frameworks is that they are very strict
| | 05:08 | about where you put your output.
| | 05:10 | So other frameworks might do
code that's more like this.
| | 05:13 | You have first your controller where
you're getting the tour data from the
| | 05:17 | model, and then you are getting your
view and assigning the tour data to the
| | 05:21 | view, and then you create one more
file where you finally echo out the
| | 05:27 | json_encode data call.
| | 05:29 | And this in my mind is a little bit of
a waste because all we are trying to do
| | 05:34 | is echo out the data in JSON format, no
matter what the data is and we are never
| | 05:40 | going to use markup.
| | 05:42 | So what is the point of
creating a separate view file?
| | 05:46 | That's why I prefer Joomla
| | 05:48 | So while Joomla's implementation
of MVC may stray from that of other
| | 05:51 | frameworks, it's still
fundamentally the same structure. Joomla
| | 05:54 | gives you the flexibility of deciding
whether you even want to use a MVC at
| | 05:58 | all or only part of it.
| | 06:00 | Knowing the nuances of Joomla's MVC
implementation will make it easy to pick
| | 06:03 | up other frameworks.
| | Collapse this transcript |
|
|
6. Front-End MVCDisplaying a single record| 00:00 | In most components, you'll have at
least one view where you display the
| | 00:03 | contents of a single record.
| | 00:05 | Let's take a look at a
standard way of doing this in Joomla.
| | 00:08 | First, let's go to the Exercise Files and
you will notice we have a tables folder.
| | 00:13 | This tables folder needs to go
into the backend of the component.
| | 00:16 | Even though it's going into the
backend of the component, the frontend of the
| | 00:20 | component is going to know to look
in the backend for these classes.
| | 00:24 | This is just the standard that Joomla
| | 00:26 | has set forth for these table classes.
| | 00:29 | So let's go to the backend of the
component, in administrator>components
| | 00:34 | >com_explore and we are going to copy
the tables folder into this folder and
| | 00:41 | once it's there, we are going
to take a look at activity.php.
| | 00:45 | So inside of activity.php is a class
called ExploreTableActivity and that
| | 00:51 | follows the naming convention of the
name of the component, table and then the
| | 00:55 | name of the table that we want to work with.
| | 00:57 | And so here, we are just overriding the
constructor which by default takes in a
| | 01:01 | database object and we are right away
calling the parent constructor and we are
| | 01:06 | passing in the name of the table we
want to work with along with the key that
| | 01:11 | we want to use which is activity ID, and then
we are passing in again the database object.
| | 01:17 | And what this class allows us to do
is it allows us to work with all of the
| | 01:22 | create, read, update, delete
functionality that we would ever want to perform on
| | 01:26 | the JOSS Explore Activities table.
| | 01:28 | That way we don't have to write,
select and update and insert statements;
| | 01:32 | we can just do it all through here.
| | 01:35 | So let's go back to the frontend
to actually use this table class.
| | 01:39 | Go to components>com_explore and go to
the models folder because we are going
| | 01:44 | to add a new model.
| | 01:46 | Go to the models folder in your
Exercise Files and copy activity.php into the
| | 01:52 | models folder of the site and now we are
going to open this and take a look at it.
| | 01:58 | And we have declared another model
class here that we are going to use and
| | 02:05 | this model class has a function called
getItem and getItem is pulling in the
| | 02:11 | ID from the getURL request.
| | 02:14 | So here we have getInt the id from the
URL and storing it in activity_id and
| | 02:22 | notice that we are using JRequest to
get this value and we are using the getInt
| | 02:28 | function and that's making sure that
we're getting an integer and not a string
| | 02:32 | or any other value that is not an integer,
and then we are getting a row object.
| | 02:37 | So we are getting a row object here
through JTable::getInstance by passing in
| | 02:42 | 'activity' and 'ExploreTable' and Joomla
| | 02:45 | assembles all this into
ExploreTableActivity and returns the row object.
| | 02:50 | Then once we have the row object, we
can call the load function passing in the
| | 02:54 | activity_id and that will load the id
that matches in the database and then
| | 03:00 | finally we return the row
object with the data preloaded.
| | 03:03 | So let's go back to the Exercise Files
and we are finally going to add a new view.
| | 03:10 | So we have a single activity view and
we are going to copy this activity view
| | 03:15 | from the Exercise Files into our site
and this activity view is much like the
| | 03:22 | other ones, if we go to view.html.php,
you will notice we have a display
| | 03:28 | function and it is getting the item
through the getItem function in the model,
| | 03:33 | but it's calling it indirectly, and
then it's assigning the value to this item.
| | 03:39 | And then finally, we have a
layout file here in default.php.
| | 03:46 | So if we open this up, you will
notice that there are two things being
| | 03:49 | pulled from the item.
| | 03:51 | We have the activity_name and the
activity_description and both of these are
| | 03:55 | just going to be output here in the layout.
| | 03:58 | So let's see all this in action.
| | 04:00 | We are going to load the activity
view and load the record with id=1.
| | 04:05 | So let's go to index.php, we are going
to pull up the explore option for the
| | 04:13 | export component, we are
going to do view=activity & id=1.
| | 04:21 | And then when we do that, it pulls in
the header of Back pack Cal, and then it
| | 04:28 | pulls in the description for
the Back pack Cal activity.
| | 04:33 | So all we had to do was define a JTable
class, have the model, load the JTable
| | 04:39 | class, return it, and then pass it
along to the view and then the view is able
| | 04:43 | to output all of the HTML here.
| | 04:46 | So whatever you want to display just
a single record in Joomla, just use a
| | 04:50 | JTable class along with your
model and then assign it to the view.
| | Collapse this transcript |
| Displaying a complex record| 00:00 | Sometimes you'll want to do something
more complex than displaying a single
| | 00:04 | record from a database table.
| | 00:06 | You will want to join in records that
are from another database table as well
| | 00:10 | as from a primary one.
| | 00:12 | To do this, you want to avoid JTable
and do a custom query in your model.
| | 00:17 | So let's do that to show at single tour.
| | 00:20 | So first, go to the models folder in
your Exercise Files and take a look at
| | 00:25 | tour.php and copy it over here into com_explore.
| | 00:30 | So we are going to copy tour.php over
and we are going to take a look at the
| | 00:36 | file, and in this case, we again have a
getItem function that is just like the
| | 00:41 | one for activity, but in this case,
instead of pulling in a JTable object, we
| | 00:46 | are doing a custom database query.
| | 00:48 | We are pulling in the id and using
getInt again, but this time, we are storing
| | 00:54 | it as tour_id, and then we are
getting a database object from the model.
| | 00:59 | We just call this getDbo and that pulls
in the database object, and then we are
| | 01:05 | getting a fresh query by
calling getQuery and passing in true.
| | 01:09 | If we don't pass in true, we get
the last query that was executed, and
| | 01:13 | that's not what we want.
| | 01:14 | Next, we are building our query incrementally.
| | 01:17 | We have select from, join in where and
all those come together to pull in the
| | 01:23 | data from the tours table, as well as
some associated data from the activity.
| | 01:27 | So in this case, we are getting the
tour that matches the tour_id that's coming
| | 01:33 | in from the request.
| | 01:34 | We are setting the query in the
database using the setQuery function, and then
| | 01:39 | we are calling the loadObject
function on the database object.
| | 01:42 | This returns a single
object that's not in an array.
| | 01:47 | And then once we have that row we can return it.
| | 01:50 | So with this model in place, now we
have to do is add a view for the tour.
| | 01:54 | So go to the views folder in your
Exercise Files, notice that there is tour
| | 01:59 | folder here and all we want to do is copy this
folder into the views folder of our component.
| | 02:06 | So let's take a look at tour and let's
take a look at the view.html.php file,
| | 02:13 | and you will notice again we are just
getting this getItem just like we did for
| | 02:17 | activity, and then let's go to
the layout file, default.php.
| | 02:24 | And in this case we are getting the tour_name
and the activity_name that we joined in.
| | 02:29 | We are getting the tour_description,
along with some details about the tour.
| | 02:33 | So if we go to the front end and go to
index.php, option=com_explore, view=tour
| | 02:42 | & then id=1, it pulls in the name of
the tour and it pulls in the name of the
| | 02:48 | activity as well that display.
| | 02:51 | And then it pulls in all the
information about the tour, including the details.
| | 02:56 | So whenever you want to get more than
just a single row from a single table, you
| | 03:01 | can use a model to do a custom query
and then that way you can get more complex
| | 03:06 | data to display it in your view.
| | Collapse this transcript |
| Blending view data| 00:00 | While single and list views are
helpful, you'll often also want to display
| | 00:04 | records that is from
different tables in the same view.
| | 00:07 | Let's blend some view data right now.
| | 00:10 | So going into the Exercise Files, we
want to open the models folder and go into
| | 00:15 | the activity.php file in there, and
there is a function called getTours.
| | 00:22 | We want to copy and paste this
function into the activity model that's
| | 00:27 | already in our component.
| | 00:28 | So go to models, activity, open it
up and then paste in the function.
| | 00:37 | So now we have a getTours function
that's in the activity model and I am going
| | 00:40 | to save the file, and we are still
getting the activity_id just like in getItem,
| | 00:47 | but this time we are building a
custom query to get all the tours that are
| | 00:52 | assigned to that activity.
| | 00:54 | So we are getting a fresh database
object from the model, and then we are
| | 00:58 | getting a fresh query from that database object.
| | 01:01 | Then we are building up our query to
get the tour name, id, location and teaser
| | 01:06 | from the tours table, for all the
tours that are assigned to this activity.
| | 01:10 | We are then setting that query in the
database, and then we are loading the
| | 01:14 | result set using loadObjectList.
| | 01:16 | This is going to return an array of
objects so we can cycle over them in the view.
| | 01:21 | So now that we have this in the model,
let's go to the view and update it so
| | 01:24 | that we have the data ready to present.
| | 01:27 | Go to views, and go to activity.
| | 01:30 | Go to view.html.php and open it, and
you will notice that we have tours as a
| | 01:38 | protected property as well as getTours.
| | 01:41 | So we want to copy these into our activity view.
| | 01:44 | So go to activity and open up view.html.
php and then just copy that property and
| | 01:51 | that function call right in.
| | 01:59 | So that's going to pull in the tours and
assign it to our view object so that it
| | 02:03 | is ready to be displayed.
| | 02:06 | So finally, now that we have the
data from the model, let's open up the
| | 02:10 | layout that's in default.php and we
are going to replace the layout that we
| | 02:17 | currently have with this one.
| | 02:21 | So currently, we are just
displaying the activity_name along with the
| | 02:24 | activity_description.
| | 02:25 | We are going to copy and paste this mark up
in, and then we are going to save this file.
| | 02:35 | So now we have a header that's
identifying the tours apart from the description
| | 02:39 | and the title of the activity.
| | 02:41 | And we are cycling over each
tour and providing a length to each.
| | 02:45 | So let's go and load one of the activities.
| | 02:48 | Let's go to index.php and
then view=activity and then id=1.
| | 02:56 | This loaded the activity title, as
well as the activity description, and then
| | 03:01 | underneath, we have loaded every
tour that is assigned to this activity.
| | 03:06 | So if we click on the link for one of
these tours, it takes us right to that tour.
| | 03:10 | The expansion of the activity view now
makes it possible for users to navigate
| | 03:14 | from an activity, over to
a tour on that activity.
| | 03:18 | The flexibility of Jmodel, allows us to
work with multiple data sets in the same
| | 03:22 | model, and then displaying all
of those data sets in the view.
| | Collapse this transcript |
| Linking views together| 00:00 | As you add views to your component,
you'll frequently also want to link
| | 00:03 | those views to each other, so that
visitors can navigate around your
| | 00:07 | component seamlessly.
| | 00:09 | Let's add some of these
links now to help out our views.
| | 00:12 | So if we go to the Tours view right now,
you'll notice that we have a list of
| | 00:17 | all the tours that are
available, but they're not linked.
| | 00:21 | So let's fix that by
adding links to these tours.
| | 00:25 | First, what we need to do is go to
the model in our Exercise Files and open
| | 00:31 | up the tours.php file.
| | 00:33 | We need to update this model because at
the moment, we're not getting the tour
| | 00:38 | ID and the tour name that's
here from the Exercise Files.
| | 00:42 | So let's copy in this function into the
model that's already in our component.
| | 00:48 | So when we update this function, we've
added few columns to the query and that
| | 00:57 | way we can get the ID as
well as the tour_teaser.
| | 01:02 | Now that we've updated the model,
let's go back and update the view.
| | 01:05 | So let's go to the Tours view.
| | 01:08 | Another thing that we want to do is we
want to have the header directly in the
| | 01:12 | layout file, and not assign it in view.html.php.
| | 01:16 | So to do that, go to Tours and go to
view.html.php and just remove the header
| | 01:24 | assignment and also remove the header property.
| | 01:30 | Finally, let's update the layout.
| | 01:32 | Go to the tmpl folder in your Exercise
Files, and open up default.php, and then
| | 01:41 | open up the one that's
already in your component.
| | 01:43 | We're going to copy and paste this markup
into our component and then save that file.
| | 01:52 | So you'll notice now the header is
being translated from the JText function and
| | 01:58 | we're also cycling over all
the items as we did before.
| | 02:02 | But now, we're building links for every
item and outputting that so that we can
| | 02:07 | navigate to those tours.
| | 02:12 | So if we go and hit Refresh, you'll
notice now we're not only have links to the
| | 02:17 | tours, we also have the short
description for each tour, and if we click on the
| | 02:22 | link, it goes to the tour.
| | 02:24 | Now, one thing you'll notice on the
tour is that as you go to the bottom, there
| | 02:28 | is no link back to the list of all the tours.
| | 02:31 | So let's fix that as well.
| | 02:33 | Let's go to the Tour view and in the
tmpl folder there is the default layout.
| | 02:42 | So open up the default.php
file in your Exercise Files.
| | 02:48 | You'll notice we have a div here with
ID of tour_footer, and we just want to
| | 02:52 | copy this div out, and then go back to
the default.php file that's already in
| | 02:59 | our component, and add that div to the bottom.
| | 03:02 | So when we save that file and we hit
Refresh and go to the bottom of the screen,
| | 03:10 | we now have a link that goes right back
to the Tours and it brings us right back
| | 03:14 | here where we can go visit another tour.
| | 03:17 | So now it's possible for us to
navigate from a list of tours to a single tour
| | 03:22 | and then navigate right back to the list.
| | 03:24 | Adding these links are making this
component come together, and it's going to
| | 03:28 | make it easier for visitors to use it.
| | Collapse this transcript |
| Styling views with CSS| 00:00 | When you are writing HTML markup, the
best strategy to use is the simplest HTML
| | 00:04 | possible that's still semantic
enough to imply what you're displaying.
| | 00:09 | However, you often need the help of
a style sheet to get the basic visual
| | 00:12 | presentation you want.
| | 00:13 | The Activities View is
definitely one of those cases.
| | 00:16 | We're going to be displaying images to
the left of the Activity Descriptions and
| | 00:20 | we don't want to use tables.
| | 00:22 | So first, let's get those images into place.
| | 00:25 | If you go to your Exercise Files, you
notice an images folder and inside that
| | 00:30 | folder is an activities folder.
| | 00:31 | This has all the images that we're going to use.
| | 00:35 | So go to the root of your Joomla
| | 00:36 | installation and go to the images
folder there and then copy activities from
| | 00:42 | your Exercise Files into the images folder here.
| | 00:45 | So now we have all the images that our
activities records are going to reference.
| | 00:53 | Next, what we want to do is add the
style sheet that we're going to use and
| | 00:58 | again we have this in the Exercise Files.
| | 01:01 | Go into the media folder and you'll
notice a com_explore folder and for this, we
| | 01:07 | want to go and add this to
the media folder of our site.
| | 01:11 | So just copy com_explore from the
Exercise Files over to the Joomla site.
| | 01:20 | And you will notice there's a subfolder
here for css and then the activities.css
| | 01:26 | file, and here we just have some very
basic CSS that's here to add a little bit
| | 01:34 | of visual styling to the
HTML that we're going to output.
| | 01:38 | You'll also notice that since we have
this css folder here, later on we're going
| | 01:44 | to add other assets that go with our component.
| | 01:47 | But for now, we're just filing
this away under css so that we can
| | 01:50 | keep everything clean.
| | 01:54 |
| | 01:54 | So once we have the CSS file in place,
next we need to do some work on the view.
| | 01:59 | The first thing we want to do is we need to
beef-up the model that is behind the activities.
| | 02:06 | So at the moment, if you go to
components>com_explore and models, you'll notice
| | 02:12 | that we don't have an activities model at all.
| | 02:15 | So copy the one from the Exercise Files
over to this folder, and if you open it
| | 02:20 | up, you'll notice it's very basic.
| | 02:22 | All we're doing is getting all the
published activities from the activities
| | 02:26 | table and returning that query.
| | 02:30 | So finally with that model in place,
let's go back to the views, and let's
| | 02:34 | replace the activities view
that's currently there with this one.
| | 02:41 | At the moment, we have a view.html.php
file and the one that we currently have
| | 02:47 | on the site doesn't really have anything in it.
| | 02:49 | So let's copy this over and paste
it into current view.html.php file.
| | 02:58 | So now this actually defines the display
function and it gets the items from the
| | 03:02 | model and assigns them to the view.
| | 03:04 | So after saving that file, the only thing
we have left to do is to update the layout.
| | 03:10 | So go into the tmpl folder in your
Exercise Files, open up default.php and copy
| | 03:19 | this markup and paste it into default.php.
| | 03:22 | So we're going to select
all and just paste right over.
| | 03:28 | So you'll notice just as before in some
of the other views, we're cycling over
| | 03:33 | some records and building some URLs
and just outputting the descriptions, and
| | 03:39 | then we also have a header
that's being translated through JText.
| | 03:43 | But in addition to those two things,
we also have the document object.
| | 03:48 | We're calling JFactory::getDocument and
this returns a document object, and what
| | 03:53 | the document object allows us to do is
it allows us to modify the HTML document
| | 03:58 | as a whole that's being generated as Joomla
| | 04:01 | goes through the components and
the modules and the plug-ins that are
| | 04:04 | generating the page.
| | 04:06 | And as it's generating that page,
it's collecting all the stylesheets, and
| | 04:11 | JavaScripts and other assets that we want
to add to the head section of the HTML page.
| | 04:17 | So in this case, we want to add the
activities.css file that we put in the media
| | 04:22 | folder and we want to display
that when this view gets called.
| | 04:26 | So using the addStyleSheet function of the
document object we're able to add that CSS file.
| | 04:33 | Notice also there is this JURI::base
function, that will always return the
| | 04:39 | base URL of Joomla
| | 04:41 | no matter where it's placed.
| | 04:42 | So even if you have it in a subfolder,
or you have it in a different domain, you
| | 04:46 | don't have to worry, just call JURI::
base and you'll always get that base URL,
| | 04:51 | and then we have the path to our CSS file.
| | 04:53 | So we have media/com_explore/css/activities.css.
| | 04:56 | So now that we have all this in place,
let's go and load the activities view.
| | 05:01 | Let's go to index.php, option=com_
explore and view=activities, and now that
| | 05:11 | we've loaded that, we have the CSS
that is moving all the images to the left,
| | 05:16 | while all the descriptions are on the
right, and then the images are linked to
| | 05:21 | the activities themselves.
| | 05:24 | So with the JDocument object it's
possible to add declarations to the header of
| | 05:28 | the HTML document rather
than adding the CSS in line.
| | 05:32 | This makes it possible for Joomla
| | 05:33 | to manage the list of assets and
for us to keep our markup clean and
| | 05:37 | regardless of Joomla
| | 05:38 | is installed you can always get
the base URL by calling JURI::base.
| | Collapse this transcript |
| Overriding views| 00:00 | One of Joomla's strongest features is
the ability to override practically all
| | 00:04 | the HTML output at the template level
without modifying the original code.
| | 00:09 | Views and custom components are no exception.
| | 00:13 | Let's test a view override.
| | 00:15 | So first, let's go to the Exercise Files.
| | 00:21 | Here, we have a default.php file.
| | 00:24 | This is an override for our Tours
view and it's going to remove the
| | 00:28 | descriptions in the links that are
currently on there and just replace them
| | 00:32 | with links and paragraph tags.
| | 00:34 | It's going to simplify
this view when we apply it.
| | 00:37 | If we go to index.php?option=com_explore
&view=tours, you'll notice we have this
| | 00:43 | list that has all the links to all the
tours and next to all those links is the
| | 00:48 | description for each tour.
| | 00:50 | This view override that we're about to apply is
going to simplify that down just to the links.
| | 00:56 | So to apply this override, we want to go
to the Templates folder, and currently,
| | 01:03 | we're using the beez_20 template and
there is an HTML folder here that is ready
| | 01:08 | to go for overrides.
| | 01:10 | So to apply this override, first we
need to create a folder for the component.
| | 01:15 | So New Folder, it's going to be called
com_explore, and inside this folder, we
| | 01:23 | want to add a folder for the
view that we're trying to override.
| | 01:27 | In this case we're overriding the Tours view.
| | 01:29 | So just add tours like that.
| | 01:33 | You don't have to add the tmpl
folder that you normally see in the
| | 01:36 | views, because Joomla
| | 01:37 | already knows that this is the
override folder and it will make sense of it.
| | 01:43 | So copy default.php right into that
folder, and then when we go hit Refresh
| | 01:49 | here on the front-end, it's simplified
everything down to just the links in paragraph tags.
| | 01:55 | Now, if we want to remove this override,
all we have to do is remove the folder.
| | 02:00 | Now, when we hit Refresh,
the original view is back.
| | 02:05 | Template overrides are very powerful
feature allowing designers to use their own
| | 02:09 | HTML markup in place of what
a programmer might provide.
| | 02:12 | You can do override one view at a time,
no need to override everything if you
| | 02:17 | just want to change one file, and
removing an override is as simple as
| | 02:20 | removing the file.
| | Collapse this transcript |
|
|
7. Back-End MVCComparing back-end and front-end MVC| 00:00 | Despite doing slightly different things,
both the front-end and the backend of Joomla
| | 00:04 | use the model View Controller
design pattern for organizing code.
| | 00:08 | The biggest difference is that the
front-end is primarily used for displaying
| | 00:11 | data while the backend is used for managing it.
| | 00:14 | So the first difference is that you
can usually get away with a single
| | 00:17 | controller in the front-end, and you
usually cannot get away with a single
| | 00:21 | controller in the backend.
| | 00:23 | In the front-end, nine times out of ten,
you're just displaying a view, you're
| | 00:27 | not going to have as many forms as you
have in the backend and you aren't going
| | 00:32 | to be taking in as many
specific requests from users.
| | 00:36 | So another difference between the front-
end and the backend is that the backend
| | 00:40 | has some controllers and models that
are a little bit more suited for loading
| | 00:45 | and saving and deleting records.
| | 00:48 | It makes this process a little bit more
automatic than it would be if you didn't
| | 00:53 | have these specialized controllers.
| | 00:56 | The third difference is that the
security model in a backend is very different.
| | 01:00 | When you have logged into the backend
of the web site, it's necessary to make
| | 01:05 | sure that another web site that you're
visiting is not trying to make a request
| | 01:11 | on the backend instead of
you making that request.
| | 01:15 | It's a security hazard that's known as
a Cross-Site Request Forgery, and the
| | 01:20 | only way to protect against this is to
send a randomized token to the form and
| | 01:26 | have that token checked
whenever that form gets submitted.
| | 01:30 | Then finally, the HTTP request
flow is different in the backend.
| | 01:34 | When you save, delete or otherwise
change a record, you're going to be
| | 01:39 | redirected by the controller
to another screen in Joomla
| | 01:42 | This is so when you hit the Back button,
you don't accidentally do that save or
| | 01:47 | delete again, and this differs from
the front-end in that the front-end is
| | 01:51 | simply displaying a view
and that's the end of it.
| | 01:54 | With the backend, whenever you do one of
these tasks, it's going to complete the
| | 01:58 | task and then redirect you to another screen.
| | 02:01 | So while the code in Joomla's!
| | 02:02 | backend serves a different purpose from
the code in the front-end, the same MVC
| | 02:06 | design pattern applies.
| | 02:08 | However, security and data management
considerations make it necessary to take
| | 02:12 | different approaches with similar looking code.
| | Collapse this transcript |
| Listing records| 00:00 | The most typical type of screen
seen in the backend of Joomla
| | 00:03 | Is one that lists all the records in a
table making them available for editing.
| | 00:07 | Let's start off the backend of the
Explore California component, with a list of
| | 00:11 | all the activities in the database.
| | 00:13 | First, let's login to the backend of Joomla
| | 00:14 | We are logging in as admin with password lynda.
| | 00:20 | Go to Explore California and
choose the Activities item.
| | 00:25 | So, right now the Activities view item
is just showing the default text that we
| | 00:30 | have for the backend of the component
that we still haven't built out yet.
| | 00:34 | Let's add some code that will load
a view rather than just showing this
| | 00:39 | backend placeholder text.
| | 00:41 | In the Exercise Files, open up
to explore.php and copy this code.
| | 00:50 | Next, go to administrator>components>com
_explore and then go to explore.php and
| | 00:56 | open it and then replace
that file with that code.
| | 01:00 | So you will notice, this is the exact
same code that we have for the front end.
| | 01:05 | It's pulling in a controller and it's
getting an instance of it, and then it is
| | 01:10 | executing the task from the request
against that controller and that is
| | 01:14 | redirecting the browser if necessary.
| | 01:16 | So next we need to add the controller,
that we are going to use for our back end.
| | 01:20 | So copy the controller.php file from
the Exercise Files over to your component.
| | 01:26 | And when we open and take a look at it,
you will notice it's a very basic controller.
| | 01:30 | There are no tasks on it;
| | 01:31 | we are just relying on the default
display task, that is included in JController.
| | 01:38 | Right now, if we go and refresh the
backend you will notice that we will get a
| | 01:40 | 500 error and that's because while
we're specifying the view activities here up
| | 01:45 | at the top, we still don't
have the Activities view in place.
| | 01:50 | So let's add a model and a view so that Joomla
| | 01:52 | has something to display when
we request the Activities view.
| | 01:56 | Go back to the Exercise Files and pick
up the models and the views folders and
| | 02:02 | then copy them and paste them
into the com_explore backend folder.
| | 02:07 | Let's take a look at the model.
| | 02:09 | So open up activities.php and you will
notice here we have a getListQuery just
| | 02:14 | like we have for the other model lists
and we are just getting a fresh query and
| | 02:18 | selecting all the records from
activities and all the columns in that table as
| | 02:22 | well, and then we are returning
the query object. Then when Joomla
| | 02:27 | goes to execute the getItems
function, we are first calling the
| | 02:30 | parent::getItems function, which will
run this query and return all of the
| | 02:34 | results from the database.
| | 02:37 | After that what we're doing is we're
doing a little bit of prep work for the view.
| | 02:41 | We are cycling over the items in a
four each loop and we're getting each item
| | 02:46 | by reference so that we can edit them
in place, and then we are adding this URL
| | 02:50 | property to each item and we are building the
edit url for every item that's in that result set.
| | 02:55 | We are pointing to be explore
component and calling up the activity
| | 03:01 | controller with the edit task, and
then we are assembling the activity_id
| | 03:06 | onto the end of that.
| | 03:07 | So that way when we assemble the URL
here, we don't have to do it in the view
| | 03:11 | and it keeps our view nice and tidy.
| | 03:14 | So let's take a look at the view now.
| | 03:16 | If we go to the activities view
here in the backend and open up the
| | 03:19 | view.html.php file, you will
notice it's a very straightforward view.
| | 03:24 | We are just pulling in the items from
the model and assigning them to the view,
| | 03:28 | and then we are displaying the layout.
| | 03:30 | So let's take a look at
the layout in default.php.
| | 03:35 | So here we have a form for the backend.
| | 03:38 | You will notice that the name of this
form is adminForm and that's very crucial
| | 03:42 | to know because all of the
JavaScript that's in the backend of Joomla
| | 03:45 | is designed to work with a form named adminForm.
| | 03:48 | So just be sure to add that to your
form whatever you're doing the list view.
| | 03:51 | You will also notice that the form is
posting back to the explore component, and
| | 03:57 | then we begin to get into the table.
| | 04:00 | We have a table here with a class of adminList.
| | 04:03 | If we go and refresh this view now,
you'll notice that we have a specific format
| | 04:08 | for the table with the alternating backgrounds.
| | 04:12 | This is controlled through the
adminList class for the table.
| | 04:15 | Every row that we go through, we are
going to take a look at which row number
| | 04:20 | it is and decide whether it's an odd
or an even row and then output the class
| | 04:25 | name based on that.
| | 04:26 | Additionally, up here at the top, we
have headers for every column, we have a
| | 04:30 | checkall check box in the first column,
and then we have standard table headers
| | 04:36 | and all the other columns.
| | 04:38 | And then finally down here in each row,
we first echo out a check box and we are
| | 04:44 | using the JHtml class to generate a
check box that's specific for these records.
| | 04:50 | It finds the record ID to every
check box and in that way when Joomla
| | 04:56 | is using the toolbar buttons to
publish or unpublish or delete or deal with
| | 05:01 | any number of records as a group, it will
have the correct IDs behind these check boxes.
| | 05:07 | Next, we have the URL, the ones that
we built back in the model and we are
| | 05:11 | simply echoing them out and we are not
building them here, we are just echoing
| | 05:15 | what we built in the model, and then
we're escaping the activity name and
| | 05:19 | echoing it as the link title.
| | 05:21 | Then we have the activity description
and then again we are calling the JHtml
| | 05:27 | class to generate
publishing and publishing buttons.
| | 05:30 | If we take a look back here at the view,
you will notice these check boxes and
| | 05:34 | these are images, when you click on
them, they will unpublish and publish
| | 05:38 | records depending on what the state it.
| | 05:40 | So that JHtml::_('jgrid.published'
function is going to determine whether or
| | 05:46 | not the item is published based on
the item data, and then it's going to
| | 05:51 | generate the appropriate check box or x
depending on whether or not that record is published.
| | 05:57 | For the most part, a list view in the
backend starts the same way that a list
| | 06:01 | view in the front end does.
| | 06:02 | Much of the same MVC functionality is
present and it's written in a very similar way.
| | 06:07 | However, the JHtml helper functions and
specific HTML markup create the familiar Joomla
| | 06:13 | backend user-interface.
| | Collapse this transcript |
| Adding back-end toolbars| 00:00 | Every backend view in Joomla
| | 00:02 | has control over the toolbar area
appearing just above the main output.
| | 00:06 | This toolbar is controlled through
some helper functions that make it
| | 00:08 | impossible to mess up.
| | 00:10 | So let's login to the backend and add
some toolbars to our Activities view now.
| | 00:14 | I'm logging in as admin and lynda
and let's go to Components>Explore
| | 00:21 | California and Activities.
| | 00:23 | Here we have the list view that we
have already built and we are just going
| | 00:28 | to add a toolbar up here at the top,
so that we have some buttons that we can
| | 00:31 | use on these records.
| | 00:33 | So go to your Exercise Files and open
up the view.html.php file and you will
| | 00:39 | notice that we have a call to this
addtoolbar, and then we have the addtoolbar
| | 00:44 | function right here.
| | 00:46 | So first we are going to copy
the addtoolbar function into the
| | 00:50 | existing view.html.php file.
| | 00:52 | Go to views>activities and then open up
view.html.php and paste this function in.
| | 01:00 | And then we are also going to want to add
this adtoolbar call into the display function.
| | 01:07 | So after you save that go back to the
backend and hit Refresh and magically you
| | 01:14 | see a title for the screen and you see
all of these different toolbar buttons.
| | 01:18 | So let's see what actually happened.
| | 01:21 | First, we have the title
function of JtoolBarHelper.
| | 01:25 | This JtoolBarHelper::title function is
receiving one argument and that is the
| | 01:31 | title that we want to display.
| | 01:33 | So we are using JText to
translate the language string
| | 01:36 | COM_EXPLORE_ACTIVITIES_TITLE and its
returning California Activities that's
| | 01:41 | being displayed here on the left.
| | 01:43 | And then next we have addNew edit list,
a divider, publishList, unpublishList, a
| | 01:50 | divider then archiveList and trash,
it displays all these different toolbar
| | 01:57 | buttons along with divider so we
can visually separate different tasks.
| | 02:02 | So for instance, we have a New task
and an Edit task here and we want to
| | 02:06 | visually separate that from the
publishing and the unpublishing and we
| | 02:09 | definitely want to separate that from trash.
| | 02:12 | All we had to do was add
these functions and Joomla
| | 02:15 | takes care of displaying the buttons.
| | 02:17 | The arguments that we are passing into
these functions are the task names that
| | 02:21 | we want to assign to these buttons.
| | 02:23 | So what will happen is whatever we click on
say editList button that is going to tell Joomla
| | 02:29 | to fire off the Activity Edit task.
| | 02:33 | Adding toolbars to your Joomla
| | 02:34 | component is simplified through
the use of standard functions.
| | 02:37 | You don't have to worry about getting
the markup right or lining things up, the
| | 02:40 | class handles this automatically.
| | 02:42 | When you create toolbar buttons,
they're loaded with tasks and when clicked,
| | 02:46 | those buttons submit the
task along with the form.
| | Collapse this transcript |
| Publishing with Controller Admin and Model Admin| 00:00 | While the majority of the
request going to Joomla
| | 00:02 | end up displaying a view, this
is not the case for all of them.
| | 00:06 | When records are published from a
backend list screen, a controller task is
| | 00:09 | called to do the publishing.
| | 00:11 | To handle publishing in
other backend tasks Joomla
| | 00:14 | has specially coded controllers and models.
| | 00:16 | So let's add some of those
controllers and models now to our backend.
| | 00:19 | First, let's login to the backend.
| | 00:21 | We are going to login as
admin with lynda as the password.
| | 00:26 | And now let's go to Components>
Explore California and Activities.
| | 00:30 | So this is a list screen
that we have from before.
| | 00:34 | If we click on Publish our Unpublish
right now, nothing happens because we
| | 00:38 | haven't added some things that we need
for the view and we also need to add some
| | 00:42 | controllers and model
code to make this all work.
| | 00:46 | Let's get started with that.
| | 00:47 | Go to your Exercise Files and look
in the models folder and you'll notice
| | 00:51 | an activity.php file.
| | 00:53 | You're going to want to copy that into the
models folder of the backend of your component.
| | 00:57 | So copy activity.php into the models
folder and let's have a look at it.
| | 01:04 | So this is a model and it's a type
of model that is the admin model.
| | 01:09 | It's not a list model or does a plain model;
| | 01:12 | it's an admin model and Joomla
| | 01:13 | knows that admin models are used to
work with specific rows in the database
| | 01:19 | and because of that it's going to need to
know which kind of row we want to work with.
| | 01:23 | So to do that we have a getTable
function and that is going to return a JTable
| | 01:29 | object, just like we used in the front
end to display a single record from the
| | 01:34 | database and we are just adding the type
of record that it is and the prefix and
| | 01:40 | it's going to assemble all of that
together to load up the ExploreTable activity
| | 01:43 | class, create an object and return it.
| | 01:47 | And then next the model also
makes us define the getForm function.
| | 01:50 | We are not really dealing with the form
that's going to edit the activity yet,
| | 01:55 | but we're still required to
define it by the JmodelAdmin class.
| | 02:00 | So we just define getForm and we called
this loadForm and that's enough to make Joomla
| | 02:06 | be happy with the modelAdmin
class that we are defining here.
| | 02:11 | So after we are done with that, let's go
and add the controller that is going to
| | 02:15 | receive the tasks from the
toolbar buttons and talk with the model.
| | 02:19 | So just copy this entire controllers folder
over into your com_explore folder in the backend.
| | 02:27 | And you'll notice we have one file in
here called activities.php and inside that
| | 02:32 | file, we have a JControllerAdmin class.
| | 02:36 | It starts off with a protected
property called text_prefix and this is used
| | 02:42 | for the language strings because
we're going to have some status message
| | 02:46 | updates that appear on screen and
we need to know what prefix to use to
| | 02:51 | assemble those language strings.
| | 02:53 | So com_explore activities is a prefix we
are using and we are just defining it here.
| | 02:58 | And now the JControllerAdmin class
wants us to define a getmodel function, so
| | 03:03 | that it knows what model to get so that
we can use that to talk to the database,
| | 03:07 | when we are dealing with individual records.
| | 03:10 | That getmodel function takes the name
of the model and then the prefix with
| | 03:14 | their model, and then it assembles all
that for Exploremodel activity, and then
| | 03:19 | it loads up the Activity
model and just returns it.
| | 03:23 | And in that way the different tasks
that are embedded in JControllerAdmin can
| | 03:27 | call up that model and work with the table.
| | 03:31 | So finally we need to update the
view with a little bit of code that
| | 03:34 | allows those toolbar buttons to
work, so that way it actually does
| | 03:37 | something and submits the form.
| | 03:39 | Go to views and activities in your
Exercise Files and go into the tmpl folder
| | 03:45 | and open up default.php.
| | 03:47 | This default.php file is very similar,
almost exactly the same as the one
| | 03:52 | that's there currently.
| | 03:54 | Only there are three more
items at the bottom of the form.
| | 03:58 | Copy those items and paste them into your view.
| | 04:01 | Go to views>activities>
tmpl and open up default.php.
| | 04:07 | Then scroll to the bottom of the form
and just before the closing form tag,
| | 04:11 | paste in those three elements.
| | 04:15 | So you'll notice the first element is
the hidden task element and this element
| | 04:20 | is here so that whenever we click on
one of the toolbar buttons, the toolbar
| | 04:24 | button will take the task that's been
assigned to it and assigned it as the
| | 04:27 | value here and then submit the form.
| | 04:30 | Next, we have the boxchecked hidden
element and what this element does, is
| | 04:35 | it keeps track of how many check
boxes have been checked off on the left
| | 04:39 | side of the screen.
| | 04:41 | And then finally we have this form.
token element at the bottom and what this
| | 04:46 | does is it thwarts off Cross-
site request forgery attacks.
| | 04:50 | It makes sure that the person that is
submitting this form is the actual person
| | 04:54 | that did it and not some other
script that's on the Internet.
| | 04:58 | So with these three elements in place,
let's save the form and close out the file.
| | 05:04 | Go back to the backend and hit Refresh
and when we check off a couple of these
| | 05:08 | records and hit Unpublish, it now
unpublishes those records and it says 2
| | 05:14 | activities unpublished.
| | 05:16 | So what happened is there is a
task here for Unpublish called
| | 05:20 | activities.unpublish that we added
to our view in the toolbar video, it's
| | 05:26 | submitted that the form along with the
values in these two check boxes, told the
| | 05:31 | controller to unpublish those records,
then the control pass those to the model
| | 05:36 | and the model did the work
of unpublishing the records.
| | 05:39 | Then the controller redirected the
browser back to the Activities view.
| | 05:44 | So when you want to do something aside
from displaying views, that task built
| | 05:47 | into ControllerAdmin will
handle most of your backend needs.
| | 05:51 | Hooking a modelAdmin class will give your
ControllerAdmin the ability to talk to the database.
| | 05:56 | And having the right HTML variables
into view, make it possible for users to
| | 06:00 | fire specific task by
clicking at toolbar button.
| | Collapse this transcript |
| Paginating results| 00:00 | Database tables quickly fill up with
rows when components are used often.
| | 00:04 | If there are too many records in the
database table your list view will take
| | 00:07 | a long time to load.
| | 00:09 | To avoid this, let's
paginate the Activities list.
| | 00:11 | So let's go to the backend
and open up that list first.
| | 00:14 | Go to Administrator.
| | 00:16 | I am logging in as admin and lynda.
| | 00:18 | Then go to Components>Explore
California and Activities and you will notice we
| | 00:24 | have all the records here.
| | 00:27 | Let's paginate these records.
| | 00:29 | So let's go to the Exercise Files and
open up views>activities and view.html.php.
| | 00:38 | This file is almost exactly the
same as the view.html.php file that's
| | 00:42 | currently there, only we have added this
pagination object that we are getting from the model.
| | 00:47 | Now even though we don't have a
getPagination function that's specifically
| | 00:51 | defined in our model that is getting
inherited from the model list class, that
| | 00:57 | our model is based on.
| | 00:58 | So it's getting this pagination
object just automatically and we are
| | 01:02 | assigning it to the view.
| | 01:03 | So let's copy and paste this code
into our view for the activities.
| | 01:07 | Go to view.html.php and open it and
then copy the place where the pagination
| | 01:15 | gets assigned, also copy in the
protected $pagination property.
| | 01:25 | Save this view.html.php file and
now let's make one more adjustment.
| | 01:30 | We are going to go to the layout and
open up default.php in the Exercise Files.
| | 01:36 | This is very similar to the layout that
we have from before, only we are adding
| | 01:40 | this tfoot section to the table.
| | 01:43 | So let's copy this tfoot section and
paste it into the layout of our file.
| | 01:50 | So in default.php scroll up to the top
here and just underneath thead add tfoot.
| | 01:55 | Now one thing you notice is that even
though it's the footer that we are going
| | 01:59 | to have at the bottom of this list,
you can put it anywhere inside the table
| | 02:03 | element and the HTML will
render it in the right place.
| | 02:08 | Another thing to note is that a
colspan here for the table cell here is 4 and
| | 02:14 | that matches the number of
columns that we have in the table.
| | 02:16 | So that way we have this pagination
here at the bottom of the list and it's
| | 02:21 | going to span all the columns.
| | 02:23 | And then all we do is echo out this
pagination->getListFooter and this
| | 02:28 | getListFooter function is going to
automatically generate all the pages we
| | 02:32 | need for this list.
| | 02:34 | So after saving this file and going back
to the backend, hit Refresh and go down
| | 02:39 | to the bottom of the list.
| | 02:40 | You will notice that down here we now
have this drop down for the Display number.
| | 02:44 | It's currently set at 20, but we only
really have nine records in the database.
| | 02:49 | Let's set this down to 5 so that we
can see some pagination in action.
| | 02:52 | So you'll notice now that we have it
set down to 5, we have the first five
| | 02:57 | records in the database.
| | 02:58 | We can use the number 2 to get to
the second page of results, and then we
| | 03:02 | can use the Previous and Next buttons to
page through as well the Start and End buttons.
| | 03:09 | Let's set this list back to 20 and now
it displays all the records on one page.
| | 03:16 | When a model list is being used to get
records from the database table, it's
| | 03:19 | possible to add pagination to
the list with a few lines of code.
| | 03:23 | All of the page numbers and record
limiting are automatically handled in
| | 03:26 | the model.
| | Collapse this transcript |
|
|
8. Filtering and SearchingFiltering records by state| 00:00 | Once admins began publishing,
unpublishing, archiving and trashing activities,
| | 00:05 | the list will become a mixture of
both irrelevant and relevant records.
| | 00:09 | To help admins find the records they are
looking for let's add a drop-down filter.
| | 00:13 | So let's go to the backend and log into Joomal!.
| | 00:15 | We are going to login as admin
and lynda and we are going to go to
| | 00:22 | the Activities list.
| | 00:24 | So right now we have both the
unpublished records and the published records
| | 00:28 | being displayed in our list and we want
to add a filter, so that admins can just
| | 00:33 | find all of the published records or
just all of the unpublished ones.
| | 00:38 | So let's go to the Exercise Files and
pull some code that will help us do this.
| | 00:41 | First let go to the models and go to activities.
| | 00:49 | What we need to do is, tell the
model to only return the published or the
| | 00:54 | unpublished records based
on what the admin chooses.
| | 00:58 | So first we need to add in
this populateState function.
| | 01:04 | So open up models and
activities and paste this function in.
| | 01:12 | What this function does, is it checks
both the session and the form variable to
| | 01:16 | see if we have a value for
the filter published variable.
| | 01:20 | And if we do have a value, we are going
to set it in the state of this model, so
| | 01:26 | that whenever we go and get
that state we can get that value.
| | 01:29 | So now we are going to apply this value
that's being populated in populateState.
| | 01:38 | Copy this code all the way from
published = down to the end of the if statement.
| | 01:43 | So copy this code from the Exercise File
into the model that we have already in place.
| | 01:49 | So we are going to save that file and
you will notice here we are getting the
| | 01:53 | published property from the state of
the model and the publish property gets
| | 01:58 | populated down here in populateState
and then regardless of what this value is
| | 02:03 | it set into published.
| | 02:05 | So if we have no value for published,
we want the query to get both the
| | 02:09 | published and the unpublished articles,
but not the trashed or the archived ones.
| | 02:14 | However, if it's set to anything but
the star variable we want it to get the
| | 02:21 | value of published and have the query only
get the state that published this set too.
| | 02:29 | So for instance, if the admin wants to
display all of the published records,
| | 02:33 | this value is going to be 1 and
otherwise if it's the unpublished records that
| | 02:38 | the admin wants it's going to be a 0.
| | 02:41 | And then we just add that to
the query in a where statement.
| | 02:45 | After we save this model and we go back
to the backend and hit Refresh, you'll
| | 02:49 | notice that nothing is changed
because we haven't really added a filter yet
| | 02:52 | for the admin to use.
| | 02:54 | So let's add a filter now
so that the admin can pick.
| | 02:59 | Go to the views folder in the
Exercise Files and in there, there is an
| | 03:03 | activities folder and then a view.html.php file.
| | 03:07 | So open up this file and you'll notice
we now have a call here to get state and
| | 03:13 | this is going to get that state
that is being set in populateState.
| | 03:18 | So that way we can always have
the value that's been entered.
| | 03:22 | So let's copy this call into our views.
| | 03:26 | Let's go to activities and view.html.
php and just like we have done for several
| | 03:32 | of the other variables, we are
going to copy this call into our file.
| | 03:37 | We are also going to copy the state
property over, so that we can do that as well.
| | 03:43 | And now save this file and finally
we're going to add the filter to the form so
| | 03:49 | that admins can pick.
| | 03:51 | So open up default.php from the
Exercise Files and copy this fieldset element
| | 03:56 | right here that's up at the top of the
file and then open default.php in your
| | 04:01 | component and then add that
element to the top of your form.
| | 04:07 | So you will notice here there are a
few elements within that fieldset.
| | 04:11 | We have a class of filter-select and
this is short for float right, so these
| | 04:18 | elements are going to appear on the
right-hand side of the screen, and then we
| | 04:22 | have it select with name filter_published
and that matches what we set in
| | 04:26 | populateState in the model.
| | 04:29 | And then we have a JText call to OPTION_
SELECT_PUBLISHED and this is a language
| | 04:35 | string that's included with Joomla
| | 04:36 | so we don't have to create a language
string for published, its just going to be there.
| | 04:42 | And then finally we have another
JHtml call and this one is calling up
| | 04:46 | select.options and select.options is a way of
generating a list of options for a select list.
| | 04:54 | The options that we are passing in
for this select list are going to be a
| | 04:58 | standard set of options that Joomla
| | 04:59 | already has defined, so we don't have
to go through and generate them and those
| | 05:04 | can be called up thtough JHtml, jgrid.
publishedOptions and that's going to give
| | 05:09 | us options like published,
unpublished, archived and trashed.
| | 05:13 | Now given the jgrid.publishedOptions,
these next two values determine what
| | 05:18 | properties of the objects that are
returned by this function, are used to set
| | 05:22 | the value in the text for each option.
| | 05:25 | So in most cases this is simply value and text.
| | 05:28 | And then finally, we're getting the
state of filter published from the model and
| | 05:34 | this is allowing us to get what has
been selected already and show that as the
| | 05:39 | selected item on this drop down.
| | 05:41 | So if you save this file and go back
to the backend and hit Refresh, you will
| | 05:47 | notice now we have a drop-down for
Select Status and if we select Published, its
| | 05:52 | now only going to show the published
items and if we select Unpublished its only
| | 05:57 | going to show the unpublished items.
| | 05:59 | Let's set it back to Select Status and it's
going to show both published and unpublished.
| | 06:04 | Through the model and the request
state it's possible to filter records.
| | 06:08 | Using the same model state the drop-down
in the view reflects the chosen value.
| | 06:12 | This makes it possible for admins to
filter just the records that they want
| | 06:15 | to see.
| | Collapse this transcript |
| Searching tables| 00:00 | Sometimes admins will know exactly
what they're looking for, but they just
| | 00:03 | need a way to find it.
| | 00:04 | Adding a Search Filter will help with this.
| | 00:07 | So let's go to the Backend and add one.
| | 00:10 | Log in as admin with the password lynda.
| | 00:15 | Let's go to Components>
Explore California>Activities.
| | 00:18 | So you'll notice on the right-hand
side of this screen, we have the drop-down
| | 00:22 | for Select Status that currently
filters Published and Unpublished records.
| | 00:26 | We're going to add a search box on the
left side of this screen that will help
| | 00:30 | admins search for specific records.
| | 00:32 | So let's go to the Exercise Files and do it.
| | 00:35 | Go to the models folder in your
Exercise Files, and open up the
| | 00:38 | activities.php file.
| | 00:40 | You will notice in here
that we've added a few things.
| | 00:43 | We've added another couple of lines
into the populateState function and this is
| | 00:48 | pulling whatever value people enter
in the form that we're going to add and
| | 00:52 | stores it into the model state.
| | 00:54 | So copy those two lines and then go to
the models folder in your component, and
| | 00:59 | open up activities.php.
| | 01:03 | Add these two lines to the top of
that function, and then save the file.
| | 01:07 | Now that we are setting the search
value in the model state, we can take that
| | 01:12 | value and use it to build more of the query.
| | 01:15 | So let's copy and paste some
more of that query code as well.
| | 01:20 | So copy everything from this search on
down through the if statement, and then
| | 01:25 | just paste it right here above the return.
| | 01:30 | So now, we're getting the search value
from the model state and once we have
| | 01:35 | that available, we also get the
database object and store that in db.
| | 01:40 | And then, we check the search variable
to make sure it's not empty, and if it's
| | 01:45 | not empty, that means that we want
to do a search on this database table.
| | 01:50 | Next, we need to prepare this search
variable so that it's ready to go into
| | 01:54 | the database query.
| | 01:55 | So to do that, we need to call the
getEscaped function on the database object
| | 01:59 | and that will return a version of the
string that's escaped and ready to go
| | 02:04 | into the database query.
| | 02:06 | This is important because the
getEscaped function will make sure that the
| | 02:10 | string that comes back is ready to go
in the query because otherwise, it's
| | 02:14 | possible that an admin might type-in an SQL
command by accident and that would break the query.
| | 02:20 | So this step is very important because it
makes sure that our queries don't break.
| | 02:24 | We're also passing in the true argument
here because we're letting getEscaped to
| | 02:28 | know the we're doing this as a part
of a LIKE statement, and the rules for
| | 02:32 | escaping LIKE statements
is a little bit different.
| | 02:35 | Then finally, we're wrapping the
string around in percent signs, and we're
| | 02:38 | using those to say, match this string
and anything before it and anything after
| | 02:43 | it in these columns.
| | 02:45 | So finally, with the search
string in place, we can build our
| | 02:48 | field_searches variable here.
| | 02:49 | We're matching it against the
activity_description and the activity_name, and
| | 02:54 | then we're adding that to
the where clause of our query.
| | 02:57 | Let's add a box to our form
where people can perform searches.
| | 03:01 | Let's go back to the Exercise
Files, and pick up this box;
| | 03:04 | go to views>activities>tmpl and then
open up default.php, and then up at the top
| | 03:12 | of this file is a div that has the box
as well as a few buttons for people to
| | 03:18 | click to do searches.
| | 03:20 | So just copy that entire div and then
go to the views folder in the backend of
| | 03:25 | your component, and go to the
layout, open it and paste-in that div.
| | 03:32 | So you'll notice that this div is very
similar to the other divs that's in this field set.
| | 03:38 | The div has a class of
fltlft and that's telling Joomla
| | 03:42 | to put it on the left-hand side of the screen.
| | 03:44 | We also have an input box here that is
pre-filled with whatever previous search
| | 03:49 | the user has entered in, and then we
have a button for Submit which will submit
| | 03:53 | the form and perform the search.
| | 03:56 | We also have one more button here for
Reset, and what that does is it goes back
| | 04:01 | and finds this text input,
clears it and then submits the form.
| | 04:06 | It does this through
JavaScript in the onClick event.
| | 04:09 | So after we've saved this file, go
back to the backend and hit Refresh.
| | 04:13 | Now, we're going to try a
search now that should work.
| | 04:18 | However, it's pulling up more than just
the one Backpack record that we want and
| | 04:23 | there's a reason for this.
| | 04:25 | If you go back to the activities.php
file, you'll notice that we have several
| | 04:30 | different where statements.
| | 04:32 | Now, whenever you call the where
statement on the query object, it's going to
| | 04:37 | join all of those statements together
with ands, and sometimes you don't want an
| | 04:42 | and glaring this together, or
you don't want the results of that.
| | 04:46 | Sometimes what you need to do is close
one of your statements in parentheses.
| | 04:53 | So what we want to do is enclose this
condition that's asking whether or not the
| | 04:57 | record is published, and then
that way, the query will be correct.
| | 05:02 | So after we save and go back to the
backend, and hit Refresh now it just pulls
| | 05:06 | up the one record that we want.
| | 05:08 | When we click Clear, it clears
the input and resubmits the form.
| | 05:12 | Also, let's try typing in
California, or just cal.
| | 05:18 | Notice that all the items in here have
cal in some form or fashion, and if we
| | 05:24 | use the pagination, we can paginate
through the results, and it still keeps the
| | 05:29 | filter value in here as we paginate.
| | 05:31 | The effort spent on adding a search box
to a component is small in comparison to
| | 05:35 | the benefits for site administrators.
| | 05:37 | Just be sure to do escape values
before you put them in your query and before
| | 05:41 | you display them in the search box.
| | Collapse this transcript |
| Sorting columns| 00:00 | Admins will sometimes want to sort the
table results as they scan through the records.
| | 00:04 | Let's add some links and some
database code to help with the sorting.
| | 00:07 | So let's go back to the backend and login.
| | 00:11 | We're going to login as admin and lynda.
| | 00:15 | Go to Components>Explore California>
Activities and you'll notice here that we
| | 00:19 | have table headers for Name,
Description, and Status.
| | 00:23 | We're going to add some code that will
allow us to sort by all of these columns.
| | 00:26 | So let's go to the Exercise Files.
| | 00:29 | First, open up the models
folder and open up activities.php.
| | 00:34 | At the top of activities.php, we're
now overriding the constructor for
| | 00:39 | ExploremodelActivities.
| | 00:41 | In this constructor, what we're doing
is we're adding a list of fields that
| | 00:44 | are valid for sorting.
| | 00:45 | So let's copy this constructor and
paste it into our existing model.
| | 00:49 | Go to models>activities and open it.
| | 00:52 | Let's go up to the top,
and add this constructor.
| | 00:57 | So now we're overriding the default
constructor and pulling in the configuration
| | 01:02 | array that gets passed in, and if the
filter_fields array is empty, we just want
| | 01:07 | to fill it with the fields that we
think are the ones that are valid.
| | 01:10 | So the filter_fields element of this
array is going to contain an array of all
| | 01:15 | the fields that are valid, and then
finally we call the parent constructor.
| | 01:20 | Next, let's take a look at populateState.
| | 01:23 | Down here at the bottom you'll notice
that ordering and direction are already
| | 01:28 | a part of populateState and they're already a
part of populateState in our function as well.
| | 01:33 | Since ordering is a very major part
of filtering and searching, Joomla
| | 01:38 | just includes this by default and
assumes that you're going to start using it.
| | 01:41 | So we don't have to do anything
to the populateState function.
| | 01:45 | Finally, we're going to look at getListQuery.
| | 01:49 | We do have to change our
list query a little bit.
| | 01:51 | Copy everything from this Column
ordering comment down to the bottom of the
| | 01:55 | if statement and paste this into the bottom of
the getListQuery of the model in your component.
| | 02:01 | So what this is doing is getting the
list ordering and the list direction for
| | 02:07 | this screen and it's storing
it in two different variables.
| | 02:11 | And first, we test to see if we have a
column that we want to sort by, and if a
| | 02:15 | column is set, then we call the order
function on the query object, and then we
| | 02:20 | pass-in the column and the direction,
and we escape them in the database object.
| | 02:25 | Let's save this model and move over to the view.
| | 02:28 | Go to the views folder in your
Exercise Files and open up the layout.
| | 02:37 | Go up to the top of the screen, and
first we have two variables that we're
| | 02:41 | getting from the state;
| | 02:43 | we're getting the ordering and the direction.
| | 02:45 | So we're going to copy these two
variables right into our layout.
| | 02:48 | Go to views>activities, and go to
the layout and open up default.php.
| | 02:55 | Make a little room, and add those
two variables to the top of the layout.
| | 03:01 | So now that we have those two
variables handy, we're going to keep using them
| | 03:04 | throughout the rest of this file.
| | 03:08 | Next, what we want to do is replace the
headers with headers that are sortable.
| | 03:12 | So copy these three headers from the
Exercise Files and paste them into the view.
| | 03:22 | You'll notice that we're calling
JHtml grid.sort and we're passing in the
| | 03:26 | language strings along with the name
of the column we want to sort, and then
| | 03:31 | along with the current values for the
list direction and the list order, and
| | 03:35 | this is happening for each one of these headers.
| | 03:37 | So this way, Joomla
| | 03:38 | will generate appropriate links based
on what the current value of the list
| | 03:43 | direction and order are and then when
people click on those links, a JavaScript
| | 03:47 | will go in, and fill some inputs
that will order the list correctly.
| | 03:52 | Let's add those inputs now.
| | 03:53 | Go back to the Exercise File, and go
to the bottom of the screen, and pick up
| | 03:58 | the filter_order and filter_order_Dir variables.
| | 04:03 | Scroll down to the bottom
and paste in those variables.
| | 04:08 | For the values, we're just using the
values that are coming in from the request,
| | 04:13 | and if someone clicks on one of the
links up here in the headers, that link will
| | 04:18 | automatically go back down here and
set these variables appropriately.
| | 04:22 | So now with all this in place, let's go
back to the View, Refresh and see what happens.
| | 04:28 | So now these headers have turned into links.
| | 04:31 | We have a link for Name, for
Description and for Status.
| | 04:34 | Let's sort by Name.
| | 04:35 | So now that's sorting it in ascending
order, so we're starting with B, and then
| | 04:39 | C, and then F and if we click on it
again, it will sort it in descending order.
| | 04:44 | So it's starting with Taste of
California and going to S and N and K. Same goes
| | 04:49 | for the Description column,
as well as the Status column.
| | 04:53 | With links in place, the
Activities table is now sortable by Name,
| | 04:57 | Description, and Status.
| | 04:58 | The JHtml grid.sort function generates
links that call JavaScript, setting the
| | 05:03 | appropriate form variables for sorting.
| | 05:05 | Finally, the model adds sorted fields
to the list query just like the filters.
| | Collapse this transcript |
|
|
9. Back-End FormsBuilding an Edit view| 00:00 | The main reason we're building a backend
for the Explore California component is
| | 00:04 | so that admins can edit and create new
records, just like list views and single
| | 00:08 | views in the front end, there are list
views and form views in the back end.
| | 00:12 | Let's add a new form view
now for editing an activity.
| | 00:16 | Let's login to the back end of the site.
| | 00:18 | Use admin as the username
and lynda as the password.
| | 00:22 | Go to Components>Explore California and
Activities, and right now try to click
| | 00:27 | on the New button and you'll notice
that we get an error and that's because we
| | 00:31 | don't have a controller or view in
place to handle that new activity task.
| | 00:36 | So go back and let's add a
controller first to handle that task.
| | 00:43 | Go to the controllers folder in the
Exercise Files and copy activity.php into
| | 00:49 | the controllers folder of
the back end of your component.
| | 00:52 | Let's take a look at activity.php.
| | 00:55 | You'll notice that we don't have any
tasks defined, because we're just using the
| | 00:59 | tasks that are already
defined in JControllerForm.
| | 01:02 | There is an edit task as well as a
save task and we're just going to use the
| | 01:07 | edit task that's available in
JControllerForm for our component.
| | 01:11 | And then the other thing that you'll
notice is that we have this protected
| | 01:14 | property called view_list and view_list
is being set to activities and what this
| | 01:20 | view_list property does is it tells
JControllerForm what list view we're using
| | 01:26 | to base this record off of.
| | 01:28 | And that way when we were done saving
the record or when we cancel out of it, or
| | 01:31 | we're just done using that form, this
controller will know to redirect us back
| | 01:36 | to the activities view instead
of any other view on the system.
| | 01:40 | So now we need to add the actual view
that's going to hold the form where our
| | 01:45 | record is going to be displayed.
| | 01:46 | So let's go to views and
you'll see this activity folder.
| | 01:51 | So copy this activity folder from the Exercise
Files into the views folder of your component.
| | 01:59 | You'll notice that just like all of
the other views there is a view.html.php
| | 02:02 | file and inside that we
have several things going on.
| | 02:06 | First we're getting an item from the model.
| | 02:09 | We already have an activity model in
place, so we're getting it from that
| | 02:13 | model and no where else.
| | 02:15 | Then we're adding a toolbar
through the addtoolbar function.
| | 02:18 | So given that we have the item that we
pulled from the model we're going to test
| | 02:22 | the activity ID property of that item to
see whether we need to edit a record or
| | 02:27 | whether we're doing a brand-new record.
| | 02:29 | If we're trying to do a brand-new
record this item is not going to return an
| | 02:34 | object, it's just going to return null or false.
| | 02:37 | So if this->item->activity_id is
false, it's going to go to this else
| | 02:42 | statement and change the title to say
we're adding an activity rather than
| | 02:46 | editing an activity.
| | 02:48 | And then beneath the title function call, we
have four more function calls to JtoolBarHelper.
| | 02:53 | One for an apply button, one for a
save button, one for a save2new button and
| | 02:58 | one for a cancel button.
| | 02:59 | So with all these buttons in place,
let's go back to the back end and click that
| | 03:03 | New button and see what happens.
| | 03:06 | You'll notice now we have all four of
these buttons for Save, Save & Close, Save
| | 03:10 | & New and Cancel and the title says
Add California Activity instead of Edit
| | 03:16 | California Activity.
| | 03:17 | Let's take a look at the HTML
that's generating this part.
| | 03:22 | Go back to the view and go to tmpl and
you'll notice that instead of default.php
| | 03:27 | it's called edit.php, and
this is important because Joomla
| | 03:31 | is using this as a way of securing this
view against people who are not allowed
| | 03:36 | to edit these records.
| | 03:38 | So in this case at the moment we just
have a simple form, we have a form that's
| | 03:42 | pointing back to the explore component
and we already have the activity_id baked
| | 03:47 | right into the form.
| | 03:48 | So this way we know that we're dealing
with this specific record and Joomla
| | 03:53 | can lock or keep it away
from admins as necessary.
| | 03:56 | We also have a hidden task variable
that's going to receive any of the values
| | 04:01 | from the buttons that we click.
| | 04:03 | And then again, we have a form.token
variable and this is to protect against
| | 04:07 | Cross-Site Request Forgery attacks.
| | 04:09 | So similar to the front end of the
component the backend has list views and edit views.
| | 04:14 | Instead of linking directly to the edit
view the link points to controller task
| | 04:18 | which make sure that the user
has permission to edit the record.
| | 04:21 | This controller also takes the user
back to list screen after saving or
| | 04:25 | canceling out of the edit view.
| | Collapse this transcript |
| Using JForms| 00:00 | HTML forms are major part of any web
application and Joomla is no exception.
| | 00:06 | Joomla has a library called JForm which is
entirely dedicated to building forms.
| | 00:10 | It handles not only the display of forms
but also the validation of form elements.
| | 00:14 | Let's add a JForm for editing activities.
| | 00:17 | Log into the backend of the site with
the username admin and the password lynda.
| | 00:23 | Let's go to Components>Explore California and
Activities and then click New to get that view.
| | 00:29 | So right now we have the view for
Adding a California Activity, but we don't
| | 00:32 | have a form to go with it.
| | 00:33 | So let's add that form.
| | 00:35 | Go to the Exercise Files and go to
models and you will notice in the models
| | 00:39 | folder there is the forms folder.
| | 00:41 | Copy this forms folder into the models
folder of the backend of your component.
| | 00:45 | When we go to that forms folder and
open activity.xml, we see an XML file with
| | 00:51 | a form element at the root, and then a
fieldset element directly nested inside there.
| | 00:57 | You can have as many fieldset elements
as you want, but in this case we are just
| | 01:00 | going to start with one.
| | 01:01 | We are starting off with a
hidden activity_id as our first field.
| | 01:05 | Every field is going to have a name and a type.
| | 01:08 | So in this form you will notice a
hidden element, you will notice a text
| | 01:11 | element, there will be a list element
and a couple of other elements that are
| | 01:14 | there as different types of form
elements that will either be displayed or just
| | 01:18 | embedded directly on the form.
| | 01:20 | Then you will have a label and a
description for every form element.
| | 01:23 | The label will display right next to
the element, if it's not a hidden element
| | 01:27 | and the description will
display when you mouse over the label.
| | 01:31 | Then you have other parameters here
like size and default and class and those
| | 01:36 | are roughly the same as doing the size
and value and class parameters on any
| | 01:42 | other input element that you
would do in a regular form.
| | 01:45 | This field element also has readonly
set to true and this adds a bit of HTML to
| | 01:51 | tell the browser not to let
anyone edit this form element.
| | 01:56 | Aside from the hidden elements, we have text
elements and those just appear as text boxes.
| | 02:00 | You can also mark elements as required.
| | 02:04 | JForm will make sure that a value is
set for that element if it's required.
| | 02:10 | Further on down in our JForm, we also
have a list type of element and this
| | 02:15 | element just provides a couple of
different options for the user to choose from
| | 02:20 | and doesn't allow the user
to choose any other options.
| | 02:24 | This element also has a filter on it
for intval and that stands for integer
| | 02:27 | value, and JForm is going to ensure
that any value that goes into this element
| | 02:33 | is always an integer.
| | 02:34 | Finally, we have an element here that's
of type media, and what this is going to
| | 02:38 | do is it's going to allow the user to
click a button and pull up the Joomla
| | 02:42 | Media Manager and pick an image or
some other type of media from the system.
| | 02:47 | So now that we have the JForm as an XML
file, let's modify the model, so that it
| | 02:52 | can read this XML file and bring up that JForm.
| | 02:55 | Pull up activity.php from the Exercise Files.
| | 02:59 | One line has changed in this file and it's
the one that loads the form and get form.
| | 03:04 | So copy this line and then go to activity.
php in your Component and replace that line.
| | 03:10 | So in this case, we are setting up the
context in the first argument here, so
| | 03:16 | com_explore.activity is going to be
the session variable where any data that
| | 03:21 | gets entered into the form is going to
be stored, and in that case, if we ever
| | 03:25 | need to redirect the user back to this
form to fill out say a missing field or
| | 03:30 | correct some other sort of error,
that date is going to be stored in the
| | 03:33 | session, so we can pull it out again,
so that the user doesn't have to type
| | 03:36 | everything all over again.
| | 03:38 | The next argument is the name
of the form that we want to load.
| | 03:42 | So, since we want to load activity.xml,
we simply add activity as this argument,
| | 03:47 | and then the final argument
is an array with configuration.
| | 03:51 | Next, let's actually add this form to
the view, open up the views folder in the
| | 03:55 | Exercise Files and then open view.html.php.
| | 04:00 | Inside here, all we are doing is
getting the form from the model and
| | 04:03 | assigning it to the view.
| | 04:04 | So go to views and activity and then open
up view.html.php and copy that get statement.
| | 04:11 | So we are going to get this->form and
assign it to the view, and then we are
| | 04:16 | going to add that form property,
so that it can store it there.
| | 04:19 | So now that we've added this form to
the view from the model, let's go into the
| | 04:24 | layout and add that form to the layout.
| | 04:28 | Open edit.php and copy this div that's
right here just inside the form, go over
| | 04:36 | to the layout in your Component,
open it and then paste in that div.
| | 04:41 | So you'll notice with this div,
there are two classes that are set on it;
| | 04:45 | one is width-60 and the other one is fltlft.
| | 04:48 | And the first one tells the div to
only be 60% of the width of the screen and
| | 04:54 | the second one tells it to float on the left.
| | 04:57 | Next we have a fieldset with class
adminform and then after that we are cycling
| | 05:01 | over every field in the field set
and outputting it as a list item.
| | 05:05 | So this getFieldset function is going
to return every field in the JForm as an
| | 05:10 | object, and then we can output
the label and the input on the form.
| | 05:14 | So let's go back here and hit Refresh.
| | 05:17 | So you'll notice now we have the Name,
Alias, Status and Activity Photo on this form.
| | 05:22 | JForm provides a way of defining
elements of a form without worrying about
| | 05:26 | the specific layout.
| | 05:28 | It also serves as a way for typing fields.
| | 05:30 | Once the form is loaded in the
model, the view can retrieve it and
| | 05:33 | finally display it.
| | Collapse this transcript |
| Loading JForms data| 00:00 | Well, JForm by itself is great for
generating a form with different field types.
| | 00:04 | It's most useful when it
can be preloaded with data.
| | 00:07 | Let's make an adjustment to the
activity model so we can edit existing records.
| | 00:11 | First let's log into the backend with
the User Name admin and the Password
| | 00:15 | lynda, and go to the Activities list
and try to edit one of these records.
| | 00:22 | You'll notice that even though we've
picked a specific record for editing we
| | 00:25 | don't see any of the data, we do see
the correct title here for editing a
| | 00:29 | California Activity but we don't
see any of the data in the form.
| | 00:33 | So let's add something to the model that
will load that data right into the form.
| | 00:38 | Let's go to the Exercise Files and go
to Loading JForm Data, go to models and
| | 00:44 | go to activity.php.
| | 00:47 | There's a new function in this file
called loadFormData, so just copy it from
| | 00:51 | the Exercise Files and paste it into the
model activity in the backend of your component.
| | 01:02 | So you notice we have loadFormData
here and first we attempt to get the data
| | 01:07 | from the session, this is important
because if someone is entering data into the
| | 01:12 | form it might not necessarily match
what's in the database, or it might not even
| | 01:17 | exist in the database yet if it's
a new record that's being entered.
| | 01:21 | So what we want to do is if someone
is being redirected back to this form
| | 01:25 | because they needed to correct a
mistake or did not enter a required field we
| | 01:30 | want to load that data again and
display it back in the form instead of loading
| | 01:34 | stuff from the database.
| | 01:36 | However, if we don't have any data
from the session we want to pull the
| | 01:40 | data from the database.
| | 01:41 | So we use this getItem to get that
data if it doesn't exist in the session.
| | 01:46 | Finally, we would return whatever data
whether it came from the database or the
| | 01:49 | session and have it go back to the JForm.
| | 01:51 | So now with this function in place
let's go back to the backend and hit Refresh
| | 01:56 | and see the data loaded.
| | 01:57 | So now we have Backpack Cal with the
Alias backpack-cal and the activity photo
| | 02:02 | that sets line to it.
| | 02:03 | Let's try this with a new record,
let's hit New and entering in Alias and
| | 02:09 | then try and click Save.
| | 02:12 | You'll notice now that we've been
brought back to the form with an alert saying
| | 02:15 | that name is a required field.
| | 02:18 | Since this data got stored in the
session, it pulled it back up on the form for
| | 02:22 | us so that we don't have to reenter test here.
| | 02:25 | JForm is flexible but in the source
of the loaded data it doesn't matter.
| | 02:29 | It's possible and preferable to check
both the session and the database, this
| | 02:33 | way users never lose any
of the data they've entered.
| | Collapse this transcript |
| Splitting JForms into layouts| 00:00 | Complex forms can get rather large in
hurry, because of this it's a good idea to
| | 00:04 | break your form into smaller
pieces that are more easily identified.
| | 00:07 | Let's break out the activity form
to make better use of the screen.
| | 00:11 | First let's login to the backend, use
admin as a User Name and lynda as a Password.
| | 00:16 | Go to Components>Explore
California>Activities, and click on New.
| | 00:21 | So the moment we have all of these
different fields right here in the same fieldset.
| | 00:26 | And we're going to break this out a
little bit so that we have the activity
| | 00:30 | photo on the right and all the
other fields remain on the left.
| | 00:33 | So let's go to the Exercise
Files and pull up some of the XML.
| | 00:37 | Go to models and go to
Forms and pull up activity.xml.
| | 00:42 | Now this file is very similar to the
one that's already in the component.
| | 00:49 | The main difference is that
we have two fieldsets now.
| | 00:52 | We have one fieldset with a name of
essential, and now we have a second fieldset
| | 00:56 | with a name of optional, and we
moved the activity_image field from the
| | 01:01 | essential one into the optional one.
| | 01:04 | So let's open up activity.xml in
our component and make this change.
| | 01:07 | So go to activity.XML and open it,
and up at the top give this a name of
| | 01:16 | essential, then go to the bottom and
copy the activity image out of this
| | 01:22 | fieldset and create a new fieldset,
give this a name of optional and then close
| | 01:30 | off the fieldset and then paste that image in.
| | 01:33 | So now we have two fieldsets, when you
only have one fieldset you don't need to
| | 01:39 | give it a name but when you have more
than one fieldset it's essential that you
| | 01:42 | have names for all the fieldsets,
that way you can work with each of these
| | 01:46 | fieldsets independently of each other.
| | 01:48 | So let's save this XML file and let's go back
and make some adjustments to the layout itself.
| | 01:56 | Go to Views and go to Activity, and
then go all the way to the edit.php file.
| | 02:02 | Notice it's pretty much the same as it
was before only we have a second div and
| | 02:07 | there's been a slight change
to the getFieldset function.
| | 02:10 | We're now passing in the name of the
fieldset that we want to use for each
| | 02:15 | one of these calls.
| | 02:16 | So let's go and make these changes on our View.
| | 02:19 | Go to Views>Activity, and then go to
the edit.php file, and you can just copy
| | 02:26 | and paste this div in and this div is
similar to the first div only it has a
| | 02:34 | class of width-40 and a float right
class as well, and this one is passing in
| | 02:40 | the optional parameter for the fieldset,
so we only get the optional fieldset
| | 02:44 | here, and then finally let's just copy
this essential parameter here and put it
| | 02:50 | in for the left-hand side.
| | 02:53 | So when we save that file and go back
to the backend and hit Refresh, you'll
| | 02:57 | notice now we have all the essential items on
the left and the optional item on the right.
| | 03:02 | Using different fieldsets is a great
way of breaking your JForm into logical
| | 03:05 | separations, once each fieldset has a
name rendering each fieldset separately
| | 03:10 | is no problem.
| | Collapse this transcript |
| Handling HTML JForms elements| 00:00 | Sometimes you need to handle
specific JForm elements independently of
| | 00:04 | the others, let's add an HTML editor to
our JForm and give it some special treatment.
| | 00:09 | We're going to login to the backend of Joomla
| | 00:11 | with the User Name admin and the Password lynda.
| | 00:14 | Go to the Activities view, and click on New.
| | 00:18 | So you'll notice here, right now we
have a fresh form with the Name, the
| | 00:23 | Alias, the Status, and the Activity
Photo and what we want to do is add an
| | 00:28 | HTML editor to this view.
| | 00:30 | So let's go to the JForm xml file in the
Exercise Files, go to models, forms and
| | 00:37 | pull up activity.xml.
| | 00:41 | You'll notice there is another
fieldset here with the name of editor and we
| | 00:44 | just want to copy this entire
fieldset and paste it into our JForm that's
| | 00:49 | already in the component.
| | 00:50 | So go to models and go to forms and
activity.xml and just open that and place
| | 00:57 | that fieldset in the XML.
| | 00:59 | So now we have a fieldset with a name
of editor, and then we have a field with
| | 01:05 | the name of activity_description.
| | 01:08 | The type of field is an editor and we have a
filter on it for safehtml, this is because Joomla
| | 01:14 | is going to strip out by default all of
the HTML that's in this editor unless we
| | 01:19 | tell it to use a different filter on the editor.
| | 01:23 | Let's go back to the View and
add this editor to the view.
| | 01:28 | Go to edit.php, you'll notice at the
bottom of the fieldset for the essential
| | 01:33 | items there are a couple of divs and a
couple of function calls to the Form.
| | 01:38 | So let's copy these four lines from
the Exercise Files and into our View.
| | 01:44 | So go to views>activity>tmpl>edit.php,
and just paste those four lines here.
| | 01:53 | So with these four lines we have a
couple of divs here, they are clearing both
| | 01:58 | the left and the right sides of the display.
| | 02:01 | This way we don't have to worry about
how the HTML editor is rendering and
| | 02:06 | it makes it possible for us to add the HTML
editor alongside all of the other elements.
| | 02:11 | Next we're using this form
getLabel to get the label for the activity
| | 02:16 | description field, and notice here that
we're not at all bothering with the name
| | 02:20 | of the fieldset, we're just going
directly to the input element on the JForm, so
| | 02:25 | after saving the file go back
to the backend of the Joomla
| | 02:28 | component and hit Refresh.
| | 02:30 | And now you'll see the HTML editor at
the bottom of the screen that's ready
| | 02:34 | for our description.
| | 02:35 | Let's close out of this new
record and open an existing record.
| | 02:39 | If we open a Backpack Cal, you'll
notice that we have the name of the alias in
| | 02:43 | the status along with the
HTML description at the bottom.
| | 02:48 | To get label and get input functions
make it possible to get a specific JForm
| | 02:51 | element to be output independently of
its fieldset, whenever you need to give a
| | 02:55 | form element individual
treatment use these functions.
| | Collapse this transcript |
|
|
10. View ConfigurationsImplementing configuration panels| 00:00 | While list and form views give the
administrators a way of managing records in
| | 00:04 | the database, it's also helpful to give
them a control panel where settings for
| | 00:08 | the component can be adjusted. Joomla
| | 00:10 | handles component-wide settings
through a Configuration panel System.
| | 00:14 | Let's build a control panel for
the Explore California component now.
| | 00:18 | Let's log into the backend of Joomla
| | 00:20 | use the User Name admin and Password lynda.
| | 00:22 | Now let's go to Components>
Explore California and Activities.
| | 00:27 | What we're going to do is we're going
to add a button to this view that will
| | 00:31 | allow us to configure the component as a whole.
| | 00:34 | So first let's go to our Exercise
Files, there is a config.xml file in
| | 00:39 | the Exercise Files.
| | 00:41 | Go to administrator>components>com_
explore and just paste config.xml right there.
| | 00:49 | Let's take a look at the contents of
config.xml so that the root of this XML
| | 00:54 | file is a config element.
| | 00:57 | Inside that config element there are
two different fieldsets, we have one for
| | 01:01 | tours and we have one for activities.
| | 01:04 | Each one of these fieldsets also
has a label and a description that go
| | 01:08 | along with the fieldset.
| | 01:10 | This is something that Joomla
| | 01:11 | is going to use to generate a
tabbed UI for the Configuration panel.
| | 01:16 | And then inside each
fieldset we have one or more fields.
| | 01:19 | It's very similar to JForm
and uses the same elements.
| | 01:23 | So now let's load this Configuration panel.
| | 01:26 | Go to views>activities and view.
html.php in the Exercise Files.
| | 01:32 | You'll notice that at the very
bottom of the addtoolbar function there is
| | 01:36 | another toolbar button named preferences.
| | 01:39 | Copy this toolbar button from the
exercise file and then go to views and
| | 01:44 | activities and view.html.php in
the backend of your component.
| | 01:50 | Go to the bottom of the addtoolbar
function and just add this other call.
| | 01:55 | Notice that the argument for this
preferences function is com_explore.
| | 01:59 | This will make sure that we load up
only this component's preferences.
| | 02:04 | After saving this file go back
to the backend and hit Refresh.
| | 02:09 | You'll now notice that we have an
Options button, when you click the Options
| | 02:13 | button you get a tabbed interface,
one with Tours and one with Activities.
| | 02:18 | We're going to set Show tour activities to
Show and we're going to click Save & Close.
| | 02:24 | And then when you click on the Options
button again you'll notice is that option
| | 02:28 | got saved and the Activities drop-down
stayed at Pictures and Divs. So Joomla
| | 02:35 | is automatically handling the
validation of all of these input elements and is
| | 02:40 | saving them into the database
for the com_explore component.
| | 02:45 | The next time you want to add a
configuration screen for your component consider
| | 02:49 | the config.xml file not only does it
handle all the validation for your form
| | 02:53 | elements it also handles the storage.
| | 02:56 | You don't need models or controllers to
make the config file work just add the
| | 03:00 | button for your toolbar.
| | Collapse this transcript |
| Reading configuration values| 00:00 | Having a Configuration panel in the backend
is only useful when the values are active upon.
| | 00:05 | Fortunately, Joomla
| | 00:06 | provides all the configuration
values any convenient object that's
| | 00:10 | available on-demand.
| | 00:12 | So let's access these values and
configure some of the front-end views.
| | 00:16 | First let's load up one of the front-end
views to see the before state.
| | 00:19 | Go to com_explore and then view=activities.
| | 00:26 | Once you are there you'll notice we
have the current layout where we have the
| | 00:29 | images on the left and the
descriptions on the right.
| | 00:33 | The configuration now has another
option that's a simpler view for this.
| | 00:37 | So let's configure this view to
read that configuration object.
| | 00:42 | Let's go to the Exercise Files, if
you're here in views go to activities and
| | 00:47 | view.html.php, and we've added one line
here to get the parameters as well as a
| | 00:54 | property to store them in.
| | 00:55 | So go to the front-end of your component
in components>com_explore and views and
| | 01:02 | then go to the activities view.
| | 01:05 | Open up view.html.php there and
then copy and paste this line in.
| | 01:15 | Also copy in the params property.
| | 01:21 | This JFactory:getApplication
function is going to return the application
| | 01:25 | object and then right-away we're
calling the getParams function on that
| | 01:30 | application object.
| | 01:31 | This function will always give
us the parameters for the current
| | 01:34 | component that's loaded.
| | 01:36 | Now that we have the parameter stored in
the view let's go to the view layout to
| | 01:40 | act upon the values of the parameters.
| | 01:44 | Open up tmpl and open default.php.
| | 01:48 | You'll notice that we have the original
markup here in the else clause, well in
| | 01:52 | the if clause we have an unordered
list where the items are cycled over.
| | 01:56 | So what we want to do is copy this entire
if statement and replace it in the layout.
| | 02:04 | So open up default.php in your
component and just replace this for each loop
| | 02:10 | with this if statement.
| | 02:13 | So now we're calling the get function on
the parameters object and we're passing
| | 02:18 | in list_style as the argument and if
the parameter list_style is set to list
| | 02:23 | then we display the
records as an unordered list.
| | 02:26 | If it's not set to list we
assume that we want the div output.
| | 02:30 | After saving this layout file go
back to the front-end and hit Refresh.
| | 02:36 | You'll notice that the layout
didn't change, because we haven't set the
| | 02:39 | parameter yet in the backend.
| | 02:41 | So let's log into the backend and set
the parameter and see the difference.
| | 02:46 | So log into the backend with User Name
admin and Password lynda, and then go to
| | 02:51 | Explore California and
Activities and pull up the Options panel.
| | 02:55 | Make sure the Activities tab is
highlighted and then click Unordered List as the
| | 03:02 | option for Activity List Style.
| | 03:04 | Click Save & Close and then go
back to the front-end and hit Refresh.
| | 03:08 | So now we have an unordered list rather
than the short descriptions with the images.
| | 03:13 | I like the short descriptions with the
images so I'm going to switch it back.
| | 03:22 | Once a configuration is set in the
backend getting the set values is
| | 03:26 | straightforward, just pull-in the
parameters object, use a member method get to
| | 03:30 | fetch each individual value.
| | Collapse this transcript |
| Configuring models| 00:00 | Configuration values are
not just applicable to Views;
| | 00:03 | they can also be used in models.
| | 00:05 | The method for using the configuration in
a model is exactly the same as in a View.
| | 00:10 | So first, let's load up the Tours
list view and see what we have currently.
| | 00:18 | So currently, we have links for each
tour along with a description of the tour,
| | 00:22 | and we added a configuration parameter
in the backend that allows you to turn on
| | 00:27 | and off showing the activity for each tour.
| | 00:30 | So now, we're going to adjust the
model to also show the activity when that
| | 00:35 | option has been selected.
| | 00:37 | Let's go to the Exercise Files, go to
models and open up tours.php and you'll
| | 00:43 | notice we now have a getItems
function along with a modified getListQuery.
| | 00:48 | Go to the front-end of your component,
under models, and open up the tours.php file.
| | 00:55 | Replace this function with
the two from the Exercise Files.
| | 01:01 | We've modified the getListQuery
function slightly so that we're now joining in
| | 01:05 | the Activities table and getting in the
activity name of each activity that is
| | 01:10 | assigned to the tours.
| | 01:12 | Additionally, we now have a getItems function.
| | 01:15 | This getItems function is getting all
the records from the database that are
| | 01:19 | being defined here in this query, and
then we're getting the parameters from the
| | 01:24 | backend that got set.
| | 01:25 | Then we use the get function on
the params object, and get the
| | 01:30 | show_activities parameter.
| | 01:32 | If the value of show_activities is
nonzero, we assume that yes, we want to
| | 01:36 | show the activities.
| | 01:37 | So then we cycle over all of the items
that have been retrieved, and then we
| | 01:43 | append the activity_name
to the end of the tour_name.
| | 01:46 | We do this in place getting the item by
reference, so that we don't have to mess
| | 01:50 | around with a lot of extra variables.
| | 01:52 | So now if we close this out, let's go
back to the backend and make sure that we
| | 01:57 | have the right setting for our configuration.
| | 02:01 | Use admin as username and lynda as a
password, and then go to Components>Explore
| | 02:06 | California>Activities.
| | 02:08 | Click on the Options panel
and then go to the Tours tab.
| | 02:13 | Make sure that Show tour activities
is set to Show, and hit Save & Close.
| | 02:19 | Now, go back to the front-end and hit Refresh.
| | 02:22 | You'll notice now that Backpack Cal
has been appended to all these records.
| | 02:26 | If we want to turn it off, just go
back to the Configuration panel, and click
| | 02:31 | Options and now click Hide.
| | 02:35 | After that, the activities are now hidden.
| | 02:39 | Configuration values are used in the model
exactly the same way they are in the Views.
| | 02:44 | After fetching the parameters object,
just call the member method get for
| | 02:47 | the values.
| | Collapse this transcript |
| Linking views through menus| 00:00 | One of the advantages Joomla
| | 00:01 | has over stand-alone model view
controller frameworks is the ability to link
| | 00:06 | views to a dynamically generated menu.
| | 00:08 | To make this work, it's first necessary
to identify these views in a way that is
| | 00:13 | recognizable to administrators.
| | 00:15 | This identification is done through XML
files in the front-end of the component.
| | 00:19 | So first, let's go to the backend
to see how this problem plays out.
| | 00:24 | Login as admin and lynda is the password.
| | 00:28 | Let's try to link to one of the views.
| | 00:30 | Let's go to Main menu>Add New menu Item,
and if you click select, you'll notice
| | 00:36 | that none of the Explore California
views are listed here, and that's because we
| | 00:41 | haven't identified these
views through the XML files.
| | 00:45 | So click the X, and cancel out of this.
| | 00:49 | Let's go back to the front-end.
| | 00:51 | Let's go to the Exercise
Files and add these XML files.
| | 00:55 | So first, go to activities>tmpl>default
.xml, and open it up and have a look.
| | 01:03 | Inside this XML file is a metadata
element with a layout element inside of that.
| | 01:08 | There is a title parameter which has the
title that we're going to use for this view.
| | 01:13 | Notice that it is a language string.
| | 01:16 | All of this is internationalized
through the language string file that got
| | 01:20 | installed when we installed the component.
| | 01:23 | We also have a message for the layout as well.
| | 01:27 | This acts as a title, and as
a description for the View.
| | 01:31 | So we have one here for the
Activities, we have another for the Single
| | 01:35 | Activity, we have a third for the Single Tour,
and then finally, we have one for the Tour List.
| | 01:41 | So let's copy all of these XML
files into their correct places.
| | 01:46 | Go to the front-end of your component
and go to Views, and then for this one,
| | 01:51 | we're going to do tours and then for
tmpl, copy the default.xml file right
| | 01:58 | alongside the default.php file.
| | 02:00 | This is where Joomla
| | 02:01 | is going to look for these xml files,
so that each layout can be identified.
| | 02:06 | I'm going to do the same for Tour.
| | 02:12 | We're also going to do the same for
Activity, and we're finally going to do the
| | 02:21 | same thing for Activities.
| | 02:22 | Now, let's go back to the
backend, and click on New menu Item.
| | 02:32 | When we click Select, there is now a
section for Explore California and there
| | 02:37 | are four views shown.
| | 02:39 | There is Activities, Activity
Base Link, Tour Base Link, and Tours.
| | 02:43 | Once all the XML view
metadata files are in place, Joomla
| | 02:46 | is able to pull in the
view titles and descriptions.
| | 02:49 | This will help administrators
find the views and link to them.
| | Collapse this transcript |
| Individually configuring views| 00:00 | In addition to having a global
component configuration, it's also useful to
| | 00:04 | occasionally override the
settings in specific places.
| | 00:08 | View XML metadata files make
it possible to do just that.
| | 00:12 | So first, let's take a look at
our Activities view for a moment.
| | 00:16 | If we go to com_explore&view=activities,
we'll have this Activities list
| | 00:23 | where we have the image for the Activity on
the left with the description on the right.
| | 00:27 | And as we added in a previous video,
we now have a configuration option where
| | 00:31 | you can change this to just an
unordered list of links to activities.
| | 00:36 | Let's create a menu item where we can
have that list, yet still retain this view
| | 00:43 | for the global configuration.
| | 00:45 | So let's go to the
Exercise Files to set this up.
| | 00:50 | In the Exercise Files, there is
activities, tmpl and default.xml.
| | 00:55 | So go to activities>tmpl and
get default.xml ready to edit.
| | 01:02 | So this is the current
default.xml file for this view.
| | 01:06 | Let's update it with the
code from the Exercise Files.
| | 01:09 | Open up default.xml, and you'll notice
that all we've done is added this fields
| | 01:15 | element to the XML file.
| | 01:17 | So copy the fields element in total and just
paste it right in and then save the XML file.
| | 01:26 | So now we have a fields element
and notice that the name is params.
| | 01:31 | This is important because Joomla
| | 01:33 | is going to compare the params fields
to the configuration in the backend, and
| | 01:39 | it's going to use this as an
override for the values in the backend.
| | 01:43 | We have a fieldset with the name of
Activities and that matches the fieldset
| | 01:47 | name of activities in the backend.
| | 01:49 | Next, we also have a label for this
fieldset, so that when we are configuring
| | 01:53 | this menu item, we have a
label for these parameters.
| | 01:58 | Then finally, we have the same
field for list_style that we have in the
| | 02:02 | config.xml file in the backend.
| | 02:04 | So now that we've saved this file,
let's go to the backend and create a link.
| | 02:10 | Log in as admin with the password lynda.
| | 02:12 | Now, let's go to menus>
Main menu>Add New menu Item.
| | 02:19 | We are now going to select the Activities link.
| | 02:22 | On the right, we now have
the Activity List Style.
| | 02:26 | It's currently set to Use Global.
| | 02:28 | We want to set this to Unordered List, and
now give the menu Item a title of Activities.
| | 02:36 | Click Save and close and
then go back to the front-end.
| | 02:40 | Click Refresh, and now
Activities appears on the Main menu.
| | 02:44 | When we click Activities, you'll
notice that we have this unordered list of
| | 02:49 | activities with links to them.
| | 02:52 | But if we go back to the direct link
for the view, we have the layout that's
| | 02:56 | still the images on the left,
and the text on the right.
| | 03:00 | Now, if we go back to the menu Item,
and we go and edit the menu Item again, we
| | 03:06 | can set it now to Use Global and click Save.
| | 03:09 | If we go back to the front-end and hit
Refresh, it changes it back to the images
| | 03:14 | on the left, and the text on the right.
| | 03:17 | We can still also set it explicitly to
Pictures and Divs and we'll have the same result.
| | 03:24 | The XML metadata files for each view
make it possible to override the global
| | 03:28 | component settings per link.
| | 03:30 | This kind of flexibility makes it
possible for the same view to be reused many
| | 03:34 | times over in several different variations.
| | Collapse this transcript |
|
|
11. Making URLs Human-ReadableWhy make URLs readable?| 00:00 | Some people assume that the only reason
to use search engine-friendly URLs is to
| | 00:04 | bump your site's ranking in search engines.
| | 00:07 | However, there are some other reasons
for using friendly URLs rather than the
| | 00:10 | ones based off index.php.
| | 00:13 | Friendly URLs match the
design of the web more closely.
| | 00:17 | On the web, you typically don't have
one file that is generating all the
| | 00:21 | different pages for the site.
| | 00:22 | So if you have the default Joomla
| | 00:24 | URLs, you'll have index.php
generating every page with different variables
| | 00:29 | determining what page is actually being loaded.
| | 00:32 | Another reason to use friendly URLs is
that they're easier for users to type.
| | 00:38 | When you have ampersands and periods
and equal signs and all those extra
| | 00:43 | characters in your URL, it makes it
more difficult for your users to type
| | 00:47 | the URL in and it also increases the
chances that they're going to make a
| | 00:51 | mistake when they type it.
| | 00:52 | Another reason to make URLs readable
is that they're easier to vocalize.
| | 00:56 | It's much easier to say for instance
explorecalifornia.org/contact than it is
| | 01:02 | explorecalifornia.org/
index.php?option=com_content;
| | 01:07 | you get the idea.
| | 01:10 | And the final reason to make URLs
readable is that they're just nicer to look at.
| | 01:15 | They are easier on the eyes and you
can see specifically where you are in the
| | 01:18 | web site and looking at that URL
gives you an idea of what page you are on.
| | 01:23 | There are some specific reasons to use Joomla's!
| | 01:26 | search engine friendly URL system
when you install your site. Joomla
| | 01:31 | includes a file called htaccess.txt
and when you rename this to .htaccess,
| | 01:37 | Apache can read it and reconfigure the
way that URLs are generated for your site.
| | 01:42 | In addition to setting up the search
engine-friendly URLs, the htaccess file
| | 01:46 | includes security enhancements.
| | 01:49 | These include hiding the XML files that
are throughout your Joomla installation.
| | 01:54 | To use the htaccess file,
rename htaccess.txt to .htaccess.
| | 02:01 | And after you have done that, go into
the Global Configuration in the backend
| | 02:05 | and switch on search engine-friendly URLs.
| | 02:08 | This way, it will use mod_rewrite
to change the URLs to remove
| | 02:12 | index.php entirely.
| | 02:14 | Search engine-friendly URLs do more
than improve your search engine rankings.
| | 02:18 | They make your site easier
for your visitors to use.
| | 02:21 | Turn them on to get the full benefits Joomla
| | 02:23 | has for URLs.
| | Collapse this transcript |
| Aliasing records| 00:00 | Without the aid of search engine-friendly
links, records are typically loaded by
| | 00:04 | an ID provided in the URL.
| | 00:06 | But when search engine-friendly
links are on, numerical keys for records
| | 00:10 | aren't usually available.
| | 00:12 | To get around this, it's usually
necessary to generate aliases for each record.
| | 00:16 | Let's take a look at how aliases can be
automatically generated for each record
| | 00:20 | when they are saved.
| | 00:21 | First, let's go to the backend to
take a look at some aliases that are
| | 00:25 | already in the database;
| | 00:27 | login as admin and lynda.
| | 00:30 | Let's go to Components>
Explore California>Activities.
| | 00:34 | Open up the BackpackCal record and
you'll notice we have a Name and an Alias.
| | 00:38 | You will notice that the alias is very
similar to the name, only it's in all
| | 00:43 | lowercase, and there's a
hyphen instead of a space.
| | 00:46 | Let's close out of this record and
add some code to our table class to make
| | 00:52 | these aliases appear automatically.
| | 00:54 | Go to the Exercise Files and
open up tables and activity.php.
| | 00:59 | You will notice there is a check function here.
| | 01:02 | We are going to copy and paste this check
function into the activity.php file on our site.
| | 01:08 | Go to administrator>components>
com_explore>tables>activity.php.
| | 01:17 | Make a little bit of room at the
bottom and then paste in the check function
| | 01:21 | and then save the file.
| | 01:23 | Every time the save function of JTable
is called, it will check to see if there
| | 01:26 | is a check function in the class,
and if there is, it will run it.
| | 01:30 | It will get the value from check and
if it's true, it will continue with the
| | 01:33 | save and if the value is false, it will stop.
| | 01:36 | We are going to use check in this case to
generate an alias based on the activity name.
| | 01:41 | So first, we get the
value of the activity_alias.
| | 01:44 | If the activity_alias is empty, this
is where we want to start filling it in.
| | 01:49 | We want to make sure that we don't
overwrite anything that the user entered in
| | 01:53 | as the alias if they wanted to
manually enter one in themselves.
| | 01:57 | So first, we set the alias to the
activity_name and then regardless of whether
| | 02:03 | the user entered the activity_alias,
or we generated it just now, we want to
| | 02:07 | make sure that the alias is safe for URLs.
| | 02:09 | So we are going to pass it
through JApplication::stringURLSafe.
| | 02:13 | stringURLSafe is going to go through
the string and replace all of the spaces
| | 02:19 | with hyphens and is going to lowercase
all of the letters and just remove any
| | 02:23 | characters that will not go in URLs.
| | 02:27 | So finally, after we've generated the
alias, we return true and the save continues.
| | 02:32 | Let's go back to the backend
and see how this function works.
| | 02:36 | We're going to create a new
record and we're going to save it.
| | 02:39 | Type-in the name In Bigfoot's
Footsteps, and now click the Save button.
| | 02:49 | The Save button will save the record and
then reload it so we can see what happened.
| | 02:54 | So you'll notice all the spaces in the
name got replaced with hyphens and the
| | 02:59 | apostrophe was removed entirely.
| | 03:01 | This is because
apostrophes do not belong in URLs.
| | 03:05 | Whenever a URL safe alias is desired
for a record, the stringURLSafe function
| | 03:10 | can be used to generate
something close to the records title.
| | 03:13 | Putting this function call directly in
a JTable class is a good way of making
| | 03:17 | sure all records have aliases.
| | Collapse this transcript |
| Handling ItemIDs| 00:00 | The way that Joomla
| | 00:01 | generates URLs is a bit
non-obvious at first glance.
| | 00:05 | Instead of actually
generating true pages Joomla
| | 00:08 | bases everything off of
the items added to menus.
| | 00:11 | Each menu item has a
numerical ID also known as the Itemid.
| | 00:16 | Understanding what Itemids are and
how they work is essential to generating
| | 00:21 | search engine friendly URLs.
| | 00:23 | So the biggest thing to keep in mind
when we are talking about Itemids is that
| | 00:27 | properly routed URLs are
always going to have an Itemid.
| | 00:31 | That is an ID that's in the menu
table that relates back to that link.
| | 00:35 | If you don't have an Itemid for your
link, you're going to get the default
| | 00:40 | configuration for whatever
is on that Joomla site.
| | 00:44 | So if you don't have an Itemid that
means you're going to miss any templates
| | 00:48 | or module assignments or any other
things that you've added to configure that
| | 00:52 | page because Joomla
| | 00:53 | doesn't have that Itemid and
doesn't know what configuration you want.
| | 00:57 | Now you maybe wondering how does an
Itemid come into play when we have the
| | 01:02 | Search Engine Friendly links turned on?
| | 01:04 | Well, the aliases that are used to build the
URLs point back to the Itemids. So Joomla
| | 01:11 | will take a look at the aliases and
compare those to the menu item aliases and
| | 01:16 | then look up the Itemids that way.
| | 01:19 | Let's take a look at what happens
when you're missing an Itemid from a URL.
| | 01:21 | We are going to go to Joomla
| | 01:24 | and let's go to the backend of the site.
| | 01:28 | Login as admin and lynda and we're going to
assign a specific template to a specific page.
| | 01:35 | Let's go to Extensions>Template
Manager and then open up the Atomic template.
| | 01:40 | You will notice we have two menu items,
one for Home and one for Activities.
| | 01:45 | Let's check off Activities.
| | 01:46 | So this way the Atomic template is going
to be assigned to the Activities menu item.
| | 01:52 | Hit Save & Close.
| | 01:54 | And now we before we go back to the
front end let's go and check something in
| | 01:57 | the Global Configuration.
| | 01:58 | Go to Site>Global Configuration and
make sure that Site tab is clicked.
| | 02:04 | For the moment, if you have any of the
SEO Settings turned on like the Search
| | 02:07 | Engine Friendly URLs or the rewriting
or the suffixes, just set them all to No
| | 02:12 | for the moment and click Save.
| | 02:14 | So let's go back to the
front end and hit Refresh.
| | 02:18 | So we still have our two menu items.
| | 02:19 | We have Home and Activities and when we
click on Activities, you'll notice that
| | 02:24 | we get this strip down template.
| | 02:25 | That's the Atomic template that
we assigned to this menu item.
| | 02:29 | And you'll notice that we have this
long URL with Itemid=108 at the end.
| | 02:34 | This Itemid is telling Joomla
| | 02:36 | to apply the atomic template to this page.
| | 02:39 | Now let's see what happens when we
strip the Itemid off the end of this URL.
| | 02:43 | Since we are missing the Itemid, Joomla
| | 02:47 | doesn't know which template to add to
this page so it just uses the default one.
| | 02:53 | I'm going to go back to the backend and
turn Search Engine Friendly URLs back on.
| | 02:59 | Hit Save & Close and then go back
to the front end and hit Refresh.
| | 03:04 | Now if you follow the Activities link,
you will notice that the template is back
| | 03:08 | to Atomic but we don't have an Itemid.
| | 03:11 | That's because Joomla
| | 03:13 | is looking up the Activities alias
and getting the Itemid based off that.
| | 03:19 | Let's go back to the backend
and remove this assigned template.
| | 03:22 | Go to Extensions>Template Manager, go
to Atomic and then uncheck Activities
| | 03:29 | and click Save & Close.
| | 03:31 | Links back to the current component are
always assumed to have the same Itemid.
| | 03:35 | This can be a problem because Joomla
| | 03:37 | assumes that there is one base link
that is always pointing to your component
| | 03:42 | and that means that there is
one Itemid for your component.
| | 03:46 | However, this is in a bit
of a conflict because Joomla
| | 03:50 | allows you to create links to
multiple views in your component.
| | 03:54 | So you could have several different
Itemids that all point back to your
| | 03:58 | component but they're pointing
to different views. So Joomla
| | 04:02 | ends up guessing which Itemid you
want to use, and this can be a problem.
| | 04:08 | You don't even know if you have
the right Itemid because Joomla
| | 04:12 | has just guessed that you
want to use the current one.
| | 04:15 | So my strategy for handling Itemids is
to always create one link and only one
| | 04:21 | link to each view and then look up the
Itemid for the view when I'm building my links.
| | 04:26 | Itemids are a core part
of Joomla's functionality.
| | 04:29 | Without an Itemid Joomla
| | 04:31 | pages are not fully configured.
| | 04:33 | Always make sure your link have an
Itemid and make sure the Itemid is the
| | 04:37 | one you want.
| | Collapse this transcript |
| Configuring SEF URLs| 00:00 | Before building URL
routes and parsing them Joomla
| | 00:03 | must be properly configured to
handle search engine friendly links.
| | 00:07 | Also, base links for the individual
record views must be added as well.
| | 00:11 | Let's configure Joomla's SEF
system and create some base links.
| | 00:14 | So first thing let's go to the backend
and turn on search engine friendly links.
| | 00:19 | Go to Administrator and then admin and lynda.
| | 00:24 | Go to Site and Global Configuration
and make sure the Site tab is clicked.
| | 00:29 | From here make sure Search Engines Friendly
URLs and Use URL rewriting are set to Yes.
| | 00:35 | Now click Save & Close.
| | 00:38 | Now in order to make the URL rewriting
work fully, we need to use the htaccess
| | 00:44 | file for Apache to get Apache
configured the right way and the issue with this
| | 00:49 | file is that it is a .txt file
that needs to be renamed to .htaccess.
| | 00:57 | Now most operating systems will
treat a file that starts with dot as a
| | 01:01 | hidden file and they won't let you
rename a file to a hidden file through
| | 01:06 | the usual user interfaces.
| | 01:08 | So what we are going to do here for
the Mac is drop into Terminal and do it
| | 01:13 | from the command line.
| | 01:14 | You can do something similar through
the command line in Windows as well.
| | 01:17 | I am just going to show it here on Mac.
| | 01:19 | So we are going to go to the
Applications folder in Finder and then go to the
| | 01:23 | Utilities folder underneath there.
| | 01:26 | Open up Terminal from the Utilities
folder and then if you're using MAMP go to
| | 01:31 | cd /Applications/MAMP/htdocs/ and then type in
the name of the folder where you have Joomla
| | 01:40 | installed.
| | 01:40 | So you'll see here we have htaccess.txt
and we are just going to move this using
| | 01:48 | the mv command from htaccess.txt to .htaccess.
| | 01:53 | So now that we have that file moved over
to the hidden file where Apache can see
| | 01:57 | it and use it for the configuration
let's go back to the front end and hit
| | 02:01 | Refresh, and after we've hit
Refresh follow the Activities link.
| | 02:06 | So you'll notice now Activities is just
here at the end of the URL and there is
| | 02:11 | no index.php or anything extraneous like that.
| | 02:15 | It's just showing Activities.
| | 02:17 | This means that Joomla's SEF
system is turned on and is ready to go.
| | 02:22 | So in addition to turning on Joomla's
SEF system we also need to create some
| | 02:26 | base links for the Tours and the Activities.
| | 02:30 | In a previous video I mentioned that Joomla
| | 02:33 | has a bit of a strange system with
the Itemids where it tries to guess what
| | 02:39 | Itemid you're trying to use for the component.
| | 02:43 | And we want to take some of the
guesswork out of that for Joomla
| | 02:46 | and we want to create specific links to
those individual views so that Joomla
| | 02:51 | always uses those links as the base URLs
rather than trying to guess what link to use.
| | 02:57 | So let's go to the backend.
| | 02:59 | And to do this you have to create them
as menu items and typically what I do in
| | 03:03 | a situation like this is I will create
a hidden menu so I can get those base
| | 03:09 | links without actually
displaying them as links in the front end.
| | 03:13 | So they won't display as hyperlinks in
the HTML but they will be available as
| | 03:19 | URLs through the front end.
| | 03:22 | So let's go to menus and menu Manager
and we are going to Add New menu here
| | 03:26 | and we are going to call this the
Hidden menu and then just type hiddenmenu as
| | 03:31 | the menu type as well.
| | 03:32 | Once you have that in place hit Save & Close
and then navigate to Hidden menu from menus.
| | 03:41 | So now we have a fresh clean menu with
no menu items on it and this is where
| | 03:46 | we are going to add those links to
those views so that we can get the base
| | 03:49 | URLs, although we are not necessarily
going to be displaying these links to
| | 03:53 | the users in the front end.
| | 03:54 | So click on New and then select the
Activity Base Link as the menu Type.
| | 04:00 | So just type Activity as the Title, and
you can leave Alias blank because when
| | 04:05 | we click Save Joomla
| | 04:07 | automatically takes that menu title
and passes it through the function that
| | 04:11 | turns it into an alias.
| | 04:13 | So activity is now all lowercase and
it's ready to use as our base URL for each
| | 04:20 | individual activity record.
| | 04:22 | Let's do the same thing for Tours.
| | 04:24 | Click Close and now click New again
and this time we are going to select
| | 04:29 | the Tour Base Link.
| | 04:31 | So just type in Tour as the
menu Title and click Save & Close.
| | 04:37 | So you'll notice here we have an
Alias for Activity that's just activity in
| | 04:40 | lowercase and the same for Tour. With Joomla
| | 04:44 | SEF turned on and base links in place,
we are ready to start building and
| | 04:47 | parsing URLs to the records.
| | Collapse this transcript |
| Building URL routes| 00:00 | Joomla handles the base of each URL through
the aliases in the menu system after the
| | 00:05 | base the rest of the URLs
generated by the component.
| | 00:08 | Let's generate some URLs for the
Explore California component now.
| | 00:12 | So let's go to the Exercise Files
and pull up the router.php file.
| | 00:16 | So we are going to copy router.
php right where it needs to go.
| | 00:20 | Copy the file and then go to
components>com_explore and paste router.php
| | 00:26 | there in the front end.
| | 00:28 | Now let's open router.php and have a look at it.
| | 00:32 | So first we have ExploreBuildRoute and this
is a standardized function name in Joomla
| | 00:39 | It's first taking the name of the
component Explorer and then looking for
| | 00:43 | BuildRoute, and when it finds
ExploreBuildRoute it's going to pass in an array
| | 00:48 | called query and it's going
to pass it in by reference.
| | 00:51 | The query array contains all of the
variables that are found in the URL that Joomla
| | 00:57 | is trying to build a route for.
| | 00:58 | So first we start off by creating an
array called segments and this array is
| | 01:04 | what we're going to return
in the end to show Joomla
| | 01:07 | which pieces of the URL we
want to build for this link.
| | 01:11 | The first thing we are going to do is
check to see if there is a view variable
| | 01:15 | in the query array, and if so we're
going to check to see if it's pointing to
| | 01:21 | one of the single record links, if it's
pointing to Activity or if it's pointing to Tour.
| | 01:26 | And if it's pointing to one of those links,
we want to get the alias for that record.
| | 01:32 | So we are going to pass in the id that
points to that record as well as the view
| | 01:37 | that points to that record into a
function called ExploreGetAlias and we are
| | 01:42 | going to take a look at that in a moment.
| | 01:44 | And then once we get the alias for that
record and add it to the segments array,
| | 01:48 | we unset the query id.
| | 01:51 | That way we don't have that id
being added to the end of the URL.
| | 01:56 | Next, we're going to look
up the Itemid for this view.
| | 01:59 | Remember that we added links for the
individual views, the ones for Tour and the
| | 02:04 | ones for Activity, and we did that so we
can get a specific Itemid for each view
| | 02:10 | and this is to get around Joomla's
system where it always assumes that you are
| | 02:14 | linking back to the main component link.
| | 02:17 | And this ExploreGetItemid is a
function that's not standard and is one that I
| | 02:23 | wrote just to get around this issue.
| | 02:25 | And then finally we are unsetting
the view variable from the query array.
| | 02:30 | So let's take a look at
ExploreGetAlias and ExploreGetItemid.
| | 02:35 | So the ExploreGetAlias function is
going into the Activities table or the Tours
| | 02:41 | table depending on whether we
have an activity or a tour record.
| | 02:46 | And it's going to go and look up that
id in the database and when it looks up
| | 02:51 | that id it's also going to
select the alias that matches that id.
| | 02:55 | So that way we get the URL alias that
we want to build into the URL and we can
| | 03:01 | use that in place of the numerical id.
| | 03:04 | So after we've built that query and
we set it we just load the text result.
| | 03:09 | We don't want an object or an array or anything;
| | 03:11 | we just want that text result.
| | 03:14 | And when we return it from that
function, it gets added back up here into
| | 03:18 | the segments array.
| | 03:19 | And now finally let's take
a look at ExploreGetItemid.
| | 03:24 | So ExploreGetItemid is taking the
view as an argument and we are taking
| | 03:29 | that view and going back to the
database and looking up the menu table and
| | 03:35 | we are getting the Itemid;
| | 03:36 | that's when you select this id from that
table, and we are looking for any links
| | 03:41 | that are pointing specifically to the
com_explore component with that view and
| | 03:47 | then this client_id bit here at the
end is making sure that we are getting a
| | 03:51 | menu link that's pointing to
the front end and not the backend.
| | 03:55 | So after we set this query in the
database, again we just load result because we
| | 04:00 | just want that numerical id;
| | 04:01 | we don't want any objects or
arrays or anything like that.
| | 04:05 | So we are returning that from this
ExploreGetItemid function, and then we are
| | 04:09 | setting the Itemid here. Now Joomla
| | 04:12 | is going to take a look at that Itemid
and automatically going to look that up
| | 04:17 | in the database and use that as the base
URL rather than the Itemid I passed in before.
| | 04:23 | So let's take a look at all of
this in action in the front end.
| | 04:26 | Let's go and click the Activities link
here in the Main menu and if we click on
| | 04:32 | California Hot Springs, you're either
going to get a blank screen, or you're
| | 04:36 | going to get some errors on screen
because we haven't yet written the function
| | 04:40 | that parses out the URL, but you will
notice that we have a nice clean URL here.
| | 04:45 | We have explore as the base of the Joomla
| | 04:48 | installation, and then we have activity
as the activity single record base link,
| | 04:54 | and then we have the alias
california-hotsprings as the end of the URL.
| | 04:59 | We don't have any hidden ids or
views or anything like that in the URL;
| | 05:04 | it's just very nice and
clean and human friendly.
| | 05:07 | So, let's click back and let's change
this router code just a little bit to show
| | 05:13 | what happens if you don't
unset all those variables.
| | 05:16 | For instance, if I go back here and I
neglect to unset that id, if I comment
| | 05:22 | that out and save this file and hit
Refresh, I can click on the California Hot
| | 05:28 | Springs link and you'll
notice now we have a ?id=3.
| | 05:33 | So it's very important that when you
have access to this query array that you
| | 05:39 | unset any variables that you no longer need.
| | 05:42 | That way they don't
appear at the end of the URL.
| | 05:45 | So, now if we go back to the Activities
list and click on California Hot Springs
| | 05:49 | again, now we just have the clean URL again.
| | 05:53 | When you add a router.php
file to your component Joomla
| | 05:56 | assumes you will have a build
route function ready to build links.
| | 06:00 | Use this function to generate the
segments of your URL and unset variables
| | 06:04 | as you interpret them.
| | 06:06 | Any remaining variables will be
appended to the end of the URL in a
| | 06:10 | standard query string.
| | Collapse this transcript |
| Parsing custom URLs| 00:01 | It is not enough to build custom
urls with router.php, they must also be
| | 00:05 | interpreted back when links are clicked on.
| | 00:08 | Let's add a data parts route function
to the router.php file in the Explore
| | 00:11 | California Component.
| | 00:13 | So first go to the Exercise files and
open up router.php, we have a couple of
| | 00:19 | new functions here, one is called
ExploreParseRoute and the other one is called
| | 00:23 | ExploreGetIDFromAlias.
| | 00:24 | So we are going to copy both of these
functions into our existing router.php file.
| | 00:31 | First let's copy ExploreParseRoute, go
to components>com_explore and router.php
| | 00:40 | in your installation.
| | 00:43 | And just paste that ParseRoute
function right underneath the BuildRoute1, and
| | 00:48 | then we are also going to pickup that
other function, we are going to go pick-up
| | 00:51 | ExploreGetIDFromAlias.
| | 00:57 | After copying this function, you can paste it
pretty much anywhere you want, in this file.
| | 01:02 | I'm going to put it right underneath
the ExploreGetAlias and now I will go
| | 01:08 | ahead and save this file.
| | 01:12 | So first we have ExploreParseRoute,
ExploreParseRoute is a standardized Joomla
| | 01:17 | function name, Joomla
| | 01:19 | is going to look for a function that
starts with the name of the components, in
| | 01:23 | this case Explore, and then it's going
to add ParseRoute and so when it puts it
| | 01:29 | all together you get
ExploreParseRoute and Joomla
| | 01:32 | is going to look for this function
whenever it has a URL that it can't
| | 01:36 | interpret on its own.
| | 01:37 | So it's going to pass in the
segments, that it can't interpret.
| | 01:42 | What we are essentially doing is
undoing, what we did in BuildRouteQuery.
| | 01:47 | In this case we get the segments from
the URL and we are building back the
| | 01:52 | Query Array here in vars.
| | 01:55 | So first, we're going to get the
current menu item and make sure that we
| | 02:00 | actually have a menu item, so that we
can get the view from that menu item And
| | 02:05 | in most cases we will.
| | 02:07 | So if the menu item is set, after we
get it from getApplication, getmenu,
| | 02:11 | getActive we are going to set the
view variable in the query string.
| | 02:16 | So we are going to look in the item and
look in the query array that's a part of
| | 02:21 | that item and get the view property
from that array and then set that in vars
| | 02:26 | view, and then we are going to count
the segments of the URL that Joomla
| | 02:30 | could not handle on its own and we are going
to check to make sure that we have a least one.
| | 02:35 | So if we do have a segment we are
going to use that segment as the alias for
| | 02:38 | the record, we're going to reverse lookup that
alias and get the ID back that matches the alias.
| | 02:45 | So we pass in not only the first
segment of the array, we are also passing in
| | 02:51 | the view that we just set and then once
we have set the ID in the vars array, we
| | 02:57 | return the vars array.
| | 02:59 | So these variables are going to get
merged in with all the other variables in
| | 03:03 | the http request and we will be
able to get them through the J request
| | 03:07 | functions, just like we
would any other variable.
| | 03:10 | Let's take a look at this
ExploreGetIDFromAlias function.
| | 03:14 | Now this is not a standard Joomla
| | 03:15 | functions, this is just a function
that I wrote, so I could get the ID given
| | 03:20 | the alias and the view.
| | 03:22 | So first we get a database query
object, before we send the alias into the
| | 03:27 | database query string what we need to do
is do a little prep on the alias string
| | 03:33 | itself because what happens is when
the alias comes through in that segments
| | 03:37 | array, all of the hyphens are changed to colons.
| | 03:42 | So this is just a nasty little surprise
if you're not prepared for it you just
| | 03:48 | do a simple string replace and
that changes the alias string back.
| | 03:52 | So after that, we do a getEscaped
function on the alias, we have sent that
| | 03:57 | through getEscaped, so that it is
ready to go into the database and we don't
| | 04:02 | accidentally run any SQL commands.
| | 04:04 | And then we build our query.
| | 04:07 | Depending on what view it is, we're
going to select from different tables.
| | 04:12 | So for instance if we are doing an
activity view, we want to look in
| | 04:15 | the activities table.
| | 04:17 | So for an activity, we are going to
select the activit_id from the activities
| | 04:21 | table, given the alias that we have.
| | 04:24 | If it's not an activity and it's not a
tour we just return zero and in that case
| | 04:31 | we really shouldn't get here to begin
with, but it just gives us a nice default
| | 04:35 | value that's safe to use.
| | 04:37 | And finally we set the query in the
database and then load the result, we
| | 04:41 | don't bother with an object or an array or
anything like that and we just return that value.
| | 04:46 | So that value gets setback here in vars ID.
| | 04:50 | So now that we have these functions in
the file, make sure to save the files
| | 04:54 | that we haven't yet and let's go
back and take a look at how it works.
| | 04:59 | We are going to go to the activities
link here on the main menu and just click
| | 05:03 | on california HOT SPRINGS, so where
before you might have got an error because
| | 05:08 | we didn't have the parseroute function in place.
| | 05:11 | We now get the record
for california HOT SPRINGS.
| | 05:15 | What a parseroute function is added to
router.php you have a chance to interpret
| | 05:19 | the url and rebuild the variables as
they came from the query string, and then
| | 05:23 | you're able to load up records.
| | Collapse this transcript |
|
|
12. JavaScript in Joomla!Considering DOM libraries| 00:00 | JavaScript is gaining popularity
among web developers in recent years.
| | 00:04 | This is in no small part due to the
advent of JavaScript-based DOM or Document
| | 00:09 | Object model, manipulation
libraries, such as Mootools and JQuery.
| | 00:14 | Let's take a quick look at the history of
DOM manipulation and how Joomla handles it.
| | 00:19 | Previously, DOM manipulation used to
be extremely difficult, programmers
| | 00:25 | would avoid anything that had to do with
JavaScript just because it was so much of a pain.
| | 00:31 | Cross browser support was an absolute joke.
| | 00:34 | You would try to do something in
JavaScript in one browser and it would
| | 00:38 | completely not work in the other one and
you would have programmers doing things
| | 00:42 | like, trying to detect which browser
they were running and it was just a
| | 00:46 | terrible awful mess.
| | 00:48 | The result was that programmers
completely avoided JavaScript.
| | 00:53 | It wasn't until DOM manipulation
libraries came along that that began to change.
| | 01:00 | Eventually, JavaScript became a necessity.
| | 01:04 | We really exhausted what you could do
through forms and HTML and CSS and it just
| | 01:11 | got to the point where JavaScript was
the only option you had for creating Rich
| | 01:17 | Internet applications.
| | 01:19 | You just couldn't do it without JavaScript.
| | 01:22 | And so eventually, DOM libraries were
authored to handle all those cross browser issues.
| | 01:27 | So you didn't have to detect whether
you are using Internet Explorer or whether
| | 01:32 | you are using Firefox or Safari or any
of these other web browsers, your DOM
| | 01:37 | manipulation library was detecting which
browser you're using and then adjusting
| | 01:42 | the code that you are writing based on that.
| | 01:45 | So as long as you do everything through
the DOM manipulation library, you're safe.
| | 01:50 | JavaScript has just flourished
since the advent of these libraries.
| | 01:54 | So now you can pull in a library
like JQuery and write all of your DOM
| | 01:59 | manipulation through that and then
regardless of which browser you're running,
| | 02:04 | JQuery is just going to interpret that
for the browser that you're working with
| | 02:08 | and it'll make everything work nicely.
| | 02:11 | So while JQuery is one of the more popular
DOM manipulation libraries out there, Joomla
| | 02:17 | uses Mootools.
| | 02:18 | Mootools has some very similar
functionality, but there are some things that you
| | 02:22 | have to keep in mind when you're using
Mootools and JQuery together and we are
| | 02:26 | going to take a look at that soon.
| | 02:29 | So for front end programming, JavaScript
has come a long way in a short period of time.
| | 02:34 | Fortunately, Joomla
| | 02:36 | ships with JavaScript tools and scripts
that are ready for your next extension.
| | 02:40 | There is no need to avoid
JavaScript programming anymore.
| | Collapse this transcript |
| Calling existing MooTools scripts| 00:00 | Joomla ships with not only the Mootools
JavaScript library, it also includes several
| | 00:04 | Mootools based scripts
ready to handle common tasks.
| | 00:08 | Let's add a Mootools powered feature
to the Explore California Component.
| | 00:12 | First, let's take a look at the Activities list.
| | 00:15 | At the moment we just have California
HOT SPRINGS and a few of these other
| | 00:19 | activities and we unpublished
some of the activities earlier on.
| | 00:24 | So let's make sure that all the
activities are published so that they are
| | 00:28 | ready for us to look at.
| | 00:29 | Let's go back to the backend
and login as admin and lynda.
| | 00:35 | Go to Components and Explore
California and Activities and then check off
| | 00:41 | Backpack Cal and
California Calm and click Publish.
| | 00:45 | So now the status of those two is set to
published and we can log out at the backend.
| | 00:51 | And now when we hit Refresh on the
Activities view, you'll Backpack Cal
| | 00:55 | and California Calm.
| | 00:56 | Let's click on Backpack Cal and you'll
notice that we have several tours that
| | 01:01 | are available underneath Backpack Cal,
and those have links, and when you click
| | 01:06 | on those links those go to the tours.
| | 01:09 | Let's go back to the Backpack Cal page.
| | 01:12 | We're going to apply an effect to all
these links, so that instead of leading to
| | 01:16 | a separate page all the
information appears in a modal window.
| | 01:21 | Sometimes you'll hear this referred to
as a Lightbox effect and very frequently
| | 01:26 | also Modal or SqueezeBox and they're
all talking about this effect where the
| | 01:31 | background kind of fades and
you have this window that pops up.
| | 01:35 | So let's add that effect.
| | 01:36 | Go to the Exercise Files and then go to
views>activity>tmpl and open up default.php.
| | 01:44 | So you'll notice up at the
top we have JHTML (behavior:
| | 01:48 | modal) and this is the function call that
will bring in all the JavaScript we need.
| | 01:53 | It's going to bring in Mootools,
it's going to bring in the modal script,
| | 01:57 | it's going to bring in everything we
need and we don't have to worry about
| | 02:00 | all the scripts that we need, this behavior.
modal function call takes care of everything.
| | 02:06 | And then next, we're building
the URL slightly differently.
| | 02:10 | The current URL structure does not have
this tmpl variable in the URL, tmpl is a
| | 02:16 | special URL variable that Joomla
| | 02:18 | uses when you want to change
the output of what's on screen.
| | 02:24 | When you set tmpl to component, it's
only going to return the component output;
| | 02:29 | it's not going to wrap the component
output in the templates like you normally see.
| | 02:34 | Finally, we're going to change the link itself.
| | 02:37 | We've added a class called modal, and
then we've also added this property called
| | 02:42 | rel, and rel is going to allow us
to configure the pop-up a little bit.
| | 02:47 | First we want to handle it through an
iframe tag, and then we want to size this
| | 02:53 | window to a specific size, so we
wanted to be 800 wide by 500 tall.
| | 03:00 | So let's go to our component in
the front end and apply this code.
| | 03:04 | Go to components>com_explore>views>
activity>tmpl and the default.php file.
| | 03:14 | So here first, we're going to copy in
that JHTML call and just make a little
| | 03:18 | room for it up here, and then we're going to
copy everything from URL on down to the semicolon.
| | 03:27 | We're just going to replace this
variable assignment so we get that that tmpl
| | 03:32 | variable inside the URL.
| | 03:35 | And then finally copy everything from
class="modal" on down through the row.
| | 03:43 | And then when you have all that, save
the file and let's go back to the Front
| | 03:47 | end and refresh the record.
| | 03:50 | So now when we click on the links,
you'll notice that the record for the Big Sur
| | 03:54 | Retreat appears in this modal window,
that's layered on top of the window that
| | 03:59 | we came from, and all the details for
this Big Sur Retreat are in this window.
| | 04:05 | And then to close out of it, we can just
click the X and we'll returned back to the screen.
| | 04:10 | Now in this case we don't want to keep
this modal effect on this specific page
| | 04:15 | because we're going to use
it for some other things.
| | 04:19 | Let's take a look at the Head
section of the HTML document to see all the
| | 04:23 | JavaScript that got added.
| | 04:24 | So first you'll notice up at the top
there is media/system/js/core.js and
| | 04:30 | mootools-core.js and this is pulling in all the
core JavaScript for Joomla and for Mootools.
| | 04:36 | There is also modal.js which is
pulling in the modal effect which we loaded
| | 04:40 | through that JHTML call and it's
pulling in mootools-more for some
| | 04:45 | dependencies and then down here we have a
script where it simply setting up that modal effect.
| | 04:52 | It's finding all of the links with the
class of modal and it's parsing that rel
| | 04:57 | attribute so that it pulls in all the
configuration that we're trying to pass
| | 05:02 | into the SqueezeBox.
| | 05:03 | We're going to remove this modal effect because;
| | 05:06 | we do not want to keep this on this
view because we're going to use this view
| | 05:10 | for some other things.
| | 05:12 | Go back to the default.php file and
just remove the rel and the class, remove
| | 05:18 | that tmpl and component, and then
also remove JHTML::_('behavior: modal').
| | 05:29 | And then when you save and click
Refresh here in the Front end and click on one
| | 05:34 | of the links, it's back to normal.
| | 05:37 | Mootools libraries are easily called
through the behavior functions of the JHTML class;
| | 05:42 | you don't even have to write a single line
of JavaScript to use the effect. Joomla
| | 05:46 | automatically includes
Mootools and the extra script.
| | Collapse this transcript |
| Using MooTools and jQuery together| 00:00 | Although Joomla Includes the Mootools framework,
jQuery has become the runaway favorite DOM
| | 00:05 | manipulation library across the web.
| | 00:08 | Well, you can include jQuery in Joomla
| | 00:10 | you need to make sure to take some
precautions, so that jQuery and Mootools
| | 00:14 | can safely coexist.
| | 00:16 | Let's add jQuery, along
with a script that uses it.
| | 00:20 | Let's pull up a tour.
| | 00:21 | Let's go to Activities>Backpack
Cal and go to the Big Sur Retreat.
| | 00:28 | Right now, we just have a
description of the tour along with some of the
| | 00:32 | Highlights and the Details and we're
going to get some things ready so we can
| | 00:37 | add a map to this view.
| | 00:39 | We're not going to add the map in this
video yet, but we're going to prepare
| | 00:43 | some things, so that we can add that map later.
| | 00:46 | So first, let's go to the media
folder in the Exercise Files and go to the
| | 00:51 | com_explore folder underneath that.
| | 00:53 | Inside there is a js folder and we
have a copy of jQuery, a jquery-noconflict
| | 01:00 | file and tour_map.js.
| | 01:02 | We're going to copy all three of these
JavaScript files into the media folder of our site.
| | 01:07 | So go to media, go to com_explore and
then copy the js folder into that folder.
| | 01:17 | So let's take a look at
some of these JavaScript files.
| | 01:20 | Let's take a look at jQuery itself.
| | 01:23 | It's completely minified, so you're
not going to be able to read it, but this
| | 01:26 | is the entire jQuery library scrunched down so
that it downloads very fast and it still works.
| | 01:35 | Next, we have a jquery-noconflict file.
| | 01:39 | This is something that I've
written specifically for Joomla
| | 01:41 | It will be included as a file and it
will send jQuery into no-conflict mode.
| | 01:48 | It's very important to include
this because if you don't have this in
| | 01:51 | place sometimes Mootools and jQuery are
going to conflict over the dollar sign variable.
| | 01:58 | And then finally I have tour_map.js.
| | 02:04 | We have jQuery document ready and is
the function that you call, to make sure
| | 02:10 | that you don't run any of the code
that's inside the function that you pass in
| | 02:14 | until the browser has finished loading
the page, and this is important because
| | 02:20 | if you start running the JavaScript
before the page is loaded, you'll end up
| | 02:25 | trying to scrape data off a
page that isn't there yet.
| | 02:29 | All I'm doing here is getting the tour_
location for my get_location function and
| | 02:35 | then sending that data as an alert on screen.
| | 02:39 | So my get_location function just goes
and uses jQuery to get the element with
| | 02:45 | the id of tour_location and gets
the HTML content from that element.
| | 02:50 | And then it stores it in the location variable.
| | 02:53 | Then it just returns location,
California and then when we get the value from
| | 02:59 | that, that just goes to alert.
| | 03:01 | Now we need to make a few
adjustments to the HTML to make sure that that
| | 03:05 | tour_location information is in place.
| | 03:10 | Let's go back to the tour folder, go to
tmpl and there is the layout for the tour.
| | 03:17 | Open up this file.
| | 03:18 | We're getting the document object, and
then we're calling the addScript function
| | 03:23 | of that document object to add jQuery,
noconflict file, and the tour_map.
| | 03:29 | We also have some content down here at
the bottom, where we're going to have the
| | 03:34 | tour_map and some other
information about the tour.
| | 03:38 | So let's open up the layout file for
this on the current component and update it.
| | 03:44 | Go to components>com_explore, go to
views>tour>tmpl and open up default.php.
| | 03:57 | So first, let's copy in
these calls to addScript.
| | 04:02 | Just make a little room up here up at
the top, and then we want to add this div
| | 04:15 | down here with the id of tour_right.
| | 04:18 | So you'll notice here we have the id of tour_
activity and we have an id of tour_location.
| | 04:26 | jQuery in our JavaScript file is
going to take a look at tour_location and
| | 04:33 | return whatever content we
have in this paragraph tag.
| | 04:39 | Another thing you'll notice is we're
calling jquery, and then we're calling the
| | 04:43 | jquery-noconflict file right after it.
| | 04:46 | This is extremely important, because
if you don't have the noconflict call
| | 04:50 | happening right after jQuery, it
won't send jQuery into noconflict mode and
| | 04:55 | you can still run into conflicts, even if
you have that script elsewhere on the page.
| | 05:00 | So if you have saved this file, let's
go back to Firefox and reload the page.
| | 05:05 | We have an alert here saying, Big Sur,
California because it is pulled that data off the HTML.
| | 05:12 | Let's click OK and scroll
down to the bottom of the page.
| | 05:15 | You'll notice that Big Sur is down
here at the bottom and that is the element
| | 05:20 | that has the id of tour_location.
| | 05:23 | Let's take a look at view source here
for a moment and we can see Mootools and
| | 05:27 | jQuery living together.
| | 05:28 | So notice we've our jQuery call up
here with no conflict right underneath.
| | 05:34 | Then we've tour_map.js and now
we've mootools-core and mootools-more.
| | 05:39 | We have Mootools on the same page
as jQuery and we don't have any other
| | 05:43 | JavaScript errors or problems,
it's all just working together.
| | 05:47 | Adding jQuery to a Joomla
| | 05:49 | site is possible, when you take the
appropriate precautions for interacting with Mootools.
| | 05:53 | Once you have jQuery included in your
component, you have access to all the DOM
| | 05:58 | Manipulation and querying by jQuery.
| | 06:01 | Just make sure you load jQuery
into noconflict mode the correct way.
| | Collapse this transcript |
| Marking tours with Google Maps| 00:00 | When component deals with records that
are related to physical locations in the
| | 00:03 | world, it makes sense to add
a map showing those locations.
| | 00:07 | Google Maps provides an extensive API
you can use to map specific locations.
| | 00:12 | Let's add a Google Map to the
individual tour view in the Explore
| | 00:15 | California component.
| | 00:17 | First, let's load up a single tour view.
| | 00:19 | Go to Activities and Backpack Cal
and then click on Big Sur Retreat.
| | 00:25 | Notice that we have a JavaScript alert
that's just showing the location and we
| | 00:30 | can clear this alert by clicking OK and
we're going to replace this JavaScript
| | 00:34 | with one that loads up a Google
Map and displays it on the right.
| | 00:38 | Let's go to the Exercise Files.
| | 00:41 | Go to the media folder and go to com
_explore and first let's go to css.
| | 00:47 | So there is a tour_map.css file here and
we want a copy that into the media folder.
| | 00:52 | So go to com_explore and css and
just copy tour_map.css right in.
| | 00:59 | Let's take a look at tour_map.
| | 01:02 | All we're doing here is creating a two-
column layout where we're going to have
| | 01:05 | the tour information on
left and the map on the right.
| | 01:09 | Let's add some JavaScript now.
| | 01:10 | Go to js folder and then also
go to the js folder on your site.
| | 01:18 | First, let's copy in gMap, gMap is
jQuery plug-in that you can use to bridge
| | 01:24 | jQuery and the Google Maps API.
| | 01:28 | Next, we're going to
modify the tour_map.js file.
| | 01:32 | Open up the one from the Exercise
Files and then open up the one that's
| | 01:37 | currently in the component.
| | 01:41 | At the moment we're simply
dumping the tour_location into an alert.
| | 01:44 | Let's replace this alert with our call to gMap.
| | 01:47 | So copy this entire block and
replace the alert with that block.
| | 01:53 | So notice first that jQuery is finding
the element on the page with an id of
| | 01:59 | tour_map, and then it's
calling the gMap plug-in on that.
| | 02:04 | The gMap plug-in allows us to control
the Google Map and it allows us to specify
| | 02:08 | what zoom level we want and where we
want to center the map, and then what
| | 02:13 | markers we want to have on the map as well.
| | 02:15 | So we're using the tour_location not
only to center the map, but we're also
| | 02:19 | using it as one of the markers.
| | 02:21 | We're only using one address with this
markers array, but if we wanted to we
| | 02:25 | could add more elements and more markers.
| | 02:28 | Be sure to save this file
and then close out of it.
| | 02:33 | The next thing we need to do is
update the layout of the tour.
| | 02:36 | So go back up to the tour folder
and then go to the default.php file.
| | 02:43 | Also go to the default.php
layout in your current view.
| | 02:48 | So go to components>com_explore>
views>tour>tmpl and default.php.
| | 02:59 | First, we're pulling in the Google Maps API.
| | 03:03 | Just copy this line and paste it
right beneath the getDocument call.
| | 03:09 | Next, we're going to copy in the
StyleSheet that we added, that's going to
| | 03:12 | create the left and right columns.
| | 03:16 | And then we're also going
to copy in the gMap plug-in.
| | 03:19 | This is going to act as the bridge
between the Google Maps API and jQuery.
| | 03:26 | Before we refresh, let's get
rid of the second level header.
| | 03:30 | It's now going to be a duplicate.
| | 03:33 | After you've saved the layout, go back
to the Front end and refresh the page.
| | 03:39 | You'll notice now that we have all the
details about the Retreat on the left and
| | 03:43 | we have a map of where Big
Sur is located on the right.
| | 03:47 | Adding a Google Map to a component is
made easier when a jQuery plug-in is used,
| | 03:51 | not only can jQuery be used to generate
the Google Map, it can also be used to
| | 03:55 | pull up the address to be marked on the map.
| | Collapse this transcript |
| Marking multiple addresses with JSON| 00:00 | While marking a single location on
a Google map is straightforward;
| | 00:03 | marking multiple locations on the map
requires a more sophisticated approach.
| | 00:08 | Instead of embedding all the information
in HTML and scraping it through JQuery, we
| | 00:12 | can generate JSON object from
the server with all the locations.
| | 00:16 | We are going to add a map on the
single activity view that maps all the tours
| | 00:21 | that are part of that activity.
| | 00:23 | Go to Activities and BACKPACK CAL,
and you will notice that we have five
| | 00:28 | different tours right now that
are published for BACKPACK CAL.
| | 00:31 | We are going to create a map that's
going to appear on the right next to this
| | 00:35 | list of all the tours.
| | 00:38 | First, let's go to the Exercise files.
| | 00:41 | Go to the media folder and com_explore
and we have both a css folder and js folder.
| | 00:47 | First let's copy in the css, go
to media>com_explore>css and just
| | 00:53 | copy activity_map in.
| | 00:55 | Let's take a look at activity_map.
| | 01:00 | Just like the single tour view we are
setting up a multicolumn layout, so that
| | 01:04 | we have the information on
the left then map on the right.
| | 01:08 | Next we are going to go to the js folder.
| | 01:11 | Copy the activity_map js file
into the js folder on your site.
| | 01:19 | This script is a little bit different
from the one that we used for the tour map.
| | 01:22 | This time we are waiting for the
document to be ready, and then we are telling
| | 01:27 | JQuery to do a JSON request back to Joomla
| | 01:31 | to get some information.
| | 01:32 | Part of what we are doing, is we're
scraping an ID from the HTML and adding it
| | 01:38 | to our JASON request. That way Joomla
| | 01:40 | Will know which record we want data for.
| | 01:44 | Notice that we are calling index.php
and we are using the com_explore option.
| | 01:49 | So that points back to
Explore California component.
| | 01:52 | We are loading up the activity view, we
are setting tmpl to component so that we
| | 01:57 | don't get the template output, and then
we are setting format to json, so that
| | 02:02 | we get to json formatted string
back instead of the entire template.
| | 02:07 | Now notices this getJSON function call
has three parts, there is first the URL
| | 02:12 | that we're going to call, next is a set
of all the different parameters we want
| | 02:17 | to send to that URL and then
the third parameter is a function.
| | 02:21 | This function is called when JQuery is done
getting the response back from the server.
| | 02:27 | So when it gets that response it passes
it in as this argument JSON, and then we
| | 02:32 | can pass JSON over to the gMap plug-in.
| | 02:35 | Instead of trying to build the object
to pass into the gMap plug-in here in
| | 02:40 | JavaScript, we are actually going to
build it on the server and then pass it
| | 02:44 | directly into the plug-in.
| | 02:46 | So let's add some code that will
return this JSON formatted string.
| | 02:51 | Go back up to the activity folder in
the Exercise files and we are going copy
| | 02:56 | view.json.php over to the activity view.
| | 03:02 | Go back to components>com_explore>
views and activity and copy view.json.php
| | 03:11 | right next to view.html.php.
| | 03:14 | Now you'll notice that this looks kind
of similar and there's a reason for that.
| | 03:18 | When we make that getJSON call in
JavaScript and we send over the format and
| | 03:23 | set the format as JSON, it's going to
load this view.json.php file instead of
| | 03:30 | the view.html.php file.
| | 03:32 | That way we can use the same
view to output both JSON on an HTML.
| | 03:38 | So let's open up the view.json.php file.
| | 03:42 | You'll notice that this array looks
slightly familiar, we have the zoom level
| | 03:47 | set to 5, just like we did in
JavaScript in the tour video, we have the
| | 03:51 | address set to California USA, this
time we just want to center the map right
| | 03:57 | on the middle of California and to start off
with we have an empty array for the markers.
| | 04:03 | After that we get all the tours from a
model, and then we cycle over each tour
| | 04:08 | that's assigned to that activity.
| | 04:10 | Firstly check to make sure that we
have a valid location for the tour because
| | 04:14 | we don't know about location it's just
going to give us a blank marker that
| | 04:18 | will be erroneous and then if we do have a
valid location for the tour, we add it as an array.
| | 04:24 | So we keep appending array elements to
the markers array in the response array
| | 04:29 | and then set the address and the
HTML properties for each array element.
| | 04:35 | The address element is used to make the
marker just like we did for the tour map
| | 04:40 | and in the HTML element is used to set
a name that will be available when you
| | 04:45 | click on that marker.
| | 04:47 | Finally, once we're done building this
response array, at the very end we simply
| | 04:52 | output the response array after it
has been passed through JSON and code.
| | 04:57 | Finally, we need to update the
layout, go to tmpl folder and open up
| | 05:02 | default.php, first we need to all
these groups along with the CSS file, copy
| | 05:08 | this entire block starting with
where we get the document object.
| | 05:14 | Open up default.php on your site and then
make a little room and add those assets.
| | 05:21 | We are getting the google maps api, we
are getting JQuery and sending it into
| | 05:29 | no conflict mode, we are getting the
gMap plug-in, and then we are getting the
| | 05:33 | activity map JavaScript file and then finally we
are adding the CSS that will style this layout.
| | 05:40 | We need to make a couple of
adjustments to the markup so that it has room for
| | 05:45 | the map and has all the data that it needs.
| | 05:47 | So the first thing we are going to do is
update this div with the rel attribute,
| | 05:54 | just copy this rel attribute and paste
it right next to the idea of activity.
| | 06:01 | The JavaScript that we've added
earlier is going to look for the ID of
| | 06:04 | activity and return the element, then
we are going to rel attribute which will
| | 06:10 | be ID for the activity.
| | 06:13 | Finally, copy these two divs from the
bottom, the first div is activity right
| | 06:24 | and that's where the activity map is
going to be displayed and then the second
| | 06:28 | div is a footer that we are adding so that
people can go back to the activities list.
| | 06:33 | Save the file and then go back
your web browser and hit Refresh.
| | 06:38 | You'll notice now that we have the
tour information on the left, and then we
| | 06:42 | have a marker for each tour on the
right, if we click on one of the tours, it
| | 06:47 | shows us the name of each tour.
| | 06:51 | When a complex JavaScript data
structure is needed, don't cram the HTML markup
| | 06:56 | with data points, instead generate a
JSON object on the server side and pull it
| | 07:01 | back into the browser at runtime.
| | 07:03 | This makes it much easier to do
sophisticated tasks, like marking multiple
| | 07:07 | addresses on a Google map.
| | Collapse this transcript |
| Detecting existing copies of jQuery| 00:01 | JQuery is definitely popular, perhaps
a little too popular for its own good.
| | 00:05 | Unfortunately, many Joomla
| | 00:06 | extensions include their own copy of
JQuery, regardless of whether or not
| | 00:10 | another extension has already loaded it.
| | 00:12 | However, it's possible to check the
JDocument object to discover if any JQuery
| | 00:17 | files have already been loaded.
| | 00:18 | So let's add some code now that will
help us detect multiple copies of JQuery.
| | 00:23 | First let's go to the
Exercise Files, open up explore.php.
| | 00:27 | You will notice in here that there is
an include statement that starts at the
| | 00:32 | JPath component that will always pull
in the path to the current component
| | 00:35 | that's being loaded, and then
we're pulling in /helpers/jquery.php.
| | 00:40 | We are going to copy this line straight
into the explore.php file for our component.
| | 00:46 | So go to Components>com_explore, and
then open up explore.php, and copy it
| | 00:54 | right there at the top.
| | 00:58 | Now we need to copy that helpers folder.
| | 01:00 | So copy the helpers folder over from the
exercise files, on over to com_explore.
| | 01:05 | Let's take a look at the helper file.
| | 01:09 | Here we have a class called
ExploreJQuery and we are just using that as a way
| | 01:14 | of name spacing this function away from any
other functions that are loaded into Joomla
| | 01:20 | We have one function in the
class called already_loaded.
| | 01:24 | This function will get the JDocument
object using JFactory::getDocument.
| | 01:29 | Then we call the getHeadData
function on the document object.
| | 01:33 | This will return an array with all
the different head_data items that are
| | 01:37 | available in the document.
| | 01:39 | Next, we're only concerned with the scripts.
| | 01:42 | So we're going to pull the scripts
element from the head_data array and cycle
| | 01:48 | over each one and take a look at the
name of each script, and then as we cycle
| | 01:53 | over every script that's been added to
the document, we're going to test to see
| | 01:57 | if 'jquery' is included in the name of
that file, if it is, we return true, if
| | 02:04 | it gets through this entire array
and doesn't find any JQuery files, this
| | 02:08 | function will return false.
| | 02:10 | So this way we can use the getHeadData
function from the JDocument object, give
| | 02:14 | us an array of all the scripts that are
already loaded and that way we can look
| | 02:18 | through and see if we can find any
copies of JQuery that are already_loaded.
| | 02:22 | Next, let's add this function call to our views.
| | 02:26 | Go to the views folder in your Exercise
files and open up the Activity folder,
| | 02:31 | inside there go to default.php and now
we have the ExploreJQuery::already_loaded
| | 02:37 | function being used here.
| | 02:39 | Notice also that we've added a
copy of JQuery from the googleapis.
| | 02:45 | Let's copy in this entire block,
all the way from the part where we're,
| | 02:48 | including JQuery from the googleapis, on
down to where we're testing to see with
| | 02:54 | whether or not JQuery is already_loaded.
| | 02:56 | So go to Views>activity and go to the
default.php file, and then from here just
| | 03:08 | replace these two lines with
the block that we've just copied.
| | 03:12 | So now let's navigate to single activity view.
| | 03:15 | Go to the Activities link and
select one of the Activities.
| | 03:20 | So you'll notice that our map is still
loading, so JQuery is still working and
| | 03:24 | let's take a look at the document head,
view source on this page, so you'll
| | 03:28 | notice now that we're pulling the
Google version of JQuery instead of the
| | 03:33 | locally hosted version that we
have in our Joomla Installation.
| | 03:36 | That function is detecting that we've
already added JQuery to the document and
| | 03:41 | it's not, including it again.
| | 03:44 | Let's go back and edit this file,
just though that we are not, including
| | 03:47 | the Google version.
| | 03:49 | So go back and remove this line, save the
file and then go back and refresh the page.
| | 03:55 | So now it's pulling the local version of JQuery.
| | 03:59 | Let's add this code also
to the single tour view.
| | 04:02 | Go to the tour folder and then open up
default.php, and again, just copy this
| | 04:09 | block with the if statement, then
replace these two lines with the if statement,
| | 04:22 | that will make sure that
we don't load JQuery twice.
| | 04:26 | Now let's navigate to a tour, go to Big
Sur Retreat, and you will notice the map
| | 04:32 | is still working, this means our
component was able to detect that JQuery wasn't
| | 04:37 | already loaded, so it loaded JQuery,
and then it also loaded the script to
| | 04:40 | generate the Google Map.
| | 04:42 | Although multiple copies of JQuery
may still be floating around in Joomla
| | 04:45 | installations for sometime to come, it's
possible to avoid contributing to the problem.
| | 04:50 | Before calling up a copy of JQuery,
check the JDocument object to make sure
| | 04:54 | another extension has not already loaded it.
| | Collapse this transcript |
|
|
13. The "Favorites" FeatureGetting personal with users| 00:00 | Whenever you want to get information about
the user currently logged into the site, Joomla
| | 00:04 | provides it in a readily available object.
| | 00:07 | Let's log into the site, grab this object
and have a look at everything it provides.
| | 00:11 | So first, let's go to the Exercise files
and get some code that uses the user object.
| | 00:19 | Copy everything from this user
variable on down through the if statement.
| | 00:23 | Now open up explore.php in your Joomla
| | 00:28 | site in the front end and
paste that code right here.
| | 00:32 | What this code is doing is it's
getting the user object from this
| | 00:36 | JFactory::getUser function.
| | 00:38 | Then once we have the object, we can
test the ID property of this object.
| | 00:42 | If we have a user ID, we assume that a
user is logged into the system and we
| | 00:46 | display a greeting with all
sorts of information about the user.
| | 00:50 | Otherwise, we display a message
saying, please log into the site.
| | 00:53 | So let's go to the explore
component now and see this code in action.
| | 00:57 | So if we go to the Activities view, currently
it says Please log in so what I can greet you.
| | 01:03 | So let's scroll down to the
bottom and log into the site.
| | 01:06 | Log in with the admin as the
User Name and lynda as the Password.
| | 01:09 | Now that we are logged into the site,
it's greeting us with Hello Super User,
| | 01:15 | which is our given name, your
username is admin, you can be emailed at
| | 01:19 | info@explorecalifornia.org,
and your numerical user id is 42.
| | 01:25 | This numerical user id is very important,
because you can use this to key other
| | 01:29 | records in database tables that
you create for your own purposes.
| | 01:33 | So you don't have to create another
table that's keeping track of users, you
| | 01:38 | can just use Joomla's!
| | 01:39 | core user table and key off of that id.
| | 01:42 | Let's go back to our explore.php file
and remove this code and when we refresh
| | 01:50 | the page, it's gone. Joomla
| | 01:52 | provides all the vital information
about a user in a ready-to-use object.
| | 01:56 | Just call JFactory::getUser to get it.
| | 01:58 | Once you have this object, you can
copy the user id and use it as a key in
| | 02:02 | other database tables.
| | Collapse this transcript |
| Assigning an onClick event| 00:00 | Many times you want to take action
when users click on a specific onscreen
| | 00:04 | element, rather than creating a
traditional link, it's possible to assign an
| | 00:09 | onClick event to an element then
take appropriate action afterwards.
| | 00:12 | Let's add an element to our tour view
and give it onClick event, let's go to
| | 00:16 | the Exercise files and add the CSS and
JavaScript, they will be necessary to drive this.
| | 00:21 | Let's go to the media
folder>com_explore and css.
| | 00:26 | Open up the tour_map.css file and
you'll notice at the bottom there are
| | 00:31 | three new declarations;
| | 00:32 | one for the tour_favorite id, and then
a class for .favorite_inactive and one
| | 00:37 | for .favorite_active.
| | 00:38 | Let's copy these three declarations
and paste them into our current css file.
| | 00:44 | Go to media>com_explore>css and tour_
map.css and then just scroll to the
| | 00:51 | bottom and paste them in.
| | 00:53 | Next, let's go back up to the
JavaScript folder and add in the
| | 00:58 | tour_favorite.js file.
| | 01:00 | Just copy this entire file
into the js folder on your site.
| | 01:07 | Inside this JavaScript file we are
calling the jQuery ready function and making
| | 01:12 | sure that the HTML document is ready
before we start executing this JavaScript.
| | 01:17 | Next, we are finding the
element with the id of tour_favorite.
| | 01:20 | We're assigning a click event
to this tour_favorite element.
| | 01:24 | Whenever a user clicks on his element,
this function is going to execute.
| | 01:29 | The first thing this function does is
test the rel attribute of the element.
| | 01:34 | If it's set to no, we assume that the
user wants to set the favorite, and if
| | 01:39 | it's set to yes, we assume that
the user wants to unset the favorite.
| | 01:43 | So in the event that they want to set
the favorite, we remove the class inactive
| | 01:48 | and we add the active class, then we
set the rel attribute to yes, otherwise we
| | 01:54 | remove the active class, add the
inactive class and set the rel attribute to no.
| | 02:00 | Now we are going to update
the layout to use this function.
| | 02:08 | Go to tour>tmpl and open up default.php and
now open the default.php layout in the view.
| | 02:19 | Go to views>tour>tmpl and default.php.
| | 02:28 | First, let's copy in tour_favorite.js
and now let's copy in the element with the
| | 02:35 | id of tour_favorite.
| | 02:38 | Notice that this is a span element.
| | 02:41 | It starts off with the rel attribute
set to no, it starts with the class set to
| | 02:46 | favorite_inactive and then the inside of
the element is a UTF-8 code and this is
| | 02:52 | the UTF-8 code for a star.
| | 02:54 | So let's go to the front
end and go to a tour view.
| | 02:57 | Go to activities, go to Backpack Cal, go to
Big Sur Retreat and now you'll see this star.
| | 03:06 | If we click on the star, it becomes
highlighted and if we click on it again, it
| | 03:11 | unhighlights, that's the JavaScript file
removing and adding the classes and the rel attribute.
| | 03:18 | Assigning an onClick event is a great
way of turning an onscreen element into
| | 03:22 | something that can be used to run JavaScript.
| | 03:24 | Just make sure you check the state of
the element so you can provide appropriate
| | 03:28 | visual feedback to the user.
| | Collapse this transcript |
| Setting favorites| 00:00 | We need a method for making Favorites
of the database, to do this let's add a
| | 00:04 | Control that talks to a
model returning a JSON response.
| | 00:08 | So first, in order to set
Favorites, we need to login to the site.
| | 00:12 | So go down to the Login Form and Login
as admin and lynda and once you're logged
| | 00:19 | in, now let's add some code that
will allow us to add Favorites.
| | 00:23 | Go to the exercise files and first go
to the administrator folder we are going
| | 00:27 | to add another Jtable class.
| | 00:33 | So copy favorites.php and paste it
into the backend of your component, go to
| | 00:38 | components, com_explore, tables,
and then just paste it right in.
| | 00:49 | This table class is like the other
one, except this one is talking to the
| | 00:53 | explore favorites table
and has a key of favorite ID.
| | 00:57 | Next, let's add some code to the front end
that will receive our requests for new favorites.
| | 01:07 | Go to the components folder in your
exercise files, first go to the models
| | 01:13 | folder and you'll notice a file that is
favorites.php, we are going to copy this
| | 01:19 | into the models folder for the
front end of our component, so go to
| | 01:23 | components>com_explore and models,
and then paste the file here.
| | 01:30 | Notice we are using this as a model list and
we will be adding a list query to this later.
| | 01:36 | For the moment we have two
functions, one is addFavorite, and one is
| | 01:39 | removeFavorite, both of these
functions require a tour ID and a user ID.
| | 01:45 | For the addFavorite function we are
getting to favorites table object, then we
| | 01:50 | are setting the tour id and we are
setting the user id, and then we are
| | 01:55 | storing the record.
| | 01:56 | For the removeFavorite function, we are
getting a database object and getting a
| | 02:01 | fresh query, then we are calling the
delete function for the query object and
| | 02:05 | we are passing in the name of the
favorites table, then we are adding in two
| | 02:09 | conditions, we want to delete the
favorite, where it's the tour id of the tour
| | 02:14 | that we are trying to delete as well the
user ID that's trying to delete the favorite.
| | 02:18 | Then we are setting the query in the
database object and calling the query
| | 02:22 | function which runs the query right away.
| | 02:25 | So now that we have the model in place,
let's add a controller where we'll be
| | 02:29 | able to receive requests,
for adding new favorites.
| | 02:31 | Go to controllers, we don't have a controllers
folder in the front end of the component yet.
| | 02:38 | So just copy the controllers
folder right into com_explore.
| | 02:44 | Let's take a look at favorites.json.php.
| | 02:47 | As you will notice json is the part of
the name of this file, this means that
| | 02:55 | whenever we have a response coming back
from this controller, it's going to be
| | 02:59 | sent back to the browser in json format.
| | 03:02 | The first thing that we are doing is
we are overloading the constructor.
| | 03:05 | We are first calling the parent
constructor function, after we have called that
| | 03:10 | function, then we are ready to register tasks.
| | 03:13 | Now you may remember that
every task in a controller has a
| | 03:18 | corresponding function.
| | 03:19 | However, it's also possible to overload
functions, so that you can have multiple
| | 03:24 | tasks going to the same function, this
is what we want to do for the setFavorite
| | 03:29 | function, we have an unfavorite task and
a favorite task and the only difference
| | 03:33 | between these two tasks is the
value that we are sending in, otherwise,
| | 03:38 | everything is completely the same.
| | 03:41 | So now in the setFavorite function, we
can get the actual task that was used in
| | 03:46 | the request and then key off that to
determine whether we want to add a favorite
| | 03:50 | or remove a favorite.
| | 03:52 | Next, we get a tour id, we need to get
the ID of the tour that we want to mark
| | 03:56 | either as a favorite or remove the favorite.
| | 03:59 | Then we get the model for the favorites,
you can do this in the controller by
| | 04:03 | calling to getmodel function and then
passing in the name of the model that you want.
| | 04:08 | Then we get the user ID from the
user object and store it in user id.
| | 04:14 | Now this point we want to make sure
that the person that is requesting this
| | 04:19 | favorite or unfavorite, is
actually logged into the web site.
| | 04:23 | If we have a user id that means that
someone is logged in and we're going to
| | 04:28 | go ahead and make the request, otherwise we
are going to bail and give a state of error.
| | 04:34 | If a user is logged in,
then we test the task variable.
| | 04:38 | If it's set to favorite, that means
we are going to add a favorite to the
| | 04:41 | database, but if it's not set the
favorite, we are going to assume that it's
| | 04:45 | unfavorite, and we want to
remove the favorite from the database.
| | 04:48 | So here we are just calling the
model functions that we defined over in
| | 04:51 | the favorites model.
| | 04:53 | And then finally, we return to state,
and what we do is we return the task
| | 04:57 | that was requested.
| | 04:58 | Now with the model and controller in place,
we can make a request and set a favorite.
| | 05:04 | To do that we are going to
type in a rather long URL string
| | 05:08 | index.php?option=com_explore&task=favorites
.favorite&format=json&tour_id=1&tmpl=raw.
| | 05:29 | Now notice here than the task is
favorites.favorite, what this is doing is
| | 05:34 | saying we want to load the favorites
controller and execute the favorite task on it.
| | 05:39 | When we hit Enter, Firefox prompts
us to download the Joomla.json file;
| | 05:44 | we are going to do that to
see what the response is.
| | 05:49 | So choose TextMate or another text
editor here and then click OK, you'll see
| | 05:58 | that the JSON response has a state set
to favorite and now we can go into the
| | 06:02 | MySQL database and take a look at what
happened, go to phpMyAdmin and go to your
| | 06:13 | database where you have Joomla
| | 06:15 | installed and then go to the favorites
table, browse the table and you'll see
| | 06:23 | favorite ID of 1 tour ID of 1 and then
the user ID, this all the information
| | 06:29 | that we need to track which
tour was favorited by which user.
| | 06:32 | Setting favorites in a database is possible
through a controller that talks to a model.
| | 06:37 | Now that we have a method for setting
favorites in the database, it's possible
| | 06:40 | to hook this up as an
asynchronous JavaScript request.
| | Collapse this transcript |
| Interpreting JSON responses| 00:00 | When we sent an asynchronous request to Joomla
| | 00:02 | using JavaScript it's helpful to interpret
the response and update the user interface.
| | 00:07 | Let's add some JavaScript that makes a
request, interprets a JSON response, then
| | 00:12 | updates the user interface.
| | 00:14 | First, let's go to the Exercise Files.
| | 00:16 | Let's go to the media folder and
com_explore, and open up the js folder.
| | 00:22 | Notice we have a tour_favorite.js file;
| | 00:25 | it has some new code t that we are
going to update the existing file with.
| | 00:28 | So go to the media folder of your site
and go to com_explore, and js, and then
| | 00:35 | open up the tour_favorite.js file there.
| | 00:41 | Completely replace everything
within the jQuery(document).ready call.
| | 00:45 | So just copy in this function and this
jQuery call and just replace this body here.
| | 00:57 | First, let's take a look
at the jQuery at the bottom.
| | 01:00 | Again, we're looking for the element
with the id of tour favorite and we're
| | 01:05 | assigning a click function to it.
| | 01:07 | When this element is clicked, first we check the
rel attribute of the element. If it's set to no.
| | 01:12 | we assume that the user wants to add
a favorite and if it's set to yes, we
| | 01:16 | assume that the user
wants to remove this favorite.
| | 01:19 | So first we test the rel
attribute of this element.
| | 01:23 | If it's set to no, we assume that
the user wants to set a favorite.
| | 01:26 | so we pass favorite into changed state.
| | 01:29 | Otherwise we assume that the user
wants to remove a favorite, so we pass
| | 01:33 | unfavorite into changed state.
| | 01:35 | Let's take a look at the
change state function now.
| | 01:38 | First, we're making a post with jQuery and
we're posting to the index.php file of Joomla
| | 01:43 | Then we have the request variables, we
are setting option to com_explore and we
| | 01:48 | are setting the task to favorites.
| | 01:50 | and then the name of the state
that we want to set the favorite to.
| | 01:54 | So we are either going to
have favorite or unfavorite here.
| | 01:57 | Then we have format of json, we have
tmpl of raw, and then for the the tour_id,
| | 02:03 | we are going to scrape the tour_id from
the element with the idea of tour, and
| | 02:08 | get the rel attribute from it.
| | 02:11 | Finally, after this request is
executed, jQuery is going to send the
| | 02:15 | response back here.
| | 02:17 | We are going to test the
state property of the response.
| | 02:19 | If it's favorite, that means we are
going to remove any inactive class, and
| | 02:23 | add the active class, and then set the rel
attribute to yes, to show that star is yellow.
| | 02:29 | Otherwise, we're going to remove the
active class and add rel as no, and that
| | 02:34 | way it'll show the star as gray again.
| | 02:37 | So now that we have this JavaScript in
place we need to make one last adjustment.
| | 02:41 | You'll notice up here we have this
tour_id element and we're getting the
| | 02:45 | rel attribute off it.
| | 02:47 | We need to add that rel attribute to
that element so that it's there when this
| | 02:51 | JavaScript goes to look for it.
| | 02:54 | So let's go back up to the Tour View in the
Exercise Files and then open up default.php.
| | 03:04 | Notice we have a rel attribute here
and it just has the id of the tour.
| | 03:08 | So let's copy it and we're going to paste
it into the layout for our existing view.
| | 03:13 | So go to the front end of your component.
| | 03:18 | Go to com_explore and views and
go to the tour view and go to the
| | 03:23 | default.php layout.
| | 03:27 | Then just paste that rel attribute in.
| | 03:30 | So now that we have the rel attribute
available, let's go back to the front end
| | 03:34 | of the component and try to set a favorite.
| | 03:37 | First, we need to log into the site,
so log in as admin and Password lynda.
| | 03:43 | Next, let's go to a tour.
| | 03:44 | Go to Activities, and then pick
Backpack Cal, and then choose the
| | 03:49 | Channel Islands Excursion.
| | 03:51 | Now what you want to do is click that star.
| | 03:54 | Now let's check phpMyAdmin to see
if that made it to the database.
| | 03:58 | Go to phpMyAdmin, load up
the database where Joomla
| | 04:06 | is installed, then select
explore_favorites, and then click Browse.
| | 04:12 | You'll notice now that we have a
tour_id of 2 with a user_idea 42.
| | 04:17 | That means that our favorite got set.
| | 04:19 | Now you may not notice this in your
table right away, and there are a couple of
| | 04:23 | things that might have gone wrong.
| | 04:25 | One of the possibilities is that the
asynchronous request still hasn't made it back to Joomla
| | 04:30 | yet, and it still has yet to appear,
so you might need to wait a second
| | 04:35 | and refresh the table.
| | 04:37 | Another possibility is that the JavaScript
file from one of the previous videos got cached.
| | 04:42 | So what you want to do is make sure
you do a hard Refresh on the browser and
| | 04:46 | make sure that the browser got the new
JavaScript file rather than the old one.
| | 04:50 | Let's try unsetting this favorite and
going back and browsing the table again.
| | 04:56 | And you'll see now that the favorite is gone.
| | 04:58 | JSON makes it easy to read a
response code from the server in JavaScript.
| | 05:03 | When you create asynchronous code, wait
until you get a response from the server
| | 05:07 | before you update the user interface.
| | 05:09 | If you try to update the user
interface right away, you may cause the user to
| | 05:13 | make unintended requests.
| | 05:15 | So always read the response code
back from the server to keep your
| | 05:18 | user interface in sync.
| | Collapse this transcript |
| Presetting a favorite state| 00:00 | With asynchronous code in place, it's
necessary to make sure the layout starts
| | 00:04 | with the correct data.
| | 00:05 | Let's adjust the layout to get the
Favorite state of the tour from the model.
| | 00:09 | First, let's log in to the
site, log in as admin and lynda.
| | 00:17 | Let's go to Activities and let's go to
Backpack Cal and let's go to The Death
| | 00:23 | Valley Survivor's Trek.
| | 00:26 | Now first let's set this as a favorite.
| | 00:29 | Now if we hit Refresh, you'll notice
that the favorite is not set, that's
| | 00:36 | because we haven't updated this view
to check the favorites, and then set
| | 00:40 | the star appropriately.
| | 00:41 | So let's do that now.
| | 00:43 | Let's go to the Exercise files
and first let's go to the model.
| | 00:52 | There is a new function in
this model called getFavorite.
| | 00:54 | We are going to copy this function
and paste it into our existing model.
| | 00:58 | So go to the front end of your component, go to
| | 01:02 | components>com_explore>models and tour.php.
| | 01:10 | At the bottom of the model,
paste in the function.
| | 01:14 | We're doing several things with this function.
| | 01:16 | First, we are getting the tour_id, and
then we are also getting the user_id.
| | 01:21 | Then if a user is logged in, we do a
database query to check to see if the tour
| | 01:25 | has been favorited by this user.
| | 01:27 | We do a fresh query, and then we
select from the favorites table where the
| | 01:32 | user_id and the tour_id are set.
| | 01:34 | Then we set the query in the
database and load the object.
| | 01:38 | Now if the query fails, it's
just going to return null or false.
| | 01:42 | Now if there is a record,
it's going to return it in row.
| | 01:45 | So if there is a row there, we'll
return true, otherwise if there isn't a row
| | 01:49 | here, this function is going to return false.
| | 01:52 | So let's save this file and
let's update the tour view.
| | 01:58 | Go to views>tour and open up view
.html.php in the Exercise files.
| | 02:07 | It's pretty much the same file as
before, only we're now getting the favorite
| | 02:11 | and setting it in the view.
| | 02:12 | So let's add this to our view now.
| | 02:14 | Go to views>tour>view.html.php and
open it, copy in the favorite property and
| | 02:27 | also copy in the call to the model.
| | 02:33 | After saving the file, we have one
more update to make, let's go to the
| | 02:38 | layout for this view.
| | 02:44 | Now we have an if statement
in place of the single span.
| | 02:47 | In this case we're now checking to see
if favorite is set to true, and if it's
| | 02:50 | set to true, we set the span with
rel equaling yes and favorite_active,
| | 02:56 | otherwise, we set rel to no and
the class of favorite_inactive.
| | 03:01 | So let's copy this if statement and
paste it into the layout in our component.
| | 03:08 | Go to tmpl and default.php, and open it up and
just replace this span with that if statement.
| | 03:21 | So now that we have this in our layout,
let's go back to the browser and refresh.
| | 03:27 | We should now see our favorite marked
when we refresh this page and there it is.
| | 03:33 | We can unfavorite it, and go back to the list.
| | 03:41 | We can favorite it again, and hit
Refresh, and it still stays there.
| | 03:47 | Once you've moved code into the
asynchronous realm, it's necessary to make sure
| | 03:51 | that your initial state is set properly.
| | 03:53 | Be sure to update your models and views
to accommodate data that may have been
| | 03:57 | set in an asynchronous request.
| | Collapse this transcript |
| Listing favorites| 00:00 | Collecting favorites from the user isn't
so useful if they can't go back and see
| | 00:04 | a list of all their favorites.
| | 00:05 | The user object in Joomla
| | 00:07 | will make it possible for us to get the
favorites of the logged in user, then display them.
| | 00:12 | Let's add new view for favorites now.
| | 00:14 | First, let's go to the Exercise files.
| | 00:16 | We are going to update the favorites
model to have a list query that will get
| | 00:20 | all the favorites from the
database for the logged in user.
| | 00:25 | Copy the function getListQuery and now
open the favorites model in the explore
| | 00:31 | component of the front end of your site
and now paste in that that function just
| | 00:40 | right here up at the top.
| | 00:41 | So we are getting the tour_id and the
tour_name from tours table, as well as the
| | 00:48 | activity_name from the activities table.
| | 00:50 | We're selecting everything from the
favorites table and then joining in the
| | 00:54 | tours and activities, and then we are
limiting everything to the id of the
| | 00:58 | currently logged in user.
| | 00:59 | Notice that we are getting the user
object, and then we are getting the id right
| | 01:03 | off that object, and then
finally, we're returning the query.
| | 01:07 | Be sure to save this file and close it
out and let's go and add the favorites view.
| | 01:12 | Since we don't already have a
favorites view in the site, go to the views
| | 01:17 | folder and just copy the favorites folder from
the Exercise files directly into the views folder.
| | 01:23 | So let's take a look at the
files that make up this view.
| | 01:27 | First we have view.html.php.
| | 01:30 | It's calling get('Items') from the
model and just returning the results and
| | 01:34 | storing them in favorites.
| | 01:38 | Next, let's take a look at the layout.
| | 01:43 | First, we have a heading for the
favorites view and then next, we are counting
| | 01:47 | the favorites that have
been assigned to the view.
| | 01:49 | If there aren't any favorites, we're
going to echo out a placeholder that says
| | 01:54 | go and add some favorites before
you come back and see this view.
| | 01:57 | Otherwise, we are going to cycle over
the favorites and then link to every tour
| | 02:01 | that the user has favorited.
| | 02:03 | Those links are going to have the
tour_name along with the activity_name.
| | 02:07 | Finally, let's take a
look at the default.xml file.
| | 02:12 | This default.xml file is very similar
to ones and the other views and it's here
| | 02:16 | so that we can link to
this view from the backend.
| | 02:20 | Let's go back to the
backend now and link to this view.
| | 02:27 | Login as admin and lynda.
| | 02:30 | Let's go to menus> Main
menu and Add New menu Item.
| | 02:34 | From here we are going to select a
menu Item type and we're going to select
| | 02:38 | Favorites from the list.
| | 02:40 | Type in Your Favorites as the menu
Title, and before you save this menu Item,
| | 02:48 | we're going to set the Access.
| | 02:49 | Right now, it's set to Public
and we want it to be Registered.
| | 02:54 | That way if someone isn't logged in to
the front end of the site, they don't see
| | 02:57 | this menu Item and they're not
distracted by something that they can't use.
| | 03:01 | So we are going to save and close this
link, and then go back to the front end,
| | 03:06 | so you notice when I refresh and I
am logged out, I don't see that link.
| | 03:10 | But if I go down and log in as admin
with password, lynda, now we see Your
| | 03:17 | Favorites displayed here.
| | 03:19 | Let's click Your Favorites and then go
to Backpack Cal, and let's unfavorite it.
| | 03:27 | If we go back, it still shows it there
and that means we just need to refresh.
| | 03:31 | So after we refresh, it goes away.
| | 03:34 | Let's also unfavorite the Big Sur Retreat.
| | 03:36 | Again, go back and refresh to
make sure it gets the current list.
| | 03:42 | Now you'll see the message that says
as you mark tours on this site as your
| | 03:45 | favorites, they will appear here.
| | 03:47 | So let's go back and mark some favorites.
| | 03:49 | Let's go to the Big Sur Retreat, mark it as a
favorite and then go back to Your Favorites.
| | 03:57 | A view containing the Favorites makes
it possible for users to go back and see
| | 04:00 | the tours they start. The Joomla
| | 04:02 | user object ensures that we always
get the ID for the logged in user, which
| | 04:06 | allows us to get their
favorites and none others.
| | Collapse this transcript |
|
|
14. Security and AccessStrategic security| 00:00 | Although security precautions have been
implemented throughout this course, it's
| | 00:03 | worth taking a step back and
looking at them more closely.
| | 00:07 | So the first thing that you always
want to do whenever you're building any
| | 00:09 | sort of web application, is you need to
validate the input that's coming from the user.
| | 00:14 | You want use the JRequest class in Joomla
| | 00:17 | that allows you to validate input.
| | 00:19 | So the base function that
JRequest provides is called getVar.
| | 00:23 | The first argument is the name of the
variable you're trying to retrieve and the
| | 00:27 | second argument is a default value
that you're going to provide in the event
| | 00:32 | that the variable isn't there in the request.
| | 00:35 | Now getVar doesn't really do a whole
lot of validation, it's very generic and
| | 00:39 | pretty much just gives
you the variable outright.
| | 00:42 | To get a little bit more specific,
among other functions, JRequest has
| | 00:45 | getString, getInt, getFloat, a get
function for pretty much any type of data
| | 00:51 | that you want to validate against.
| | 00:53 | And then in addition to using JRequest,
you can use JForm to do the validation.
| | 00:58 | So you want to use JForm whenever it's
practical, because right there in the
| | 01:02 | form you can specify what
you want to filter against.
| | 01:06 | In addition to validating the input,
you also want to escape the output.
| | 01:10 | The issue is that some of the data
that you're displaying onscreen might have
| | 01:15 | characters that are considered
to be special characters in HTML.
| | 01:19 | So you always want to escape your output,
so that you don't break your layout.
| | 01:23 | Another situation where you want to escape is
before you add a variable to a database query.
| | 01:29 | It's very important that you get the
escaped version of that variable, so that
| | 01:34 | any time that you have data that
might end up being interpreted as an SQL
| | 01:39 | command, that that gets properly escaped,
so that it's just treated as data and
| | 01:44 | not treated as a Command.
| | 01:46 | Another way of escaping things before they
go to the database is using the JTable class.
| | 01:51 | Anytime you bind the data to the
JTable class and then store it, Joomla
| | 01:55 | is automatically going to escape that
data before it goes to the database.
| | 01:59 | And then finally, use JForm to render
the elements onscreen whenever possible.
| | 02:05 | JForm is automatically going to escape
the date that you feed into it and that
| | 02:10 | way you can keep your HTML forms safe.
| | 02:13 | Another thing you need to do is
provide and check tokens whenever someone is
| | 02:17 | logged into the site.
| | 02:18 | What you're trying to do is
avoid cross-site request forgeries.
| | 02:22 | What can happen is, if someone is
logged into the site, and another web site is
| | 02:27 | aware of how your web site is
constructed, that other web site that the person
| | 02:32 | might be visiting can spoof a request to Joomla
| | 02:37 | and make it seem as if the user
that is logged into your Joomla
| | 02:40 | site is doing something in the database.
| | 02:43 | And you don't want that to happen.
| | 02:45 | You always want to make sure that the user
is actually submitting the form that Joomla
| | 02:50 | is receiving.
| | 02:52 | So first you want to add
form tokens with this php echo
| | 02:56 | JHTML::_('form.token') function.
| | 02:58 | Every token that gets added to the form is a
randomly named input with one as the value.
| | 03:04 | This way it makes it very difficult for
another web site to try and guess what
| | 03:08 | the name of the input is.
| | 03:10 | And then finally, you want to check
for the presence of that token with the
| | 03:14 | JRequest get token function.
| | 03:16 | And if that function fails, you want to
exit right away and say invalid token.
| | 03:21 | Another thing you want to
do is consider your hosting.
| | 03:24 | If you have control over the
environment where your code is going to be run,
| | 03:28 | it's best to thwart off security issues at
the server level rather than do it in your code.
| | 03:34 | One thing you can do is turn the
virtual directories off in Apache.
| | 03:38 | This supersedes the blank index.html
files that often get added to individual
| | 03:44 | folders into Joomla Extension.
| | 03:46 | A lot of times people will add these
blank index.html files to try to prevent
| | 03:51 | Apache from displaying the contents of a folder.
| | 03:54 | And while this is a somewhat acceptable
approach, if you're doing this on shared
| | 03:58 | hosting where you might not have
control over the virtual directory setting,
| | 04:03 | it's a good idea to just turn virtual
directories off, and then you don't have
| | 04:08 | the need for the index.html files at all.
| | 04:11 | And then finally, make sure that the
directory permissions are set correctly.
| | 04:15 | If you have all of your folders set as world
writable, you're asking for a lot of trouble.
| | 04:21 | Finally, deny, deny, deny.
| | 04:23 | Only run PHP from within Joomla
| | 04:26 | Always add the defined '_JEXEC' or die
statement at the top of your PHP files
| | 04:31 | and that way if people try to go directly to
the PHP files, they won't be able to run them.
| | 04:35 | You only want them to be
able to run through Joomla
| | 04:38 | Also, when it's appropriate, you
want to limit access to your code.
| | 04:42 | You want to make sure that only users
that are a part of the group that should
| | 04:46 | have access to that code can get to it.
| | 04:48 | So use the ACL system when appropriate.
| | 04:52 | Then finally, remove code that isn't being used.
| | 04:56 | If there is a security hole in code
that isn't being used and you have it on
| | 05:00 | your site, you have code there
that's not serving any purpose, yet it's
| | 05:05 | causing a security issue.
| | 05:06 | So just remove any code that you're not
using, and then you don't have to worry
| | 05:10 | about having a security issue in it.
| | 05:12 | While adopting specific techniques can
help towards common security attacks,
| | 05:16 | adopting a strategic approach
to securing your code is best.
| | 05:20 | Retrieve only the input you need.
| | 05:22 | Remove code that's no longer needed.
| | 05:24 | You don't have to worry about
security holes in code that isn't there.
| | 05:28 | And finally, when possible and
practical, limit access to your code.
| | Collapse this transcript |
| Throwing exceptions| 00:00 | When an error occurs, it's best to
stop the rest of the code from running.
| | 00:04 | However, just stopping in middle of the code
and exiting out of PHP is not the best solution.
| | 00:09 | Better approach is to
throw an exception. Joomla
| | 00:12 | is designed to catch exceptions,
gracefully stop the code and display an error
| | 00:16 | message if necessary.
| | 00:18 | Let's add a couple of
exceptions to the component.
| | 00:20 | First, let's take a look at an
example of why we need to throw exceptions.
| | 00:25 | Let's go to index.php and then option=
com_explore, then view=tour&id=zero.
| | 00:39 | So you'll notice here that this is
not loading any record whatsoever.
| | 00:45 | It's just loading the Shell for the view
and there is no data here, but we still
| | 00:51 | do see a marker on California and some blanks.
| | 00:56 | And this is really a screen that
nobody should ever see or be able to get to.
| | 01:00 | What we'd really like to do here is to
prevent users from getting to this screen
| | 01:06 | and instead show them a 404 message.
| | 01:08 | So let's add some code that will
throw an error and show that 404 message.
| | 01:13 | Let's go to the Exercise
Files, now go to the tour view.
| | 01:17 | You'll notice we have a view.html.php file here.
| | 01:21 | Let's open it and this is the same
as the file that's currently in our
| | 01:26 | component, it just now throws an exception.
| | 01:29 | So copy this if statement and we're
going to paste it into the view.html.php
| | 01:35 | file in our component.
| | 01:37 | Go to components>com_explore>views and tour.
| | 01:44 | Open up the view.html.php file
there and add that if statement.
| | 01:53 | So what's happening here is we're
getting the item from the model.
| | 01:56 | If the item doesn't actually exist,
it's going to return null or false.
| | 02:01 | So we test for null false here.
| | 02:03 | And if that's the case, we throw a new
exception and then the first argument we
| | 02:08 | pass is the message for the exception.
| | 02:11 | If the item doesn't exist, we're
going to throw a new exception.
| | 02:14 | The first argument is the message for
the exception, while the second argument
| | 02:18 | is the http status code for the exception.
| | 02:21 | Note that the exception class is
built into PHP, this is not a Joomla
| | 02:26 | specific feature, it's one that's built
right into PHP and Joomla is just using it.
| | 02:32 | So now after you save the file, go
back to the front end and hit Refresh.
| | 02:36 | You'll notice now we get
a 404 Not Found message.
| | 02:40 | This message here is coming from the
language string that we passed into the exception.
| | 02:45 | If you have Firebug, you'll
also notice that you have an error.
| | 02:49 | So go to Firebug and click on the All
tab if it's not already selected and
| | 02:55 | you'll notice that the request to get
this page is in red and is shown with a
| | 02:59 | status of 404 Not Found.
| | 03:04 | Let's take a look at the Favorites view.
| | 03:07 | First, make sure you're
not logged into the site.
| | 03:13 | Next, let's go to index.php
option=com_explore&view=favorites.
| | 03:22 | You'll notice that this is currently
displaying a message saying that, As you
| | 03:30 | mark tours on this site as your
favorites they will appear here.
| | 03:32 | Well, the problem is if someone isn't
logged into the web site, that's not
| | 03:36 | actually going to happen, it's
going to do attempt to mark a favorite.
| | 03:41 | And then when it sees that the person
isn't logged in, it's not going to do anything.
| | 03:45 | So what we really want to do for this
view is completely prevent people from
| | 03:49 | even seeing this message.
| | 03:51 | What we want to do is throw a
403 message for Access Denied.
| | 03:57 | So let's add that to this view now.
| | 04:00 | Go to the Exercise Files and then go to
the favorites folder and open up view.html.php.
| | 04:10 | You'll notice in this case we're not
even getting the items until we verify that
| | 04:16 | the user is actually logged in.
| | 04:18 | Let's copy this if statement and we're
going to paste it into the view.html.php
| | 04:24 | file for the favorites view.
| | 04:30 | Just replace all of the code that's here
and paste in the code from the Exercise File.
| | 04:35 | So let's go back to the browser and hit Refresh.
| | 04:39 | You'll notice now we get a 403 error
asking us to login to view our favorites.
| | 04:44 | And if we go to Firebug again,
you'll notice we now have a 403 Forbidden
| | 04:49 | status on this request.
| | 04:52 | By throwing exceptions, you can give Joomla
| | 04:54 | a chance to clean up and display an
error message, rather than just stopping in
| | 04:57 | the middle of your code.
| | 04:58 | The first argument accesses the
message, while the second argument is
| | 05:01 | interpreted as and http status code.
| | 05:04 | Throwing exceptions not only allows Joomla
| | 05:06 | to display errors, but it also
prevents visitors from seeing code in a
| | 05:10 | broken state.
| | Collapse this transcript |
| Logging activity with jLog| 00:00 | Keeping a log of key events is a good
way of having a record of what's happening.
| | 00:04 | If you ever suspect a hacking attempt,
you can use an activity log to see
| | 00:08 | who did what and when.
| | 00:09 | Let's create a log with entries for
each time someone saves an Explore
| | 00:13 | California activity to the database.
| | 00:15 | First, let's go to the Exercise files.
| | 00:18 | Go to the tables folder and
you will notice activity.php.
| | 00:21 | We currently already have this check
function in place and we are going to copy
| | 00:26 | in this log in code.
| | 00:29 | So copy everything from this
comment on down to log addEntry.
| | 00:32 | Now let's go to the backend of Joomla
| | 00:36 | and go to components>com_
explore>tables and activity.php.
| | 00:45 | Make a little bit of room
and paste in the login code.
| | 00:48 | You will notice that first we're
importing the joomla.error.log library.
| | 00:53 | Next, we are calling JLog::
getInstance to get an object for the log.
| | 00:58 | The argument that we are passing in
to getInstance is the name of the log.
| | 01:02 | Notice that the name ends in .php.
| | 01:05 | This is because the logs
folder is still web accessible.
| | 01:08 | After we are done making some
log entries, we'll take a look at
| | 01:11 | activity_saves.php and see how it gets secured.
| | 01:15 | Next, we create an entry for the log.
| | 01:18 | There is a comment element and inside
that comment element we're going to have a
| | 01:22 | string that has the entry that we want to log.
| | 01:25 | So in this case we have a string that
says Activity, and then we are using the
| | 01:29 | activity_id from this record, and then
we're saying modified by, and then we
| | 01:33 | are getting the name from the user
object of the name of the person who is
| | 01:36 | modifying this activity.
| | 01:38 | Finally, we pass the entry
array into log-> addEntry.
| | 01:42 | Once this is in place, the logging is set to go.
| | 01:45 | Let's log in to the backend of the site
and save some records, and then we are
| | 01:49 | going to go and see the
log and see what happened.
| | 01:57 | Go to administrator and then login as
admin, then use lynda as the password.
| | 02:03 | Let's go to Components>Explore
California and Activities, open up Backpack Cal
| | 02:08 | and click Save & Close, then open up
California Calm, hit Save & Close, then
| | 02:15 | open up California
Hotsprings and hit Save & Close.
| | 02:19 | Now this will have
generated three entries in our log.
| | 02:21 | So let's go to the logs folder in
our installation and see what happened.
| | 02:27 | Go all the way back to the Joomla
| | 02:28 | route and go to the logs folder, then
open up activity_saves.php and have a look.
| | 02:34 | Now you will notice right up at the
top here we have a statement saying
| | 02:38 | #<?php die('Forbidden.').
| | 02:41 | So if we try to go to this file in
the front end, you will notice that we
| | 02:51 | only see Forbidden.
| | 02:52 | This way people browsing the web won't
be able to see our logs and we'll just
| | 02:56 | see them when we go to them on the server.
| | 02:58 | So let's go, take a look and you will
notice that we have Activity 1 modified
| | 03:03 | by Super User, Activity 2 modified by Super
User, and Activity 3 modified by Super User.
| | 03:09 | Joomla's!
| | 03:10 | built-in login class is a great way to
log events that occur in your extensions.
| | 03:14 | Just pull in the class
and start logging entries.
| | Collapse this transcript |
| Restricting back-end access| 00:00 | By default, Joomla
| | 00:01 | has multiple levels of both
front end and back end access.
| | 00:05 | Some back end users are not
allowed to edit records and components.
| | 00:08 | Let's restrict access to the Explore
California back end, to only allow users
| | 00:12 | who can edit records.
| | 00:14 | Let's go to the Exercise files, open up
explore.php and you'll notice here that
| | 00:20 | there is an if statement
that is at the top of the file.
| | 00:23 | This is the only change that
has been made to this file.
| | 00:25 | So let's copy this if statement and
paste it into the existing explore.php file.
| | 00:31 | Go to administrator>components>com_explore
and open up the explore.php file there.
| | 00:37 | Make a little room at the top
and paste in the if statement.
| | 00:42 | So first we're getting the user object,
and then we are calling the authorized
| | 00:46 | function on that object.
| | 00:48 | Then the first argument is an action
that we want to authorize against and the
| | 00:52 | second argument is the name of the component.
| | 00:56 | So we want to make sure that the user
is authorized to manage com_explore.
| | 01:02 | Now if they are not authorized, this
function is going to return false and we'll
| | 01:07 | throw an exception saying that they're
not authorized along with the 403 error.
| | 01:12 | So let's log in to the back
end and see this code in action.
| | 01:16 | First, let's just log in with our
administrator username and password.
| | 01:20 | Go to administrator and login as
admin and then use the password lynda.
| | 01:27 | Now if we go to Components and
Explore California right now, and go to the
| | 01:31 | Activities list, it loads up just normally.
| | 01:34 | Now let's create a user that will be
able to log in to the back end, but won't
| | 01:38 | have access to the screen.
| | 01:40 | Let's go to Users>User Manager>Add New User.
| | 01:44 | We're going to give this user a name of
admin2 and make that the Login Name as well.
| | 01:51 | Then we are going to have a Password of
lynda and confirm that password and the
| | 01:57 | Email will be admin2@explorecalifornia.org.
| | 02:07 | Finally, we need to assign a group to this user.
| | 02:12 | Currently, Registered is selected, but we also
want them to be able to log in to the backend.
| | 02:17 | So click Manager on the Assigned User Groups.
| | 02:22 | Finally, click Save & Close.
| | 02:25 | Now let's log out of the
admin user and log in as admin2.
| | 02:33 | Remember to use lynda as the
password and now you will notice that the
| | 02:38 | backend is stripped down.
| | 02:40 | We don't have as many of these icons
here on the start page and the Components
| | 02:44 | menu has also been stripped down.
| | 02:47 | We also don't see the
Explore California component.
| | 02:50 | Let's try however to go directly
to the component through the URL.
| | 02:54 | So let's go to option=com_explore.
| | 02:58 | You will notice now that we get the 403
Error, because we are not authorized to
| | 03:04 | manage this component. Joomla's!
| | 03:06 | authorization functionality can be
added to your component to restrict access.
| | 03:10 | Check for specific levels of access
using the authorize member method of
| | 03:14 | the JUser class.
| | Collapse this transcript |
| Premium front-end access| 00:00 | Many operators' web sites want to
charge for multiple levels of access for the
| | 00:04 | content on their site.
| | 00:05 | Well the e-commerce portion is outside
of the scope of this course, we can't set
| | 00:10 | up the records for multiple levels of access.
| | 00:12 | So first let's go to the backend and
set up a group that will be the premium
| | 00:17 | group for our users.
| | 00:19 | Go to administrator and login as
admin and use the password lynda.
| | 00:24 | First we are going to go to Groups
and we're going to Add a New Group.
| | 00:28 | The group's name is going to be
Premium and we're going to set the Group
| | 00:32 | Parent to Registered.
| | 00:34 | This will allow people to log into the site.
| | 00:36 | Now click Save & Close.
| | 00:39 | So in addition to the group, we also
need to add an Access Level for the group.
| | 00:42 | So go to users, Access Levels,
and Add New Access Level.
| | 00:47 | The level title is also going to be
Premium and now we are going to select the
| | 00:53 | groups that have access to the premium level.
| | 00:56 | In this case we just want to assign the
Premium group to have access to the Premium level.
| | 01:01 | So now click Save & Close.
| | 01:03 | So now that we have our group set up,
let's create a user that will be able to
| | 01:07 | login and have access to this content.
| | 01:10 | Let's go to Users>User Manager and Add
New User and we're going to name this
| | 01:15 | user premium with a login name of
premium and the password will be lynda,
| | 01:21 | confirm the password and then
the Email address is going to be
| | 01:25 | premium@explorecalifornia.org.
| | 01:29 | Finally, let's assign a user group.
| | 01:32 | Registered is already pre-selected and
we now want to add premium as a group.
| | 01:38 | Now click Save & Close.
| | 01:40 | So now that we have our user setup,
let's make it possible to restrict certain
| | 01:44 | records only for the premium users,
let's go to the Exercise Files.
| | 01:49 | Open up the forms folder
and then open up activity.xml.
| | 01:53 | We are going to add a field to the form
for activities, so that we can say this
| | 01:58 | activity is a premium activity.
| | 02:01 | So copy this field at the bottom,
activity access, and we're going to paste it
| | 02:06 | into the existing JForm.
| | 02:08 | So go to administrator>components>com_explore
>models>forms and then open up activity.xml.
| | 02:18 | Scroll down to the bottom and then make
a little room underneath activity image
| | 02:23 | and paste in that field.
| | 02:25 | So you'll notice the field name is activity
access and the type is access level, so Joomla
| | 02:30 | is going to go into the database
and look at all the access levels and
| | 02:34 | automatically generate a drop-down based
on the access levels that are in the system.
| | 02:40 | The default is set to 1 and it's not required.
| | 02:43 | So let's save this JForm and
open up the form at the backend.
| | 02:48 | Go to Components>Explore California and
Activities and let's say the California
| | 02:52 | Calm is going to be a premium activity.
| | 02:55 | Currently, the access is set to Public,
and let's just change that to Premium.
| | 03:01 | Now click Save & Close.
| | 03:02 | So now if we open up California Calm again,
you'll notice that premium is the access level.
| | 03:09 | Now that we've assigned an access
level to California Calm, we need to change
| | 03:13 | the code in the front end
to honor that access level.
| | 03:16 | So let's go back to the Exercise
Files and go to the activity folder.
| | 03:20 | You'll notice we have view.
html.php file with some changes.
| | 03:26 | You'll notice there are a couple of lines of
code here that have been added to view.html.php.
| | 03:31 | So just copy them and we're going to
paste them into the view.html.php file
| | 03:35 | that's currently on the site.
| | 03:37 | So go to components>com_explore>
views>activity and open view.html.php.
| | 03:46 | Make a little bit of room and now we
have the code in place that will restrict
| | 03:50 | access to this view.
| | 03:52 | So first we're calling to
getAuthorizedViewLevels function on the user object
| | 03:57 | and this returns all the levels that
the user is currently authorized for.
| | 04:02 | Next, we're checking that activity
access column in the database that we set
| | 04:06 | through the JForm and now
we have an if statement.
| | 04:09 | First we're checking to make sure
that the activity access column in the
| | 04:12 | database has a value.
| | 04:14 | And if it does have a value, we're
also going to check to make sure that that
| | 04:18 | activity access level is in the array
of levels that have comeback from the
| | 04:23 | getAuthorizedViewLevels function.
| | 04:25 | Now if either of those conditions fail, we're
going to set the template layout to upgrade.
| | 04:32 | Now setting the layout as a way the you
can add another screen to a view without
| | 04:37 | having to replace a lot of
code in your main PHP file.
| | 04:41 | So we are going to copy this default
upgrade.php file right into our view.
| | 04:46 | So go to activity>tmpl and paste
that file right next to default.php.
| | 04:52 | So now if we go to the front end and we
go to activities, you'll notice we have
| | 04:58 | our list of activities.
| | 04:59 | And make sure you're not
logged in and go to California Calm.
| | 05:03 | So you'll now see that This content is only
available to Premium Subscribers. Sign up today!
| | 05:10 | So let's sign in as Premium and use
lynda as the password and let's go to
| | 05:18 | the activity again.
| | 05:19 | Go to activities and
California Calm and now it displays.
| | 05:23 | Now very interesting thing about Joomla's!
| | 05:25 | ACL system is that you may notice
that by default there is this group
| | 05:29 | called super users.
| | 05:31 | And you might assume that
super users can do anything.
| | 05:34 | However, this is actually
not the case, because Joomla's!
| | 05:38 | permission system is very specific.
| | 05:40 | You can have users that are not a part
of this group, yet still be super users
| | 05:46 | and not be able to view this content.
| | 05:48 | So let's log out as a premium member,
so now that we're logged out, it gives us
| | 05:53 | a message saying that This content is
only available to Premium Subscribers.
| | 05:57 | So now let's login as the
admin and lynda as the password.
| | 06:01 | So you'll notice that the message is still here,
even though we are logged in as a Super User.
| | 06:06 | So just be sure that when you're
setting up your groups that you have everyone
| | 06:10 | in the group that needs to be there. Joomla's!
| | 06:13 | access control list system can be
leveraged when you want to restrict view
| | 06:16 | access to a specific group of people.
| | 06:19 | Just remember that users must be
in the group to validate against the
| | 06:22 | access control list.
| | 06:23 | Even the so called Super Users will be
denied until they are added to the group.
| | Collapse this transcript |
| Checking out records| 00:00 | One of the advantages of
using software like Joomla
| | 00:03 | is that you can have multiple users logged in
to the backend making edits at any one time.
| | 00:08 | However, this does pose a problem.
| | 00:11 | How do you make sure that two people don't
edit the same thing at the same time? Joomla
| | 00:15 | has a solution for this.
| | 00:17 | Records get checked in and checked out.
| | 00:19 | Let's have a look at how
the checkout system works.
| | 00:22 | Let's go to phpMyAdmin and
have a look at the database table.
| | 00:28 | Go to the database where you have Joomla
| | 00:30 | installed and then open up
the explore activities table.
| | 00:35 | So you'll notice that at the end of
the table there are two columns, one is
| | 00:39 | called checked_out and what
is called checked_out_time.
| | 00:42 | If we browse this table, you'll notice
that checked_out is an integer, while
| | 00:46 | checked_out_time is a time and date stamp.
| | 00:50 | Checked_out and checked_out_time are
standardized column names in Joomla when Joomla
| | 00:53 | sees a database table with these two
columns, it will automatically take the
| | 00:59 | ID of the user a mark it on checked_out,
and it will also mark the time that
| | 01:03 | the checkout occurred.
| | 01:05 | So now let's create a situation where we
might have two different admins editing
| | 01:09 | the same record at the same time.
| | 01:11 | Let's log in to the backend of Joomla
| | 01:14 | login as admin and lynda.
| | 01:17 | Now let's go to the User Manager and
we're going to create a new user that has
| | 01:23 | the same level of access as our Super User.
| | 01:26 | We are going to call this person admin2
with a login name of admin2, a password
| | 01:33 | of lynda and Confirm it and then an
Email of admin2@explorecalifornia.org.
| | 01:40 | We're going to add another user that has
the same level of access as our current admin.
| | 01:46 | So let's go to Users>User Manager>Add New User.
| | 01:50 | The Name is going to be secondadmin
with a Login Name of secondadmin, the
| | 01:55 | Password will be lynda and the Email
will be secondadmin@explorecalifornia.org.
| | 02:02 | And finally, let's assign this user to a group.
| | 02:05 | Go down to the bottom and check off Super Users.
| | 02:09 | Now click Save & Close.
| | 02:11 | So now we have secondadmin and that'll
be ready to go when we're ready to log in
| | 02:15 | at the same time as this user.
| | 02:17 | Now are going to implement the
checked_out functionality for records.
| | 02:21 | Let's go to Components>
Explore California and Activities.
| | 02:24 | When we have the checked_out
functionality in place, we are going to display an
| | 02:28 | icon that let's other admins know that
a record is checked out, so that they
| | 02:32 | don't click on it and try to do any edits.
| | 02:35 | So first let's go back to the
Exercise Files and get some of this code.
| | 02:39 | First we're going to change the
model for the activities lists.
| | 02:42 | So open up activities and then
go to the getListQuery function/
| | 02:49 | We're now going to join in another table
so that we can get the name of the user
| | 02:54 | who's checked out the record if
the record has been checked out.
| | 02:58 | So copy everything from select and from
and join and we are going to paste that
| | 03:05 | into the model in the backend.
| | 03:07 | So go to administrator>components>com
_explore>models and activities.php.
| | 03:15 | So now we just want to replace these two
lines with our new query and then save it.
| | 03:22 | So after you have this query in place,
so now with our query in place, we now
| | 03:27 | need to update the view so that it
shows in a lock icon whenever someone else
| | 03:30 | has checked out a record.
| | 03:32 | Let's go back to the activities folder
and tmpl and then open up default.php.
| | 03:39 | This file is almost as same as it was
before, only we now have an if statement
| | 03:43 | here right before the link.
| | 03:45 | So copy this if statement, and we're
going to paste it into the layout in
| | 03:49 | the current backend.
| | 03:52 | So go to views>activities>
tmpl and open up default.php.
| | 03:59 | Make a little room above the
link and paste in that if statement.
| | 04:03 | So now, as we cycle over the
items in the list, it's going to check
| | 04:06 | the checked_out column.
| | 04:08 | If the checked_out column has a value
we're going to call JHTML, JGrid checked out.
| | 04:14 | We're also going to pass in the row
number, we're also going to pass in the name
| | 04:19 | of the user who has checked out the
record, then the time that user checked out
| | 04:23 | the record, and then we are going to
use activities as the prefix for the task.
| | 04:29 | So after you save this file, go
back to the backend and hit Refresh.
| | 04:33 | So you notice pretty much nothing is
changed and let's open up Backpack Cal as a
| | 04:39 | record we're going to edit.
| | 04:41 | So now that we've opened up Backpack Cal,
this has checked out the Backpack Cal
| | 04:45 | record in the database.
| | 04:46 | Now let's open up a separate browser
window and log into the backend with our
| | 04:50 | secondadmin username and see
what happens when we go to the list.
| | 04:55 | Go to administrator and login as
secondadmin and lynda as the password.
| | 05:03 | So if we go to Components and Explore
California and Activities, you'll notice
| | 05:07 | there is now a little lock icon next to
Backpack Cal and it will say that it was
| | 05:11 | checked out by Super User and
at what time and date we did it.
| | 05:15 | So let's try to open this record now.
| | 05:17 | You'll notice that we got an
error saying check-out failed with the
| | 05:20 | following user error.
| | 05:21 | The user checking out does not
match the user who checked out the item.
| | 05:25 | So this is warning us that it tried
to checkout the record but it couldn't,
| | 05:30 | because it's already checked out.
| | 05:32 | And now let's even try to make a change here.
| | 05:34 | Let's say Backpacks Cal and click Save
& Close and it will say now you are not
| | 05:41 | permitted to use that link
to directly access that page.
| | 05:44 | And you'll notice that the record did
not change, it's still Backpack Cal.
| | 05:48 | If we go back to the backend here and click
Cancel that will check the record back in.
| | 05:54 | So if we go back as the secondadmin and
hit Refresh, you'll notice now the lock
| | 05:58 | is gone, we can go make any changes
we want and the record saves normally.
| | 06:05 | I'm going to remove that
change and click Save & Close.
| | 06:09 | By adding standard field names to the
database table, you can hook into Joomla's!
| | 06:13 | checkout system.
| | 06:14 | Just be sure to also update the user
interface, so that people know when
| | 06:17 | records are checked out.
| | Collapse this transcript |
|
|
15. Plug-InsSelecting plug-in types| 00:01 | Plugins are the one extension type that
aren't necessarily visible on your Joomla site
| | 00:05 | They run in the background waiting
for certain events to be fired off.
| | 00:08 | Let's take a look at the different types
of plugins that can be built for Joomla
| | 00:12 | So the first plugin type we are going
to take a look at is authentication.
| | 00:16 | Authentication plugins allow
users to log in to the system.
| | 00:20 | By default, Joomla
| | 00:21 | is set up to use the core Joomla
| | 00:23 | Authentication plugin, and that one
authenticates against the Joomla database.
| | 00:28 | However, there are other
Authentication plugins out there.
| | 00:31 | For instance, you can authenticate
against Gmail and use Gmail as your login,
| | 00:36 | rather than the Joomla database.
| | 00:38 | The next type of plugins
are Editors and editors-xtd.
| | 00:42 | These are what you see as what
you get editors with their controls.
| | 00:46 | So the editor that ships with Joomla
| | 00:49 | is not the only option that you have,
it can also install other HTML editors
| | 00:54 | and those are installed as plugins, and
the editors-xtd plugin type allow other
| | 01:00 | buttons that interact with the editor, but
aren't necessarily specifically tied to that editor.
| | 01:05 | So the next type of plugin is the
Extension plugin type and this responds to
| | 01:10 | installation and
uninstallation events in Joomla
| | 01:14 | So if someone is uninstalling a plugin
that you really need for your extension,
| | 01:18 | you can stop that uninstallation
through an extension plugin type.
| | 01:22 | Next, we have the Search plugin type.
| | 01:25 | This will feed into the core com_search results.
| | 01:28 | This way if you want the records for
your component to show up in com_search you
| | 01:33 | can add a search plugin that will
automatically feed results from your component
| | 01:38 | into the search results.
| | 01:39 | The next plugin type is the User plugin type.
| | 01:42 | Whenever users are created or deleted
or a user has finished authenticating or
| | 01:46 | is just logged out, you can use this
plugin to do something right before or
| | 01:52 | after one of these events.
| | 01:54 | There are also Content plugins and these
plugins are concerned with when content
| | 01:59 | items are displayed.
| | 02:01 | Very typically, content plugins are used to
search and replace text within your content body.
| | 02:07 | And then finally, there are system plugins.
| | 02:09 | These are the base events in the Joomla
| | 02:11 | execution lifecycle.
| | 02:12 | So for instance, if you want to hook
into an event that happens after the Joomla
| | 02:18 | application is routed;
| | 02:19 | you can get that URL and then act upon it.
| | 02:22 | So in addition to all these
different plugin types, you can also define
| | 02:26 | custom plugin types.
| | 02:28 | All you have to do is come up with the
name of your custom plugin type and add
| | 02:33 | that to the XML manifest
for the plugin installation.
| | 02:36 | You can also use custom plugin events;
| | 02:39 | just give them names as
the functions in your plugin.
| | 02:42 | Just remember that all event names have
to start with the prefix on, but other
| | 02:46 | than that the plugin system is very
flexible, and you can just define any custom
| | 02:51 | plugin type you want or any
custom event that you want.
| | 02:54 | This way if you want to have custom
events for your component, you can have
| | 02:59 | those events and then allow third-
party developers to create plugins that
| | 03:03 | respond to those events. Joomla's!
| | 03:06 | predefined plugin types and events
allow you to hook into almost every level of
| | 03:09 | execution and when necessary, you can
also define custom plugin types and events
| | 03:15 | tailored for your extensions.
| | Collapse this transcript |
| Searching and replacing with system plug-ins| 00:00 | System plug-ins in Joomla
| | 00:01 | give us a chance to inject code into
any part of the execution flow, right up
| | 00:06 | until output is sent back to the browser.
| | 00:09 | Let's build a plug-in that will scan
the entire output of the page and turn
| | 00:12 | certain phrases into links.
| | 00:15 | First, let's take a look at where
these system plug-ins are fired.
| | 00:18 | Open up index.php and let's have a look.
| | 00:21 | You will notice this PROFILER
variable, its marketing after every system
| | 00:26 | event is being fired.
| | 00:27 | So we have afterLoad, afterInitialize,
afterRoute, afterDispatch and afterRender.
| | 00:35 | The one that we are going
to work with is afterRender.
| | 00:38 | So let's install this plug-in now.
| | 00:40 | Go back to the backend and login as
admin and lynda and then just install this
| | 00:48 | extension from the Exercise Files.
| | 00:50 | So now that we have installed this plug-in,
let's take a look at the files that it added.
| | 00:57 | Go to plugins>system and then
open up the tourlinks folder.
| | 01:03 | Open tourlinks.xml and let's
have a look at the manifest.
| | 01:07 | The extension type is plugin
and the plugin group is system.
| | 01:11 | Then also notice down here that
tourlinks.php is tagged as a file name with an
| | 01:16 | attribute of plugin= "
tourlinks". This tells Joomla
| | 01:20 | that the tourlinks.php file is the
main file to run when this plug-in is run.
| | 01:25 | Let's also take a look at tourlinks.php.
| | 01:29 | Notice that the class
here is plgSystemTourLinks.
| | 01:32 | The standard here is to have plg as the
prefix, System the name of the plugging
| | 01:37 | group as the second part and then the
suffix is TourLinks that's the name of the
| | 01:42 | plug-in that we are running and
it all extends to JPlugin class.
| | 01:47 | Now the event that we want
to hook into is onAfterRender.
| | 01:50 | So we define an onAfterRender function.
| | 01:53 | The first thing we want to do is check
to make sure that we are running this
| | 01:56 | plug-in in the front end of the site.
| | 01:58 | System plug-ins run in the
front end and in the backend.
| | 02:00 | So we want a make sure that we are
running this in the front end so that we
| | 02:03 | don't do any string
replacement on the backend output.
| | 02:06 | So to do that, we get the
Application object using the getApplication
| | 02:10 | function of JFactory.
| | 02:12 | Then we call the isAdmin function on
that object and if it returns true that
| | 02:17 | means we are in the
administrator portion of Joomla
| | 02:19 | and we don't want to run the plug-in, so
we just return right away and don't run
| | 02:24 | the plug-in into admin.
| | 02:26 | Next, we want to get the output that Joomla
| | 02:28 | has already assembled, to do that, we
are going to call to getBody function of
| | 02:32 | JResponse and store it in the output variable.
| | 02:37 | After we have the output, next we
want to do the string replacement.
| | 02:41 | In this case we are running a regular
expression, that's going to search for
| | 02:45 | guided tours or tour finder and replace
that text with a link to the tours view.
| | 02:51 | After we do that replacement, we are
calling the setBody function of JResponse,
| | 02:55 | so that the string that we pass into
setBody is used as a response, rather than
| | 03:00 | what we got originally and
then finally we return true.
| | 03:05 | Now before we run this plug-in, you'll
notice that we need to have a link that
| | 03:08 | points to view=tours.
| | 03:09 | So if you don't already have a link
that's pointing to the tour's view of the
| | 03:14 | explore component, go ahead and create that now.
| | 03:17 | Let's do that in the backend.
| | 03:19 | Go to menus>Main menu and Add New menu Item.
| | 03:25 | Select Tours as the link type
and add Tours as the menu Title.
| | 03:31 | Finally, click Save & Close.
| | 03:33 | Let's go to the front end and hit Refresh.
| | 03:35 | You will notice that Tours is now on the
Main menu list and when we click Tours,
| | 03:40 | we are able to see all the California Tours.
| | 03:44 | Now that we have our Tours link in place,
let's add a module with some content
| | 03:48 | that the plug-in will be able
to do a search and replace on.
| | 03:52 | Let's go to Extensions>Module
Manager and click on the New button.
| | 03:57 | Choose Custom HTML and give
this a title of Come Explore.
| | 04:06 | Select position number 7 and if there
is a better position for your site just
| | 04:12 | choose that instead and then under
Custom output we are going to copy and paste
| | 04:18 | the text from content.txt
from the Exercise Files.
| | 04:23 | Just paste that right here into the Text box.
| | 04:26 | Make sure the module is assigned to appear
on all pages and then click Save & Close.
| | 04:31 | Let's go to the front end, hit Refresh
and you'll notice the Come Explore module
| | 04:35 | here on the left with the content on the right.
| | 04:39 | Let's go to the backend
and publish the plug-in now.
| | 04:42 | Go to Extensions>Plugin Manager and
choose System as the plug-in type.
| | 04:47 | You will notice that the Tour Links
System plug-in up at the top and now click
| | 04:52 | the red circle to publish and
now it turns into a green check.
| | 04:56 | Let's go back to the front end and hit Refresh.
| | 04:59 | You'll notice that both of these links
are pointing to the Tours view and that
| | 05:03 | this link is in a module while
this link is in a content item.
| | 05:08 | Now while you can use the onAfterRender
event to do searches and replaces like
| | 05:13 | this for links, a better example
might be a content delivery network.
| | 05:18 | For instance you might have images that
are spread across your modules and your
| | 05:22 | content as well your template and you
want to place all of those images on the
| | 05:27 | content delivery network, where it will
be faster, than trying to pull it from
| | 05:31 | the server that's running Joomla
| | 05:33 | You can create an onAfterRender
System plug-in that will do searches and
| | 05:37 | replaces to replace the base URL of
your site with the base URL of the
| | 05:41 | content delivery network.
| | 05:43 | So with a system plug-in you
can gain control of Joomla
| | 05:46 | at every major point of execution.
| | 05:48 | The onAfterRender event provides the
opportunity for one last chance of the
| | 05:52 | output, before it's sent to the browser.
| | Collapse this transcript |
| Summarizing with content plug-ins| 00:00 | Content plugins are designed to run
inside of Joomla's content component, but
| | 00:04 | they can also be run on module content.
| | 00:07 | However, sometimes you want to make
sure a certain content plugin event is only
| | 00:10 | running on articles. Joomla
| | 00:12 | plugins are aware of their context,
allowing you to decide how you want to run them.
| | 00:17 | Let's add a content summary to the
activities plugin that only displays on articles.
| | 00:21 | Let's go to the Exercise
files and open up activities.php.
| | 00:27 | This is the existing content
activities plugin, but we now have a new event.
| | 00:31 | We have onContentAfterDisplay.
| | 00:33 | Copy this entire function and
paste it into the existing plugin file.
| | 00:39 | Go to plugins>content>
activities and activities.php.
| | 00:47 | Make a little room at the
bottom and paste in the function.
| | 00:50 | So what this event is going to do is
it's going to summarize the article and
| | 00:54 | display how many times the word
California is mentioned in the article.
| | 00:58 | First it's checking to make sure
we're within the article context.
| | 01:02 | We only want this part of the plugin to run on
articles and we don't want it to run on modules.
| | 01:08 | So if the context is not in the article
context, we want to return out of this
| | 01:12 | event and not run any more of the code.
| | 01:15 | Next, we run a regular expression to
count up the number of times California is
| | 01:20 | mentioned in the intro text of the article.
| | 01:22 | We count the number of matches
that we have for the word California.
| | 01:26 | If the count of California matches is
nonzero, we add that to the content that
| | 01:31 | gets returned, otherwise we
just return a null string.
| | 01:35 | Finally, we return
whatever was stored in mentions.
| | 01:39 | Be sure to save the plugin file and now
let's go back to the front end and hit Refresh.
| | 01:43 | So you'll notice now that the number of
California mentions is 2 and it's only
| | 01:49 | displaying on the article,
it's not displaying on the module.
| | 01:53 | Before running an event in a content
plugin, check the context to make sure that
| | 01:57 | it's appropriate for what
you are attempting to do.
| | 02:00 | Events such as onContentAfterDisplay are
typically most useful on standard articles.
| | 02:05 | You may want to avoid returning
output, when you're running in the
| | 02:08 | module context.
| | Collapse this transcript |
| Alerting with custom plug-ins (onFavorite)| 00:00 | The true power of Joomla's plugin
system is that you can define custom plugin
| | 00:04 | types and fire custom plugin events.
| | 00:07 | This makes it possible for other
developers to hook into your component
| | 00:10 | at strategic points.
| | 00:12 | Let's add a custom plugin event to
our component, then add a plug-in that
| | 00:16 | responds to that event.
| | 00:17 | First, let's go to the Exercise Files.
| | 00:19 | Go to the models folder
and open up favorites.php.
| | 00:22 | We're going to copy these three
lines from the addFavorite function.
| | 00:29 | Go to the front end of your component in com
_explore and models and open up favorites.
| | 00:36 | And then in the addFavorite function,
make a little room and add those three lines.
| | 00:41 | The first line is calling the
importPlugin function of JPluginHelper and we're
| | 00:46 | passing explore in as the argument.
| | 00:49 | This is telling Joomla
| | 00:50 | to load up all of the plugins that are in
the explore folder of the plugins folder.
| | 00:55 | Next, we're calling the
getInstance function of JDispatcher.
| | 00:59 | This is going to return an object that we
can use to trigger all of the plug-in events.
| | 01:04 | Finally, we're triggering the
onExploreAttractionFavorite event and we're
| | 01:09 | passing in the two arguments.
| | 01:11 | Notice that the arguments are
being passed in as an array.
| | 01:15 | These individual elements in the
array will be passed in as individual
| | 01:18 | arguments to the function.
| | 01:20 | Now that we're triggering the
onExploreAttractionFavorite event, let's add a
| | 01:24 | plugin that responds to this event.
| | 01:27 | We have an alert.zip file which is a
plugin that responds to this event.
| | 01:32 | Let's log in to the back end of Joomla
| | 01:33 | and install this plug-in.
| | 01:39 | Login as admin and lynda and then
go to Extensions>Extension Manager.
| | 01:46 | Locate the alert.zip file and
then click Upload & Install.
| | 01:51 | Once we've installed the plugin go
to the Plug-in Manager and enable it.
| | 01:56 | Under select type, you'll
now see explore as an option.
| | 02:00 | Click the red circle and that will
publish the explore alert plug-in.
| | 02:03 | Now let's take a look at the
code that just got installed.
| | 02:11 | Go to the plugins folder of your Joomla
| | 02:13 | installation and you'll now
notice the explore folder is there.
| | 02:18 | There is also an alert folder for the
plugin and first let's take a look at alert.xml.
| | 02:23 | So notice that the difference between
this xml manifest and the one for other
| | 02:27 | plugins is that the group
attribute is set to explore.
| | 02:31 | The type is still set to plugin and we
still have an alert.php file here that is
| | 02:37 | tagged as being the plugin file.
| | 02:40 | All you need to do to create your own custom
plugin group is to name it in this argument.
| | 02:49 | Let's also take a look at alert.php.
| | 02:52 | The name of this plugin follows the
naming convention as all the other plugins do.
| | 02:57 | It starts with plg, then it has the
name of the plugin group which in this case
| | 03:01 | is Explore and it's ended with the
name of the plugin itself, which is Alert.
| | 03:07 | Next, we have a function for the
onExploreAttractionFavorite event.
| | 03:11 | Notice that we have two arguments.
| | 03:13 | These are the same two arguments
that we passed in when we dispatched the
| | 03:17 | event in the component.
| | 03:19 | Now in this example, we're mailing
someone when a user of the site sets a favorite.
| | 03:24 | You might not be able to receive
this email, if you are running this in a
| | 03:27 | localhost environment, but you should
be able to receive it if you are running
| | 03:31 | your site on a hosted server.
| | 03:33 | So in this case, we're getting the
instance of the JMail class and it's
| | 03:38 | returning a mailer object.
| | 03:40 | And on this mailer object, we're able
to set the sender, the recipient, the
| | 03:43 | subject and finally the body.
| | 03:47 | And once we have all those pieces together,
we can send the Email and return true.
| | 03:52 | Also notice that we're importing the Joomla
| | 03:54 | mail class here using the import statement.
| | 03:57 | Additionally, we're using a couple of
helper functions that are defined right
| | 04:00 | here in the plug-in class.
| | 04:02 | You can define private helper
functions when you don't want to have
| | 04:05 | them necessarily respond to events,
but you do want to have them around
| | 04:09 | to do sub-processes.
| | 04:11 | So first, we have the getAttraction name
function which will get the name of the
| | 04:15 | attraction by the id.
| | 04:17 | It's just running a database query that
is selecting the attraction name by the
| | 04:21 | attraction id and we have a
similar function for getUsername.
| | 04:25 | Given the user_id, it goes back to the
users table and selects the username column.
| | 04:31 | In both cases we're just loading a
result, we're not loading an object or
| | 04:35 | an array of results.
| | 04:36 | We're just returning the text
result that comes back from the database.
| | 04:43 | Let's take a look at this in action.
| | 04:44 | Let's go back to the front end;
| | 04:46 | I'm going to log in as a user of this site.
| | 04:48 | Log in as admin and lynda and
then let's go to the Tours section.
| | 05:00 | Let's go to The Death Valley Survivor's
Trek and let's add that as a favorite.
| | 05:05 | Now if I were in a hosted environment,
I would be receiving an Email right now
| | 05:09 | saying that someone marked this as a favorite.
| | 05:12 | However, depending on your hosting setup,
you may or may not receive this Email.
| | 05:16 | Now notice also though that we don't
necessarily have to send an Email and we
| | 05:21 | don't necessarily have to have only one
plugin that responds to the on favorite event.
| | 05:26 | We can have multiple plugins that
respond to this event and possibly post to
| | 05:31 | Twitter or order a pizza or do
whatever we want whenever that event happens.
| | 05:37 | So the real power of this is that
you can define this event and have
| | 05:41 | third-party developers develop as many plugins
as you could imagine to respond to that event.
| | 05:49 | So the possibilities for custom
plugins and events are limitless.
| | 05:53 | Creating your own plugin types is as
easy as naming them and you can fire the
| | 05:56 | plugin events you want to use.
| | 05:59 | Custom plugin types allow the
authors of over 8,000 Joomla
| | 06:02 | extensions to hook code into your
component without directly modifying
| | 06:06 | your code.
| | Collapse this transcript |
|
|
16. Translating Your User InterfaceCreating extension language files| 00:00 | The first step to internationalizing your
extension is to add a language file for it.
| | 00:05 | The Explore California component
already has a full English language file, but
| | 00:09 | it doesn't yet have one for French.
| | 00:11 | Let's get started on a French
language file for the component.
| | 00:15 | Before you start translating into
French, you'll need to download the French
| | 00:18 | language pack from joomlacode.org.
| | 00:21 | Once you've downloaded the language
pack, you need to install it on the site.
| | 00:25 | Let's go to the backend.
| | 00:28 | Log in as admin and lynda.
| | 00:32 | Go to Extensions>Extension Manager
and then browse for the language pack.
| | 00:40 | After you've installed the
language, now you need to enable it.
| | 00:44 | Go to the Language Manager and
set French as the default language.
| | 00:48 | Now if we go to the front end and hit
Refresh, you'll notice that certain pieces
| | 00:53 | of the user interface have
now been translated into French.
| | 00:57 | However, none of the content gets translated.
| | 01:00 | The language packs are only going to
translate the user interface elements.
| | 01:04 | Let's take a look at what
happened on the file system.
| | 01:07 | Go to the root of your Joomla
| | 01:08 | Installation and then go to the language folder.
| | 01:11 | You'll notice that there
is now an fr-FR folder here.
| | 01:15 | Also, you'll now notice that there are fr-
FR files for every component in the system.
| | 01:21 | Similarly, the backend also has language files.
| | 01:24 | Go administrator and go to the language
folder there and you'll notice, again,
| | 01:29 | we have an fr-FR folder.
| | 01:32 | This folder contains language files for
all of the components in the backend as well.
| | 01:36 | Now while we have language files for all
of the components that come with Joomla.
| | 01:40 | we don't have a language file for the
Explore California component that we created.
| | 01:45 | So let's create a language
file for Explore California now.
| | 01:48 | Let's go back to the front end and
go to the language folder and fr-FR.
| | 01:54 | Now go to the Exercise Files
and copy in fr-FR.com_explore.ini.
| | 02:01 | So now we have an fr-FR.com_explore.ini
file and if we open it, you'll notice
| | 02:09 | that there is a language
string for com_explore tour details.
| | 02:13 | Let's go to the single tour view where
we'll see this language string in action.
| | 02:18 | Go to Tours and click on Big Sur Retreat.
| | 02:24 | The string in the language file for our
component for French has translated this header.
| | 02:29 | However, these other user interface
elements have not been translated yet.
| | 02:33 | And these will stay untranslated
until we add language strings for them.
| | 02:37 | So keep in mind, if you start a language
string file for a language, you need to
| | 02:41 | complete all of the language
strings for your extension.
| | 02:45 | After you've installed and enabled the
pack for the language translation you're
| | 02:48 | targeting, adding a language file will
give you control over the translations.
| | 02:53 | However, once you add that file, you're
responsible for providing translations
| | 02:57 | for all the language strings.
| | Collapse this transcript |
| Debugging languages| 00:00 | When you're developing language files
for Joomla, it's easy to get confused
| | 00:04 | over what is and what isn't
going to the translation engine.
| | 00:07 | This can be especially
confusing if you started without JText.
| | 00:11 | Fortunately, Joomla
| | 00:12 | includes a debug languages feature that
makes it easy for you to determine where
| | 00:16 | the translation engine is being used.
| | 00:19 | First, let's go to a single tour view.
| | 00:21 | Go to activities and then click on Backpack Cal.
| | 00:25 | You'll notice that at the
moment we have the bare language
| | 00:28 | string, COM_EXPLORE_TOURS.
| | 00:30 | Now at the moment we're using the JText engine.
| | 00:33 | Let's make a slight adjustment to this layout,
so that we're not using JText. Go to your Joomla
| | 00:38 | installation and go to components>
com_explore>views>activity and then open up
| | 00:45 | the tmpl>default.php.
| | 00:49 | Right where it says COM_EXPLORE_
TOURS, just change this to Tours.
| | 00:54 | So now you see this header just says Tours.
| | 01:00 | If we were translating this extension
into French, we might be confused as to
| | 01:04 | whether this is coming from the
English language file, whether this is coming
| | 01:08 | from the French language file that we
are working on or whether this is just
| | 01:12 | hardcoded into the layout.
| | 01:13 | Fortunately, we can use the debug language
mode to determine what actually happened.
| | 01:19 | Let's go back to the back end and turn it on.
| | 01:23 | Login as admin and lynda.
| | 01:26 | Go to Site>Global Configuration
and then click on the System tab.
| | 01:31 | From here set Debug Language
to Yes, then click Save & Close.
| | 01:36 | Go back to the front end and hit Refresh.
| | 01:40 | Now you'll notice that down at the
bottom of the screen, we have certain
| | 01:44 | language strings that are being
identified by a double asterisk.
| | 01:48 | There's also a language string that
hasn't been translated and it's noted with a
| | 01:53 | double question mark.
| | 01:55 | However, the header here does not
have any markings on it whatsoever.
| | 01:59 | This lets us know that it is not
going to through the translation engine.
| | 02:04 | Now let's undo the change that we made.
| | 02:06 | When we save the file and go back to the
front end and hit Refresh, now it shows
| | 02:11 | our missing language string.
| | 02:13 | Now we know we can go to the French language
file and add a language string for this key.
| | 02:18 | Let's go back to the back end and
turn off the Debug Language mode.
| | 02:22 | Go to Global Configuration and then set
Debug Language to No, then click Save & Close.
| | 02:28 | If we go back to the front end and hit
Refresh, all of the markings go away.
| | 02:32 | Joomla's Language Debug mode makes it
clear when you are missing a language
| | 02:36 | string or when you're not using JText.
| | 02:39 | Just turn on the Debug Language
feature in Joomla's Global Configuration, to
| | 02:43 | start finding your missing language strings.
| | Collapse this transcript |
| Overriding language files| 00:00 | Sometimes we want to change just one or
two or the strings from a language file.
| | 00:04 | Instead of modifying the existing
language files in Joomla, you can create
| | 00:08 | language overrides that
change to specific strings.
| | 00:11 | Let's override one of the headers
in the Explore California component.
| | 00:15 | First, let's turn off the French
language if you still have it on and make sure
| | 00:19 | that English is selected.
| | 00:21 | Go to the Administrator action
and login as admin and lynda.
| | 00:24 | Then go to Extensions>Language
Manager and then set English as the default.
| | 00:32 | Now go back to the front end and hit Refresh.
| | 00:34 | So now, let's navigate
to a single activity view.
| | 00:37 | Go to activities and go to Backpack Cal.
| | 00:40 | Let's say for instance we
want to change this header.
| | 00:43 | Instead of changing the English language
file that will be distributed with this
| | 00:46 | component, let's add an override
that will just override this header.
| | 00:51 | Go to the Exercise Files and
open up en-GB.override.ini.
| | 00:58 | This is an alternate title for that header.
| | 01:02 | We can copy this title into the current
overrides file, if it exists in your Joomla
| | 01:06 | installation.
| | 01:10 | Navigate to language overrides
and then open up en-GB.override.ini.
| | 01:18 | If you do not have this folder or this
file, just create this folder and copy
| | 01:22 | the file from the
Exercise Files into this folder.
| | 01:29 | Now copy that language string from
the Exercise File into the override.
| | 01:34 | After saving the file and going
back to the front end hit Refresh.
| | 01:38 | Now you notice that the
header says Related Tours.
| | 01:41 | Also, other strings from our
component are still translated.
| | 01:46 | This is because the overrides file allows
you to override specific language strings.
| | 01:50 | You don't have to override all of the
language strings from a language file.
| | 01:54 | When you want to change a language
string, don't hack the core Joomla
| | 01:57 | language file, add a language override.
| | 02:00 | This will protect you from future
patches that might otherwise overwrite
| | 02:03 | your work.
| | Collapse this transcript |
|
|
ConclusionPackaging your extensions| 00:00 | Now that the Explore California
component is complete, we could just leave it in
| | 00:04 | place and launch it as a web site.
| | 00:06 | However, we wouldn't get the benefit of
creating reusable packages of our code
| | 00:10 | to use with other sites.
| | 00:11 | Let's turn our
extensions into reusable packages.
| | 00:14 | Go to the Exercise Files and you'll
notice a folder called com_explore.
| | 00:20 | Inside this folder is the
structure for your component package.
| | 00:25 | Let's create a component package.
| | 00:27 | Start by creating a new folder
preferably on the Desktop or somewhere that's
| | 00:30 | easier to find and name it package build.
| | 00:35 | Open up the folder and just copy
that com_explore folder on inside.
| | 00:45 | Next, start copying the code from
your current site into this structure.
| | 00:50 | So first we're going to go to
administrator, and components, and then we're
| | 00:56 | going to copy the entire com_explore
folder into administrator>components.
| | 01:01 | Next, we have administrator, language,
so go to administrator>language, then go
| | 01:11 | to en-GB, and then find the two
files for the explore component.
| | 01:18 | Find the explore.ini and explore.sys.ini.
| | 01:22 | Copy these two files into the
en-GB folder of the structure.
| | 01:28 | Now for components, we're
going to pull the front-end files.
| | 01:31 | So go back to the root, go to
components>com_explore, and then just copy the
| | 01:38 | entire folder into components.
| | 01:44 | Next, we're going to get the
language strings for the front-end.
| | 01:46 | So go to language>en-GB and then get the
language string file for the explore component.
| | 01:55 | Copy this file and paste it right on in.
| | 01:58 | And then for the media folder, we're
going to do something slightly different.
| | 02:02 | Go to the media folder on the site and
go to com_explore and then copy css and
| | 02:08 | js and copy them directly into this folder.
| | 02:12 | Do not create a com_explore folder underneath.
| | 02:16 | So now that we have all the files from
the current site, we still need to update
| | 02:20 | the manifest file to include some of
the files and folders that we've added
| | 02:24 | throughout the course.
| | 02:25 | So go back to the Exercise
Files and open up manifest.xml.
| | 02:33 | Also go to the package
that you're building and go to
| | 02:35 | administrator>components>com_explore and
open up the manifest.xml file there as well.
| | 02:45 | So the first thing you'll notice is
that we need to add the media element.
| | 02:49 | So bring that element is from the Exercise
Files into the package that we're building.
| | 02:56 | You'll notice that the destination
is com_explore, so that com_explore
| | 03:00 | folder will be created inside the
media folder on the site where this
| | 03:04 | package gets installed.
| | 03:06 | And notice that we just have two folders.
| | 03:08 | We're referring to the folders as
a whole rather than listing out the
| | 03:12 | individual file names.
| | 03:14 | Next, update the front-end file listing.
| | 03:17 | Notice that we have a mix
of file names and folders.
| | 03:20 | We just need to list everything that's
in this component's com_explore folder.
| | 03:26 | Finally, we need to update the
back-end files, so copy in everything
| | 03:30 | underneath this files element.
| | 03:33 | Again, we have a mix of file
names and folders. That's fine.
| | 03:37 | Now save the file and we're going to
copy this manifest.xml file all the way
| | 03:43 | back to the root of our com_explore folder.
| | 03:47 | That way the manifest.xml file is going
to sit right beside the administrator,
| | 03:51 | components, language, and media folders.
| | 03:54 | Now let's zip up com_explore and we're
going to install it on a fresh copy of Joomla
| | 04:01 | I've already installed a fresh copy of Joomla
| | 04:02 | on my local host, so I'm going to use it.
| | 04:07 | Log in to the back-end
of the fresh installation.
| | 04:09 | I'm logging in as admin and lynda and
then go to Extensions>Extension Manager.
| | 04:16 | Click on the Browse button and then
navigate to the package that you just built.
| | 04:23 | Click Upload & Install and it will say that
the component installation was successful.
| | 04:28 | In addition to the component
installation, let's update the module
| | 04:32 | installation as well.
| | 04:34 | Go back to your original
site and then go to modules.
| | 04:38 | Go to mod_explore and open up mod_explore.xml.
| | 04:43 | There is one slight change
that we need to make here.
| | 04:46 | We added a tmpl folder, so just type in
folder tmpl, and then close the element.
| | 04:54 | After you save the file, zip up
the entire mod_explore folder.
| | 04:59 | I'm going to move it to
the Desktop so I can find it.
| | 05:03 | And then just browse for
that mod_explore.zip file.
| | 05:09 | Finally, let's install the plug-ins.
| | 05:12 | Go to the plugins directory and then go
to content and then zip up activities,
| | 05:18 | put that on the Desktop.
| | 05:20 | Go to explore, zip up the alert folder,
and put that on the Desktop as well.
| | 05:26 | And then go to system and zip up tourlinks.
| | 05:32 | We didn't change the file structure for
any of these plugins, so we don't have
| | 05:36 | to update the manifest file.
| | 05:37 | And now if we click Browse, we can
install activities, we can install the alert
| | 05:42 | plug-in, and we can install tourlinks.
| | 05:48 | We can also create links to our component.
| | 05:50 | Go to menus, Main menu and Add New
menu Item, and Select, choose Tours, then
| | 05:57 | type in Tours as a menu
Title, and click Save & Close.
| | 06:02 | Let's go to the front-end of our fresh
installation and you'll now notice Tours on the menu.
| | 06:07 | Click Tours and the tours now display.
| | 06:10 | So now we've packaged all of our
extensions and they're now all available
| | 06:13 | for any other Joomla site to use.
| | 06:14 | Joomla's XML manifest file system
makes it possible for you to package your
| | 06:19 | extensions as reusable pieces of code.
| | 06:22 | Once you've created a ZIP archive of your
extension, it's installable on any Joomla site.
| | Collapse this transcript |
| Next steps| 00:00 | Thanks for watching this
course on Joomla programming.
| | 00:03 | I hope you enjoyed creating your first
extensions and are now ready for more.
| | 00:06 | So where can you go from here?
| | 00:07 | First, there is a Joomla
| | 00:09 | developers portal with
information about the Joomla
| | 00:11 | code base and related Joomla
| | 00:13 | projects, it's at developer.joomla.org
and there are links here to
| | 00:18 | different mailing lists.
| | 00:20 | One of the most useful mailing lists
for extension developers is the Joomla
| | 00:23 | General Development list, it's at
groups.google.com/group/joomla-dev-general.
| | 00:31 | And finally, if you're wanting to publish
one of your extensions, go to the Joomla
| | 00:35 | Extensions Directory at extensions.joomla.org.
| | 00:38 | Once you login, you'll be able to submit
your extension to the Joomla directory.
| | 00:43 | As a Joomla
| | 00:43 | Extension Developer, you're in good company.
| | 00:46 | Join the community and learn how
you can take your code even further.
| | Collapse this transcript |
|
|