Reusable components for your ProcessWire-templates!
Welcome to Twack! Twack helps you build well-structured and maintainable ProcessWire-projects. Inspired by angular.
ProcessWire-Module: | https://modules.processwire.com/modules/twack/ |
Support-Forum: | https://processwire.com/talk/topic/23549-twack/ |
Repository: | https://github.com/Sebiworld/Twack |
Wiki: | https://github.com/Sebiworld/Twack/wiki/ |
- Create components ! Twack components are designed for reusability and encapsulating a set of features for easy maintainability. They can handle hierarchical or recursive use (child components).
- Based on ProcessWire's core functionality and principles
- HTML- and Ajax-Views - specify json output for ajax-requests
- Define services, that handle global data. Twack manages the shared service-classes (->singleton) for you and lets you access the data from everywhere you need it.
- Not exclusive - use Twack components to extend existing templates. You don't have to rewrite everything!
- 1: Home
- 2: Naming conventions & component variants
- 3: Component Parameters
- 4: Asset handling
- 5: Services
- 6: Named components
- 7: Global components
- 8: Ajax-Output
- 9: Configuration
Twack can be installed like every other module in ProcessWire. Check the following guide for detailed information: How-To Install or Uninstall Modules
The prerequisites are PHP>=5.5.0 and a ProcessWire version >=3.0.0. However, this is also checked during the installation of the module. No further dependencies.
Twack uses components to subdivide the website into logical components. A typical component can stand for its own and has no dependencies, which make it reusable and easy to maintain. Most components consist of a controller and a view.
If you have not done create the site/templates/components
directory. Here we will place all of our future components. Add a new file hello_world.view.php
inside of the directory. Create site/templates/services
where all our service classes will find a home.
Open the file and fill in the following contents:
<?php
namespace ProcessWire;
?>
<h2>Hello World!</h2>
It's done! We have our first functioning component. Admittedly, the component consists of only one view, but even for simple components there are many useful purposes. We will add data-handling and functions in a moment. But first, let's learn how to use our component in one of our ProcessWire-templates.
If we had a controller-class for our view, the class would be called HelloWorld
. More on that in the next chapter. To use our component in a ProcessWire-template, we have to ask the Twack-module for it and it will find and initialize it for us.
<?php
namespace ProcessWire;
// Get a new instance of our HelloWorld-component:
$myComponent = wire('twack')->getNewComponent('HelloWorld');
?>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<?php
// Render the component`s view:
echo $myComponent->render();
?>
</body>
</html>
As you see, including a Twack-component in traditional ProcessWire-templates is quite simple. You can build the complete HTML in Twack-views and use its full potential, but you don't have to. It is possible to gradually replace individual parts of the page.
Let's go back to our component. You created your HelloWorld-component with nothing but a view that outputs a bold "Hello World!". Most components need more than just an output. We need a controller to make the view more dynamic.
Create a new directory site/templates/components/hello_world/
and move our view-file to this destination. Additionally create a controller file with the name hello_world.class.php
in this new directory.
A Twack-controller needs a bit of boilerplate-code to correctly function. Copy the following code to your controller-file (hello_world.class.php
):
<?php
namespace ProcessWire;
class HelloWorld extends TwackComponent {
public function __construct($args) {
parent::__construct($args);
}
}
Every Twack-controller has to extend our general TwackComponent, which brings a lot of background-functionality to our controller. With parent::__construct($args);
we let the parent TwackComponent
finish its general initialization work before our custom component's code will be executed.
In our constructor we will define variables, add child-components and do all logical work for the view.
An a little more advanced controller can look like this:
<?php
namespace ProcessWire;
class HelloWorld extends TwackComponent {
public function __construct($args) {
parent::__construct($args);
$this->title = 'Hello World!';
if(isset($args['title'])) {
$this->title = $args['title'];
}
// Add and initialise a child-component
$testChildArgs = [
'myTestValue'
];
$this->addComponent('TestChild', $testChildArgs);
}
}
$this->title
will be "Hello World!", as long as we get no value for $args['title']
from our constructor's $args
parameter. If we had initialized the component with $twack->getNewComponent('HelloWorld', ['title' => 'My new Title.']);
, we would set it to this new value.
Every attribute of the controller is also accessible in the view, you don't have to care about transferring values.
A child component can be added via $this->addComponent()
. In our example, we add the Component 'TestChild', which shall be located under site/templates/components/hello_world/test_child/test_child.class.php
. Twack automatically looks in the current component's directory for subdirectories. Specifying an other path is also possible. I created an array $testChildArgs
to demonstrate passing additional parameters to the TestChild
, which will be passed to its constructor.
Our new view could look like this:
<?php
namespace ProcessWire;
?>
<div class="hello_world_component">
<?php
if(!empty($this->showTitle)){
echo "<h2>{$this->showTitle}</h2>";
}
?>
<p>Lorem ipsum</p>
<div class="children_wrapper">
<?php
foreach ($this->childComponents as $childComponent) {
echo (string) $childComponent;
}
?>
</div>
</div>
As you see, we only show the title, if $this->title
has a value. Under $this->childComponents
we have a list of all components that were added via $this->addComponent()
in the controller.
We now have created a basic Twack-component and you now the general concepts how Twack works. But Twack has are a lot of more great features that will emend and simplify your development process.
- Add hash to page requests
- Return 204 (No Content) if matching hash is sent via GET param
- Use AppApi getAjaxOf() if available
- Improved Fallback getAjaxOf()
- Added componentLists to TwackComponent
- Bugfix catch error if manifest path does not exist
- Api: Throw 404 if page not found
- Api: Added support for Multi-Language URLS
- getAjaxOf: Use AppApi-function if installed
- Api: Improve optional
lang
param, add many langugage codes that can be used as a shortcut
- Api: Add optional
lang
param to select a language in multilang environments
- JSON-API: Use AppApi (if installed) to add a 'tpage' endpoint. See more at https://github.com/Sebiworld/Twack/wiki/8:-Ajax-Output
- Improved documentation
- Moved most contents of README to Wiki
- added page-links
- Made Twack available as API-variable like
wire('twack')
. (Thanks to @BernhardBaumrock)
We use SemVer for versioning. For the versions available, see the tags on this repository.
This project is licensed under the Mozilla Public License Version 2.0 - see the LICENSE.md file for details.