Creating A Block¶
Creating a Bldr Block for Bldr is fairly similar to creating a Bundle for Symfony2. Here’s a quick guide:
1. Create a repo¶
Try and stay with the naming convention used by the other blocks: <name>-block
2. Initialize composer in the repo¶
cd your-repo && composer init
3. Add Bldr as a dev dependency¶
In your composer.json file, you will want to add bldr-io/bldr as a require-dev dependency. Because embedded composer and composer are unstable packages by definition or they do not have a stable release you will have to add them too into your composer.json as below:
{
"require-dev": {
"bldr-io/bldr": "~4.2.0",
"dflydev/embedded-composer": "dev-master@dev",
"composer/composer": "dev-master@dev"
}
}
4. Create a Block class¶
All of bldr, and the official extensions follow PSR-4 (as well as all the other PSR’s, and most, if not all, of the bylaws). With that, create your directory structure and your Block class:
mkdir src && vim src/AcmeDemoBlock.php
All blocks must extend the BldrDependencyInjectionAbstractBlock, so your class, empty, will look something like this:
src/AcmeDemoBlock.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Bldr\DependencyInjection\AbstractBlock;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author John Doe <john@doh.com>
*/
class AcmeDemoBlock extends AbstractBlock
{
/**
* {@inheritDoc}
*/
protected function assemble(array $config, ContainerBuilder $container)
{
}
}
The assemble function is where the magic happens. If you take a look at the AbstractBlock, there are some helper functions in there to make it easier to add new calls, services, and parameters to the Container.
5. Create your Call¶
As a demo, let’s say we want to make a call that will output a random number to the user when running the call.
First, lets create the call. Directory structure doesn’t really matter, but the core structure is normally src/Call/<Name>Call.php. Similar to blocks, all calls must extend `Bldr\Call\AbstractCall`_.
Lets make the src/Call directory, and create the new Call: .. code-block:: shell
mkdir src/Call && vim src/Call/OutputRandomNumberCall.php
Then, let’s build the call class! Extending the AbstractCall, requires that we implement two methods: configure and run
src/Call/OutputRandomNumberCall.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo\Call;
use Bldr\Call\AbstractCall;
/**
* @author John Doe <john@doh.com>
*/
class OutputRandomNumberCall extends AbstractCall
{
/**
* {@inheritDoc}
*/
public function configure()
{
$this->setName('acme_demo:output_random_number')
->setDescription('This call outputs a random number. If min and max are specified, it will use those as the range')
->addOption('min', true, 'Minimum number in range', 0)
->addOption('max', true, 'Maximum number in range', 100)
;
}
/**
* {@inheritDoc}
*/
public function run()
{
$random = rand($this->getOption('min'), $this->getOption('max'));
$this->output->writeln(['', 'Random Number: '.$random, '']);
return true;
}
}
Next, we need to add the call to the container, so we can use it in .bldr.yml files:
src/AcmeDemoBlock.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Bldr\DependencyInjection\AbstractBlock;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author John Doe <john@doh.com>
*/
class AcmeDemoBlock extends AbstractBlock
{
/**
* {@inheritDoc}
*/
protected function assemble(array $config, ContainerBuilder $container)
{
// Here's one of the shortcut methods! This method will return a Symfony DI Definition
// that is tagged as `bldr`. If you need to, you can easily add arguments to the constructor,
// or calls to methods.
$call = $this->addCall('acme_demo.output_random_number', 'Acme\Block\Demo\AcmeDemoBlock');
// If you need dependencies, you could do the following:
// $call->setArgument(0, new Reference('some_service'));
// or
// $arguments = array(new Reference('some_service'));
// $call->addMethodCall('someMethodName', $arguments);
// If you want to add a service, that isn't a call, you can also use:
// $this->addService($name, $class);
// Which will also return a Symfony DI Definition
}
}
With this, you should be able to add it to a .bldr.yml file:
blocks:
- Acme\Block\Demo\AcmeDemoBlock
bldr:
name: some/name
profile:
default:
tasks:
- randomize
tasks:
randomize:
calls:
-
type: acme_demo:output_random_number
min: 0
max: 100000
And run it!
./bldr.phar build -p default
There’s some more advanced stuff, like being able to specify configuration:
src/AcmeDemoBlock.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Bldr\DependencyInjection\AbstractBlock;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author John Doe <john@doh.com>
*/
class AcmeDemoBlock extends AbstractBlock
{
// ...
/**
* {@inheritDoc}
*/
protected function getConfigurationClass()
{
return 'Acme\Block\Demo\Configuration';
}
}
6. Advanced Config¶
Then make a Configuration.php file. This config is the config from symfony. You can read their docs for more information.
src/Configuration.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
/**
* @author John Doe <john@doh.com>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_demo');
// here you will build the configuration tree
return $treeBuilder;
}
}