Joomla! Development Workshop

Requirements

  1. Composer
  2. Local Webserver
  3. Joomla! (here /var/www/html/joomla/)

Create a work directory


								~/$ mkdir workshop
								~/$ cd workshop/
								~/workshop$
							

Initialize a new project with Composer


								~/workshop$ composer init

								  Welcome to the Composer config generator

								This command will guide you through creating your composer.json config.

								Package name (<vendor>/<name>) [joomla/workshop]: 
								Description []: 
								Author [joomlax <info@joomla.de>, n to skip]: 
								Minimum Stability []: 
								Package Type (e.g. library, project, metapackage, composer-plugin) []: 
								License []: 

								Define your dependencies.

								Would you like to define your dependencies (require) interactively [yes]?
								Search for a package: joomla-projects/jorobo
								Enter the version constraint to require (or leave blank to use the latest version):
								Using version ^0.7.0 for joomla-projects/jorobo
								Search for a package: 
								Would you like to define your dev dependencies (require-dev) interactively [yes]?
								Search for a package: 

								{
									"name": "joomla/workshop",
									"require": {
										"joomla-projects/jorobo": "^0.7.0"
									},
									"authors": [
										{
											"name": "joomlax",
											"email": "info@joomla.de"
										}
									]
								}

								Do you confirm generation [yes]? 
								~/workshop$
							

Install the defined dependencies for the project


								~/workshop$ composer install
								Loading composer repositories with package information
								Updating dependencies (including require-dev)
								Package operations: 30 installs, 0 updates, 0 removals
								  - Installing joomla/uri (1.1.1): Loading from cache
								  - Installing ircmaxell/password-compat (v1.0.4): Loading from cache
								  - Installing symfony/polyfill-php55 (v1.6.0): Loading from cache
								  - Installing joomla/string (1.4.1): Loading from cache
								  - Installing joomla/utilities (1.4.1): Loading from cache
								  - Installing joomla/compat (1.2.0): Loading from cache
								  - Installing joomla/registry (1.5.2): Loading from cache
								  - Installing composer/ca-bundle (1.0.8): Loading from cache
								  - Installing joomla/http (1.3.0): Loading from cache
								  - Installing joomla/github (1.5.3): Loading from cache
								  - Installing symfony/process (v3.3.10): Loading from cache
								  - Installing symfony/finder (v3.3.10): Loading from cache
								  - Installing symfony/filesystem (v3.3.10): Loading from cache
								  - Installing symfony/event-dispatcher (v3.3.10): Loading from cache
								  - Installing psr/log (1.0.2): Loading from cache
								  - Installing symfony/debug (v3.3.10): Loading from cache
								  - Installing symfony/polyfill-mbstring (v1.6.0): Loading from cache
								  - Installing symfony/console (v3.3.10): Loading from cache
								  - Installing psr/container (1.0.0): Loading from cache
								  - Installing container-interop/container-interop (1.2.0): Loading from cache
								  - Installing league/container (2.4.1): Loading from cache
								  - Installing consolidation/output-formatters (3.1.12): Loading from cache
								  - Installing consolidation/log (1.0.3): Loading from cache
								  - Installing symfony/yaml (v3.3.10): Loading from cache
								  - Installing dflydev/dot-access-data (v1.1.0): Loading from cache
								  - Installing grasmash/yaml-expander (1.2.0): Loading from cache
								  - Installing consolidation/config (1.0.6): Loading from cache
								  - Installing consolidation/annotated-command (2.8.1): Loading from cache
								  - Installing consolidation/robo (1.1.4): Loading from cache
								  - Installing joomla-projects/jorobo (0.7.0): Loading from cache
								symfony/event-dispatcher suggests installing symfony/dependency-injection ()
								symfony/event-dispatcher suggests installing symfony/http-kernel ()
								consolidation/robo suggests installing pear/archive_tar (Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.)
								consolidation/robo suggests installing henrikbjorn/lurker (For monitoring filesystem changes in taskWatch)
								consolidation/robo suggests installing patchwork/jsqueeze (For minifying JS files in taskMinify)
								consolidation/robo suggests installing natxet/CssMin (For minifying CSS files in taskMinify)
								Writing lock file
								Generating autoload files
								~/workshop$ ls
								composer.json  composer.lock  vendor
								~/workshop$
						

Component - First steps

Necessary directory structure for JoRobo


								~/workshop$ mkdir source
								~/workshop$ cd source
								~/workshop/source$ mkdir administrator
								~/workshop/source$ mkdir administrator/components
								~/workshop/source$ mkdir administrator/language
								~/workshop/source$ mkdir administrator/language/en-GB
								~/workshop/source$ mkdir administrator/components/com_workshop
								~/workshop/source$ mkdir administrator/components/com_workshop/sql
								~/workshop/source$ mkdir administrator/components/com_workshop/sql/install
								~/workshop/source$ mkdir administrator/components/com_workshop/sql/install/mysql
								~/workshop/source$ mkdir administrator/components/com_workshop/sql/updates
								~/workshop/source$ mkdir administrator/components/com_workshop/sql/updates/mysql
								~/workshop/source$ mkdir components
								~/workshop/source$ mkdir components/com_workshop
								~/workshop/source$ mkdir language
								~/workshop/source$ mkdir language/en-GB
								~/workshop/source$ mkdir media
								~/workshop/source$ mkdir media/com_workshop
								~/workshop/source$
							

source/administrator/components/com_workshop/workshop.xml


							<?xml version="1.0" encoding="utf-8" ?>
							<extension type="component" version="3.5" method="upgrade">
								<name>COM_WORKSHOP</name>
								<creationDate>##DATE##</creationDate>
								<author>[AUTHOR]</author>
								<authorEmail>[AUTHOR_EMAIL]</authorEmail>
								<authorUrl>[AUTHOR_URL]</authorUrl>
								<copyright>(C) ##YEAR## - [COPYRIGHT]</copyright>
								<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
								<version>##VERSION##</version>
								<description>COM_WORKSHOP_XML_DESCRIPTION</description>
								<scriptfile>script.php</scriptfile>

								<!-- Runs on install -->
								<install>
									<sql>
										<file driver="mysql" charset="utf8">sql/install/mysql/install.mysql.sql</file>
									</sql>
								</install>

								<!-- Runs on uninstall -->
								<uninstall>
									<sql>
										<file driver="mysql" charset="utf8">sql/install/mysql/uninstall.mysql.sql</file>
									</sql>
								</uninstall>

								<!-- Runs on update -->
								<update>
									<schemas>
										<schemapath type="mysql">sql/updates/mysql</schemapath>
									</schemas>
								</update>

								<!-- Front-end files -->
								<files folder="components/com_workshop">
									##FRONTEND_COMPONENT_FILES##
								</files>
								<languages folder="language">
									##FRONTEND_LANGUAGE_FILES##
								</languages>

								<!-- Back-end files -->
								<administration>
									<!-- Menu entries -->
									<menu view="workshop">COM_WORKSHOP</menu>
									<submenu>
										<!--
											Note that all & must be escaped to & for the file to be valid
											XML and be parsed by the installer
										-->
										<menu link="option=com_workshop">COM_WORKSHOP</menu>
									</submenu>

									<!-- Core files -->
									<files folder="administrator/components/com_workshop">
										##BACKEND_COMPONENT_FILES##
									</files>
									<languages folder="administrator/language">
										##BACKEND_LANGUAGE_FILES##
									</languages>
								</administration>

								<!-- Update servers -->
								<updateservers>
									<server type="extension" priority="1" name="[PROJECT_NAME]">https://www.example.com/workshop.xml</server>
								</updateservers>
							</extension>
						

source/administrator/components/com_workshop/skript.php


							<?php

							defined('_JEXEC') or die;

							/**
							 * Workshop script file.
							 *
							 * @package     A package name
							 * @since       1.0
							 */
							class Com_WorkshopInstallerScript
							{
								/**
								 * Constructor
								 *
								 * @param   JAdapterInstance  $adapter  The object responsible for running this script
								 */
								public function __construct(JAdapterInstance $adapter) {}

								/**
								 * Called before any type of action
								 *
								 * @param   string  $route  Which action is happening (install|uninstall|discover_install|update)
								 * @param   JAdapterInstance  $adapter  The object responsible for running this script
								 *
								 * @return  boolean  True on success
								 */
								public function preflight($route, JAdapterInstance $adapter) {}

								/**
								 * Called after any type of action
								 *
								 * @param   string  $route  Which action is happening (install|uninstall|discover_install|update)
								 * @param   JAdapterInstance  $adapter  The object responsible for running this script
								 *
								 * @return  boolean  True on success
								 */
								public function postflight($route, JAdapterInstance $adapter) {}

								/**
								 * Called on installation
								 *
								 * @param   JAdapterInstance  $adapter  The object responsible for running this script
								 *
								 * @return  boolean  True on success
								 */
								public function install(JAdapterInstance $adapter) {}

								/**
								 * Called on update
								 *
								 * @param   JAdapterInstance  $adapter  The object responsible for running this script
								 *
								 * @return  boolean  True on success
								 */
								public function update(JAdapterInstance $adapter) {}

								/**
								 * Called on uninstallation
								 *
								 * @param   JAdapterInstance  $adapter  The object responsible for running this script
								 */
								public function uninstall(JAdapterInstance $adapter) {}
							}
						

source/administrator/components/com_workshop/sql/install/mysql/install.mysql.sql


							CREATE TABLE IF NOT EXISTS `#__workshop` (
							  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
							  `catid` int(11) NOT NULL DEFAULT 0,
							  `title` varchar(250) NOT NULL DEFAULT '',
							  `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '',
							  `description` text NOT NULL,
							  `hits` int(11) NOT NULL DEFAULT 0,
							  `state` tinyint(1) NOT NULL DEFAULT 0,
							  `checked_out` int(11) NOT NULL DEFAULT 0,
							  `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
							  `ordering` int(11) NOT NULL DEFAULT 0,
							  `access` int(11) NOT NULL DEFAULT 1,
							  `params` text NOT NULL,
							  `language` char(7) NOT NULL DEFAULT '',
							  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
							  `created_by` int(10) unsigned NOT NULL DEFAULT 0,
							  `created_by_alias` varchar(255) NOT NULL DEFAULT '',
							  `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
							  `modified_by` int(10) unsigned NOT NULL DEFAULT 0,
							  `metakey` text NOT NULL,
							  `metadesc` text NOT NULL,
							  `metadata` text NOT NULL,
							  `featured` tinyint(3) unsigned NOT NULL DEFAULT 0 COMMENT 'Set if link is featured.',
							  `xreference` varchar(50) NOT NULL COMMENT 'A reference to enable linkages to external data sets.',
							  `publish_up` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
							  `publish_down` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
							  `version` int(10) unsigned NOT NULL DEFAULT 1,
							  `images` text NOT NULL,
							  PRIMARY KEY (`id`),
							  KEY `idx_access` (`access`),
							  KEY `idx_checkout` (`checked_out`),
							  KEY `idx_state` (`state`),
							  KEY `idx_catid` (`catid`),
							  KEY `idx_createdby` (`created_by`),
							  KEY `idx_featured_catid` (`featured`,`catid`),
							  KEY `idx_language` (`language`),
							  KEY `idx_xreference` (`xreference`)
							) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;
						

source/administrator/components/com_workshop/sql/install/mysql/uninstall.mysql.sql


							DROP TABLE IF EXISTS `#__workshop`;
						

source/administrator/components/com_workshop/sql/updates/mysql/1.0.0.sql


							# Example for update ...
							ALTER TABLE `#__workshop` ENGINE=InnoDB;
						

source/administrator/components/com_workshop/workshop.php


							<?php

							defined('_JEXEC') or die;

							echo "This simple task works. Now we can go on with complicated tasks.";
						

source/administrator/language/en-GB/en-GB.com_workshop.ini


							;
							; [PROJECT_NAME] language file
							;

							COM_WORKSHOP="[PROJECT_NAME]"
							COM_WORKSHOP_CONFIGURATION="[PROJECT_NAME] Options"
						

source/administrator/language/en-GB/en-GB.com_workshop.sys.ini


							;
							; [PROJECT_NAME] language file
							;

							COM_WORKSHOP="[PROJECT_NAME]"
							COM_WORKSHOP_XML_DESCRIPTION="[PROJECT_NAME]"
						

source/components/com_workshop/workshop.php


							<?php

							defined('_JEXEC') or die;

							echo "Great! The front end also works.";
						

Configure Jorobo

Copy jorobo.ini and RoboFile.php


							~/workshop$ cp vendor/joomla-projects/jorobo/jorobo.ini .
							~/workshop$ cp vendor/joomla-projects/jorobo/jorobo.dist.ini ./
							~/workshop$ cp vendor/joomla-projects/jorobo/RoboFile.php .
							~/workshop$ ls
							composer.json  composer.lock jorobo.ini  jorobo.dist.ini  RoboFile.php source  vendor
							~/workshop$
						

Add jorobo.ini to .gitignore

Edit jorobo.ini


							extension = workshop
							version = 0.0.1
							source = source
							target = zip

							[github]
							remote = origin
							branch = develop
							token =
							owner = joomla-projects
							repository = weblinks
							changelog_source = commits

							[ftp]
							host =
							port = 21
							user =
							password =
							ssl = false
							target = /

							[header]
							files = php,js
							exclude =
							text = "
							/**
							 * @package    [PACKAGE_NAME]
							 *
							 * @author     [AUTHOR] <[AUTHOR_EMAIL]>
							 * @copyright  Copyright (C) ##YEAR## [COPYRIGHT]
							 * @license    GNU General Public License version 2 or later; see LICENSE.txt
							 * @link       [AUTHOR_URL]
							 */
							"
						

Test the component

vendor/bin/robo map (todo do not uninstall)


							~/workshop$ vendor/bin/robo map /var/www/html/weblinks/tests/joomla
							 [Filesystem\FilesystemStack] symlink ["/workshop/source/media/com_workshop","/var/www/html/joomla/media/com_workshop"]
							 [Filesystem\FilesystemStack] symlink ["/workshop/source/components/com_workshop","/var/www/html/joomla/components/com_workshop"]
							 [Filesystem\FilesystemStack] symlink ["/workshop/source/modules/mod_workshop","/var/www/html/joomla/modules/mod_workshop"]
							 [Filesystem\FilesystemStack] symlink ["/workshop/source/administrator/components/com_workshop","/var/www/html/joomla/administrator/components/com_workshop"]
							 [Filesystem\FilesystemStack] symlink ["/workshop/source/plugins/content/workshop","/var/www/html/joomla/plugins/content/workshop"]
							~/workshop$
					

Joomla! Discover
http://localhost/joomla/administrator/index.php?option=com_installer&view=discover

Backend
http://localhost/joomla/administrator/index.php?option=com_workshop

Frontend
http://localhost/joomla/index.php?option=com_workshop

Database
http://localhost/joomla/index.php?option=com_workshop

Four JoRobo Functions

  1. vendor/bin/robo map
  2. vendor/bin/robo headers
  3. vendor/bin/robo build
  4. vendor/bin/robo bump

You've already used vendor/bin/robo map

vendor/bin/robo headers


							~/workshop$ vendor/bin/robo header
							~/workshop$
						

This is magical! Now each file in your project has the header that you entered in jorobo.ini.

vendor/bin/robo build


							~/workshop$ vendor/bin/robo build
							 [Filesystem\CleanDir] Cleaned /workshop/dist/workshop-0.0.1
							 [Filesystem\FilesystemStack] mkdir ["/workshop/dist/workshop-0.0.1/administrator/components/com_workshop"]
							 [Filesystem\FilesystemStack] mkdir ["/workshop/dist/workshop-0.0.1/components/com_workshop"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/source/administrator/components/com_workshop/script.php","/workshop/dist/workshop-0.0.1/administrator/components/com_workshop/script.php"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/source/administrator/components/com_workshop/workshop.xml","/workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/source/administrator/components/com_workshop/workshop.php","/workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.php"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/source/components/com_workshop/workshop.php","/workshop/dist/workshop-0.0.1/components/com_workshop/workshop.php"]
							 [Filesystem\FilesystemStack] mkdir ["/workshop/dist/workshop-0.0.1/media/com_workshop"]
							 [Filesystem\FilesystemStack] mkdir ["/workshop/dist/workshop-0.0.1/administrator/language"]
							 [Filesystem\FilesystemStack] mkdir ["/workshop/dist/workshop-0.0.1/administrator/language/en-GB"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/source/administrator/language/en-GB/en-GB.com_workshop.ini","/workshop/dist/workshop-0.0.1/administrator/language/en-GB/en-GB.com_workshop.ini"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/source/administrator/language/en-GB/en-GB.com_workshop.sys.ini","/workshop/dist/workshop-0.0.1/administrator/language/en-GB/en-GB.com_workshop.sys.ini"]
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml updated. 3 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/script.php unchanged. 0 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml updated. 1 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml updated. 1 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml updated. 1 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml updated. 1 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml unchanged. 0 items replaced
							 [Filesystem\FilesystemStack] _copy ["/workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.xml","/workshop/dist/workshop-0.0.1/workshop.xml"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/dist/workshop-0.0.1/administrator/components/com_workshop/script.php","/workshop/dist/workshop-0.0.1/script.php"]
							 [Filesystem\FilesystemStack] _copy ["/workshop/dist/workshop-0.0.1/administrator/components/com_workshop/script.php","/workshop/dist/workshop-0.0.1/script.php"]
							 [File\Replace] /workshop/dist/workshop-0.0.1/script.php unchanged. 0 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/components/com_workshop/workshop.php unchanged. 0 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/script.php unchanged. 0 items replaced
							 [File\Replace] /workshop/dist/workshop-0.0.1/administrator/components/com_workshop/workshop.php unchanged. 0 items replaced
							 [Filesystem\FilesystemStack] symlink ["/workshop/dist/workshop-0.0.1","/workshop/dist/current"]
							~/workshop$
						

Look at your work directory! Here you will find a subfolder called dist and in this is among other things an installable zip file.

By the way: The command

vendor/bin/robo build --dev

enables you to start a new development release.

vendor/bin/robo bump


							~/workshop$ vendor/bin/robo bump
							~/workshop$
						

Now the string __DEPLOY_VERSION__ is exchanged in each file with the version number you entered in the file jorobo.ini.

Component - Improvements

File


							~/workshop$ mkdir source
						

Module

Necessary directory structure for JoRobo


							~/workshop$ cd source
							~/workshop/source$ mkdir modules
							~/workshop/source$ mkdir modules/mod_workshop
							~/workshop/source$
						

File


							~/workshop$ mkdir source
						

Plugin

Necessary directory structure for JoRobo


							~/workshop$ cd source
							~/workshop/source$ mkdir plugins
							~/workshop/source$ mkdir plugin/content
							~/workshop/source$ mkdir plugin/content/workshop
							~/workshop/source$
						

File


							~/workshop$ mkdir source
						

Packages

Necessary directory structure for JoRobo


							~/workshop$ cd source
							~/workshop/source$ mkdir administrator/manifest
							~/workshop/source$ mkdir administrator/manifest/packages
							~/workshop/source$
						

File


							~/workshop$ mkdir source