Monday, September 16, 2013

Custom Asset Package for Symfony2 app or how to generate bundle assets dir in Symfony2 Twig app

If you try to google how to get bundle assets dir in your Symfony2 Twig template you find almost nothing about this.

for example to output some image you need to write following in your twig template:

<img alt="" src="/bundles/sitebundle/images/image.jpg" />

But if you prefer Symfony way, you probably write something like:

<img alt="" src="{{asset('/bundles/sitebundle/images/image.jpg')}}" />

But what if you can generate bundle assets path by bundle name, which is so familiar to you like 'YourGreatBundle' for example.

I decided to write some code for this.

Symfony's asset() twig function actually accepts 2nd argument, which is $packageName. $packageName is just named asset Package instance. By default it is PathPackage. Url for assets generated with getUrl() method of Package instance. All we need is create 
custom asset Package class, let's call it BundlePathPackage:


<?php
namespace Vendor\SiteBundle\Asset\Package;

use 
Symfony\Component\Templating\Asset\PathPackage;
use 
Vendor\SiteBundle\Asset\Package\BundlePathPackageInterface;

/**
 * Allows prepending bundle assets directory to base path
 */

class BundlePathPackage extends PathPackage implements BundlePathPackageInterface {

    
/**
     * @var string
     */
    
private $bundleDir;

    
/**
     * {@inheritdoc}
     */
    
public function __construct($basePath = null, $version = null, $format = null) {
        
parent::__construct($basePath, $version, $format);
    }

    
/**
     * If relative url detected, also prepend bundle dir to path
     * {@inheritdoc}
     */
    
public function getUrl($path) {
        if (isset(
$this->bundleDir))
            
$path = $this->bundleDir . '/' . ltrim($path, '/');
        return 
parent::getUrl($path);
    }

    
/**
     * {@inheritdoc}
     */
    
public function setBundlePath($bundleName) {
        
$this->bundleDir = 'bundles/' . strtolower(str_replace('Bundle', '', $bundleName));
    }

}





You can find that it extends some interface. Here it is:


<?php
namespace Vendor\SiteBundle\Asset\Package;

interface 
BundlePathPackageInterface {

    
/**
     * registers bundle dir by bundlename
     * @param string $bundleName Identical to what
     * Symfony\Component\HttpKernel\Bundle\BundleInterface->getName() gives
     */
    
public function setBundlePath($bundleName);
}
 


Almost done. Last step would be to tell Kernel that something new happens in our app. Something is Kernel event listener:

<?php
namespace Vendor\SiteBundle\Event\Listener\HttpKernel;

use 
Symfony\Component\HttpKernel\Event\KernelEvent;
use 
Vendor\SiteBundle\Asset\Package\BundlePathPackage;

class 
AssetPackageInjector {

    
/**
     * Inject custom Asset package to Kernel assets helper
     * @param \Symfony\Component\HttpKernel\Event\KernelEvent $event
     */
    
public function onKernelRequest(KernelEvent $event) {
        
$container = $event->getDispatcher()->getContainer();

        
/** @var Symfony\Component\Templating\Helper\CoreAssetsHelper */
        
$assetsHelper = $container->get('templating.helper.assets');

        
$bundles = $container->get('kernel')->getBundles();
        foreach (
$bundles as $bundle) {
            
$bundlePathPackage = new BundlePathPackage();
            
$bundlePathPackage->setBundlePath($bundle->getName());
            
$assetsHelper->addPackage($bundle->getName(), $bundlePathPackage);
        }
    }

}
 


Finally we register listener in services.yml configuration file:

services:
  vendor.site.event.listener.assetpackage:
    class: Vendor\SiteBundle\Event\Listener\HttpKernel\AssetPackageInjector
    tags:
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

That's it. Now in Twig we can write following:

<img alt="" src="{{asset('images/image.jpg', 'SiteBundle')}}" />

Or with leading slash (in this case base url will be appended if not standard):

<img alt="" src="{{asset('/images/image.jpg', 'SiteBundle')}}" />

Sunday, September 15, 2013

Jenkins CI server installer for php projects

Recently, working on unit testing of Symfony2 project I thought that it'll be great to integrate Continuous Integration server. I'm using Netbeans IDE for my daily work, and found Netbeans page suggests using Jenkins CI  for php projects. So, after reading Jenkins template for php projects I decide to build installation script for it. So here it is on gihtub trig/jenkins-php-installer And is for those devs, which like to type several words in their terminal while script interactively asks some words about what it going to do, and pick some coffee. At the end of process Jenkins CI server is ready to start building tasks.

Installation script is on it's early stage, currently only in shell script. Who knows maybe it will be useful for someone searching for how to automate Jenkins CI server for php.

Tuesday, January 10, 2012

ubuntu 11.10 bash beep script

Like my title sad, i've been forced by myself to write a bash script for producing some good sound from bash scripts. Why i wrote a script? The answer is in my laziness to do deeply investigation in operation system core.
So we have:

  1.  Need to produce some notification sound (possibly error and success ones), when our script reach  final steps in it execution. 
  2. Do it as simple as possible.
My not deepest googling  provides me with this links:

Only last link definitely  shed light on my problem. And I decide to write small script that will be capable to play ubuntu native *.ogg files with it's own native  library wich in turn plays this particular sounds in real time, just i belive? like ubuntu does.

So following bash snippet will help to establish my, or someone needs:

#!/bin/bash
if [[ $1 == "" ]];then
echo -e "\tbeep [|]\ncreated by "
fi
if [[ $1 == "error" ]];then
sound="/usr/share/sounds/freedesktop/stereo/suspend-error.oga"
fi
if [[ $1 == "done" ]];then
sound="/usr/share/sounds/freedesktop/stereo/complete.oga"
fi
canberra-gtk-play --file="$sound" &>/dev/null

How to install it and run:
  1. cp or simlink it with sudo to any in your $PATH environment
  2. to run it: type in terminal "beep error" or "beep done"
  3. If you hear nice sounds all is good if not, post me back and i'll try to fix it up.
Script is available for download in my ubuntu.one account.