lundi 12 mars 2012

Installing Blitz templating engine for PHP 5.4

Earlier today I wanted to install the Blitz templating engine on my brand new PHP5.4.
The docs say to do:
phpize
./configure
make install
However, make complains about safe_mode.h not being found and the compiling fails.
That's logical because safe_mode was removed from php 5.4.

There's an easy workaround: comment out or remove the #include "safe_mode.h" line from the blitz.c file and then run make install

Running the tests with run_tests.sh will show you everything works fine.

BTW, the stable version (0.6.10 at the time of this writing) won't compile at all, you'll need to install the development version (0.7.1.14) with PHP 5.4.

samedi 31 décembre 2011

Installing webistrano on Debian Squeeze 64bits


This is how *I* did it. By no means is this the perfect way, nor very probably how it should be done, but it worked for me.

As root:

1 activate default repositories
# vi /etc/apt/sources.list
add, if not already there:
deb http://ftp.debian.org/debian squeeze main contrib
deb-src http://ftp.debian.org/debian squeeze main contrib

2 update apt
# apt-get update

3 install the necessary packages
# apt-get install build-essential
# apt-get install ruby rubygems libmysql-ruby libmysqlclient-dev libdbd-mysql-ruby mysql-server unzip rake

4 install the required ruby gems
# gem install rake -v=0.8.7
# gem install rack -v=1.0.1
# gem install bundler

5 add the user you want webistrano to run as
# adduser webistrano

As the user you want webistrano (and capistrano) to run as:

1 get webistrano
webistrano$ wget -O webistrano.zip https://github.com/peritor/webistrano/zipball/master

2 unzip the file
webistrano$ unzip webistrano.zip

3 Follow the installation instructions from the official wiki:
webistrano$ cd peritor-webistrano-xxxxxxx/
webistrano$ cp config/webistrano_config.rb.sample config/webistrano_config.rb
--> edit at your convenience
webistrano$ cp config/database.yml.sample config/database.ym
--> edit at your convenience (mysql.socket is at /var/run/mysqld/mysqld.sock)

4 create database webistrano_{development|production|test} on MySQL server

5 edit your .profile file and add ruby and rubygems paths:
webistrano$ vi ~/.profile
PATH="$PATH:/usr/lib/ruby/1.8:/var/lib/gems/1.8/bin"

6 reload your profile:
webistrano$ . ../.profile

7 edit the Gemfile to tell it to use rake version 0.8.7:
webistrano$ vi Gemfile
gem "rake", "0.8.7"

8 install webistrano
webistrano$ bundle install
webistrano$ RAILS_ENV=development rake --trace db:migrate

9 Start webistrano
webistrano$ ruby script/server -d -p 3000 -e development


You should now be able to access the webistrano application on http://<hostname>:3000

dimanche 19 décembre 2010

Zend framework: imaging the menu

Hmm

This is more of a reminder to ::self than a post. Because it took me nearly a full day to figure out how to be able to put just a logo image in the menu with Zend_View_Helper_Navigation_Menu. So here goes.
Note 1: I used ZF 1.11
Note 2: For simplicity, I used "fullmoon" where you should use your application name. Take notice of case within the code, it's important and it changes depending on the part of code you're in.

Step 1: Extend Zend_View_Helper_Navigation_Menu

In the library, create your own menu view helper:
library/Fullmoon/View/Helper/Navigation/FullmoonMenu.php
with the following code:
class Fullmoon_View_Helper_Navigation_FullmoonMenu extends Zend_View_Helper_Navigation_Menu
{
    public function fullmoonMenu(Zend_Navigation_Container $container = null)
    {
        return $this->menu($container);
    }
}


Step 2: Modify the layout view script

This will allow you to make the following call in your layout view script (application/layouts/scripts/layout.phtml):
echo $this->navigation()->fullmoonMenu();


Step 3: Modify the bootstrap

In application/bootstrap.php, add the following:
    /**
     * Menu
     */
    protected function _initNavigation()
    {
        // Load menu data from XML file. First argument is the XML file,
        // second is the XML node containing the menu XML data
        $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav');
        // Retrieve the view object
        $view = $this->getResource('view');
        // Add our own Navigation Menu helper to the view plugins path
        $view->addHelperPath(
            'Fullmoon/View/Helper/Navigation',
         'Fullmoon_View_Helper_Navigation_'
        );
        // Load the menu into the view
        $view->navigation(new Zend_Navigation($config));
    }
Note: You can find examples of XML menu files here.
At this point, your menu should be loading normally, albeit still without an image.

Step 4: Adding the image (aahh, finally!)

Adding the image to the XML file:
<img>
  <class>title</class>
  <src>/img/logo-small.png</src>
  <module>default</module>
  <controller>index</controller>
  <action>index</action>
</img>


Step 5: Amending your menu helper

As a final step, we need to render the image (in library/Fullmoon/View/Helper/Navigation/FullmoonMenu.php) by overriding the protected _renderMenu() method from library/Zend/View/Helper/Navigation/Menu.php:
    /**
     * Renders a normal menu (called from {@link renderMenu()})
     *
     * @param  Zend_Navigation_Container $container   container to render
     * @param  string                    $ulClass     CSS class for first UL
     * @param  string                    $indent      initial indentation
     * @param  int|null                  $minDepth    minimum depth
     * @param  int|null                  $maxDepth    maximum depth
     * @param  bool                      $onlyActive  render only active branch?
     * @return string
     */
    protected function _renderMenu(Zend_Navigation_Container $container,
                                   $ulClass,
                                   $indent,
                                   $minDepth,
                                   $maxDepth,
                                   $onlyActive)
    {
        $html = '';

        // find deepest active
        if ($found = $this->findActive($container, $minDepth, $maxDepth)) {
            $foundPage = $found['page'];
            $foundDepth = $found['depth'];
        } else {
            $foundPage = null;
        }

        // create iterator
        $iterator = new RecursiveIteratorIterator($container,
                            RecursiveIteratorIterator::SELF_FIRST);
        if (is_int($maxDepth)) {
            $iterator->setMaxDepth($maxDepth);
        }

        // iterate container
        $prevDepth = -1;
        foreach ($iterator as $page) {
            $depth = $iterator->getDepth();
            $isActive = $page->isActive(true);
            if ($depth < $minDepth || !$this->accept($page)) {
                // page is below minDepth or not accepted by acl/visibilty
                continue;
            } else if ($onlyActive && !$isActive) {
                // page is not active itself, but might be in the active branch
                $accept = false;
                if ($foundPage) {
                    if ($foundPage->hasPage($page)) {
                        // accept if page is a direct child of the active page
                        $accept = true;
                    } else if ($foundPage->getParent()->hasPage($page)) {
                        // page is a sibling of the active page...
                        if (!$foundPage->hasPages() ||
                            is_int($maxDepth) && $foundDepth + 1 > $maxDepth) {
                            // accept if active page has no children, or the
                            // children are too deep to be rendered
                            $accept = true;
                        }
                    }
                }

                if (!$accept) {
                    continue;
                }
            }

            // make sure indentation is correct
            $depth -= $minDepth;
            $myIndent = $indent . str_repeat('        ', $depth);

            if ($depth > $prevDepth) {
                // start new ul tag
                if ($ulClass && $depth ==  0) {
                    $ulClass = ' class="' . $ulClass . '"';
                } else {
                    $ulClass = '';
                }
                $html .= $myIndent . '<ul' . $ulClass . '>' . self::EOL;
            } else if ($prevDepth > $depth) {
                // close li/ul tags until we're at current depth
                for ($i = $prevDepth; $i > $depth; $i--) {
                    $ind = $indent . str_repeat('        ', $i);
                    $html .= $ind . '    </li>' . self::EOL;
                    $html .= $ind . '</ul>' . self::EOL;
                }
                // close previous li tag
                $html .= $myIndent . '    </li>' . self::EOL;
            } else {
                // close previous li tag
                $html .= $myIndent . '    </li>' . self::EOL;
            }
            // Manage menu image
            if ($page->src != '') {
                $html .= $myIndent . '    <li class="title">' . self::EOL
                      . '        <img src="' . $page->src . '" />' . self::EOL;
            } else {
                // render li tag and page
                $liClass = $isActive ? ' class="active"' : '';
                $html .= $myIndent . '    <li' . $liClass . '>' . self::EOL
                       . $myIndent . '        ' . $this->htmlify($page) . self::EOL;
            }
            // store as previous depth for next iteration
            $prevDepth = $depth;
        }

        if ($html) {
            // done iterating container; close open ul/li tags
            for ($i = $prevDepth+1; $i > 0; $i--) {
                $myIndent = $indent . str_repeat('        ', $i-1);
                $html .= $myIndent . '    </li>' . self::EOL
                       . $myIndent . '</ul>' . self::EOL;
            }
            $html = rtrim($html, self::EOL);
        }

        return $html;
    }
This part is what does the trick:
            // Manage menu image
            if ($page->src != '') {
                $html .= $myIndent . '    <li class="title">' . self::EOL
                      . '        <img src="' . $page->src . '" />' . self::EOL;
            } else {
                // render li tag and page
                $liClass = $isActive ? ' class="active"' : '';
                $html .= $myIndent . '    <li' . $liClass . '>' . self::EOL
                       . $myIndent . '        ' . $this->htmlify($page) . self::EOL;
            }


Conclusion

I had a hard time gathering the necessary information over the Internet, hopefully this may help out those wanting to add a logo to the menu with Zend Framework.
Note that the logo does not have link attached to it, but with a little tweaking of the last code snippet that shouldn't be too difficult ;)

There may be a far simpler solution to this but I don't know of it nor have I found it on the Internet.

jeudi 11 novembre 2010

Should your company develop it's own framework ?

Having had some discussions with colleagues about building a framework, I just wanted to share my point of view, hoping it may profit to someone.

Adapted to your needs

A framework, per definition, is generic. If you develop one yourself and you do it right, your home-made framework will end up having as much abstraction as a public one.
On the other hand, a public framework can be adapted to some specific needs you may have with less effort than developing one from scratch.

What about tests ?

A public framework usually comes with a full stack of unit tests. And every modification or addition to the code will have it's accompanying tests.
It will take you a good deal of time and consistency to accompany each and every change to your home-made framework with it's unit tests.

Documentation

You're developing a framework for your company so everyone can take benefit of it. So you have to document it properly. Not just API documentation, but also a developer reference guide so anyone new to the company and the framework can get up to par swiftly. That requires time too. Writing documentation is not that easy as you might think it is, either.
Public frameworks -at least the major ones- come fully documented and the documentation is being kept up-to-date as the framework evolves.

Security

The framework you're developing will be used by not that many people (unless you release it out in the open and it becomes a success, but then I guess it'll have no specificities to your company any more) and security flaws and bugs will not be detected rapidly.
Public frameworks are being used in many applications. So security is one of the major concerns of the contributors of a public framework. Besides that, many people using the framework in many different ways, bugs are rapidly detected - and corrected.

Support

By it's nature, the proprietary framework will have a far less big user base than a public one. So support for it is naturally reduced to a few people, if it is not just one person.
I'm quite sure you'll often get a response to a question more rapidly and accurately from the user community of a public framework than you will from the gurus who wrote the one for your company.

Recruitment

Last but not least, it'll be easier to recruit if you're using a public framework: it's quite obvious no one will know yours!

Conclusion

In the end, and in almost any case, there's no valid reason for your company to develop it's own framework: it'll cost more time & effort than adapting an existing one, and that includes performance optimization if needs be.
As a side note though, I'd encourage any developer to try and build his own framework or actively contribute to an existing one. You learn a lot from it!

vendredi 6 août 2010

Setting the paper straight

As a reminder note to myself, and for anyone else it may help, here's how you can easily set the default page size for printing in Firefox.
  1. fire up firefox
  2. Type about:config in the address bar
  3. Confirm that you'll be careful
  4. In the filter bar, type paper_size
  5. Double-click the entry print.postscript.paper_size and change it's value to A4 for example
  6. Hit Ok to save your modification
  7. Double-click the entry print.print_paper_size and change it's value to 1 to set the value of entry print.postscript.paper_size as the default
That's it, now Firefox should have A4 as the default paper size when printing.

jeudi 13 mai 2010

Ubuntu 10.4 ambiance theme: setting the buttons straight

I just recently installed Ubuntu 10.4 LTS and set appearance to use the ambiance theme.

The window border buttons were on the left though by default.
Now, I'm not a fluent Mac user, so I prefer having those on the right.

It proved to be really simple to do so: Hit <alt><f2>, type

gconf-editor
and hit <enter>. Navigate to apps > metacity > general and edit the item
button_layout
Simply put the colon ":" on the left side of the string instead of the right side to set the buttons to be on the right side of the window border.

You can also modify the order of the buttons by modifying the order of the "maximize,minimize,close" string.