The fork system

Regenerate and keep your customizations.

Using this feature, you will be able to re-install a fresh downloaded component structure, and all your customs will be kept.

Simply install the new component over. As simple as that.

How it works ?

fork-diagramIt is using the native PHP classes overrides, and take advantage of the JLoader class.
At the bottom of each original class is a snipplet of code wich eventually load the fork file when exists.

Some files are for the moment excluded of this features :

  • Entry file of the component (mycomponent.php)
  • Some XML files (config, manifest, layout)
  • Javascript files

During the upgrade of your component, the fork directory will not be overriden.
You can be sure it is a good place to keep your customs.



Fork-FileTreeHow to use it ?

When you download your component, Cook furnish you an empty fork file for every php class. Located in /_fork directory.

Pick up the concerned file to fork from this given list.
For this lesson, let's fork a view file from a view called 'product' (view.html.php).

All your customs will be written behind the 'fork' directories from concerned client side (site or admin)

Also, your fork files will be organised the same way than your component root, but will only contains the concerned files that have been modified.

Structure of the empty fork file

// no direct access 
defined('_JEXEC') or die('Restricted access'); 
 
class HellomyworldViewProduct extends HellomyworldCkViewProduct {
 
}

Fork it

Copy the original function and paste it in the fork file.
For this lesson, we will fork the displayProduit() function.
You can fork with at least 3 different methods:

a. Fork to replace

class HellomyworldViewProduct extends HellomyworldCkViewProduct { 
  protected function displayProduct($tpl = null) {
    echo("Forked"); 
    
    // Fork and replace the original function 
  } 
}

b. Fork to execute before

class HellomyworldViewProduct extends HellomyworldCkViewProduct {
  protected function displayProduct($tpl = null) { 
 
    // Read the ACL of the current user 
    $acl = HellomyworldHelper::getActions(); 
 
    if ($acl->get('core.admin')) { 
 
      // Call another Layout 
      $this->displayAdminLayout(); 
 
      // Do not execute the original layout return; 
    } 
 
    // Call the original function 
    return parent::displayProduct($tpl); 
  } 
}

c. Fork to execute after

class HellomyworldViewProduct extends HellomyworldCkViewProduct { 
  protected function displayProduct($tpl = null) { 
 
    // Execute the native function
    $result = parent::displayProduct($tpl); 
    
    // Execute after
    $document = JFactory::getDocument(); 
    $document->title = "Forked title - " . $document->title; return $result; 
  } 
}

Forking the Non-PHP files

CSS

Both original + Fork are loaded.
CSS fork files are loaded AFTER original CSS.

Images

Basicly, it is not possible to fork a static image. Your component is not checking image fork presence.
The workaround is to call your forked images from the forked CSS (see CSS.)

Javascript files

Your alternative scripts must implicit be called from a forked file.
Same than images, it is not possible to fork them directly but if you manage well with your php files, there is no limitation.

JDom

JDom has its own system of overrides. You can override JDom files in many ways.
The main and important difference is that JDom is not able to overload individual functions. A fork is a file replacement.
When you custom inside a file, you do a copy of this entire file and put it in the fork directory as usual.
But remember you are substituting the whole JDom class.



Good practices

Override only the strict necessary

Keep in mind the less you fork, the easiest is to upgrade the component.
If you follow a good coding practice, it is a piece of cake to remember and backup your changes.

parent, self

The fork feature has a limitation with the parent and self keywords.
In facts, the parent of your forked class is the original one, not its real parent.
The self keyword call the original class, so in your fork it becomes parent.

Some trick functions like JView::_parentDisplay() permit to avoid this problem.

For example when you override a view file, instead of calling :

parent::display(); //Infinite loop

Replace by one of the following possibilities

$this->_parentDisplay(); 
self::_parentDisplay(); // Static call
return self::_parentDisplay(); //Static call with returning value 

XML files.

JForms XML can be forked, but only to ADD or OVERRIDE fields. You cannot remove an existing field.
Copy the original XML file structure and empty it first. Then you can ADD or OVERRIDE individual fields.

For the moment, the fork system does not apply on the others XML files. (manifest, config, layouts)
Before to reinstall a fresh component, copy all changed XML files in a safe place (can be in the fork tree).
After reinstallation, you can override manually those XML.

Known issue

The forked XML does not recognize sub items.
This is a Joomla issue, you need to do a little hack on your Joomla! if you want to make it working.

See the hack

Disclaimer

When you reinstall a fresh scaffolding you must know the last Cook changes and reprocess all the tests to know if your forks are still working. This fork system is not guaranteed at all because it depends how you implement your forks. It cannot replace a versioning system or a comparison tool.

Finalize your component. Merge the forks into the structure.

Once you've finished developing and are ready for production, you can merge (manually) your forks into their respective files, and suppress the fork directories. Resulting in a clean component ready to distribute.

Obviously, you can also keep those fork directories forever if you want.

Get Started