Installation de Drupal chez Nexen


En tant que salarié du groupe Alterway nous avons eu compte d’essai chez Nexen services pour hébergé un site en PHP/MySQL. En temps que développeur Python nous nous sommes posé la question: « C’est bien gentil, mais à quoi cela va-t-il nous servir ? ». Pourquoi ne pas tester un framework LAMP en reprenant un site fait de bric et de broc pour en faire un site professionnel… pour l’instant le nom du site restera secret.

Après investigation auprès de mes camarades de Nexen c’est sur Drupal que je vais faire mes armes. Cela fait 5 ans que je n’ai pas touché à du PHP, j’ai un brin de nostalgie. La première chose à faire est de trouver de la documentation. Un coup d’œil dur le site de la communauté drupal française et me voilà avec un tutorial un peu court mais suffisant pour commencer.

Viens la question fatidique de la gestion du projet. Je serai seul pour le moment, mais le développeur de la version précédente du site viendra sans doute me donner un coup de main durant la phase de migration. De plus, je voyage beaucoup, un système centralisé n’est pas envisageable.

Il me reste bazaar, darcs, mercurial et git. J’ai déjà testé les trois premiers avec un penchant pour darcs mais c’est un bonne occasion pour tester git qui semble avoir le vent en poupe. un coup de ‘man
gittutorial’ pour démarrer :

Préparation des sources en local

$ tar zxf /home/encolpe/Desktop/drupal-6.4.tar.gz
$ mv drupal-6.4/ drupal-nexen
$ cd drupal-nexen/
drupal-nexen$ git init

Initialized empty Git repository in /…/drupal-nexen/.git/

drupal-nexen$ git config –global user.name « Encolpe Degoute »
drupal-nexen$ git config –global user.email encolpe@gmail.com

drupal-nexen$ git add .
drupal-nexen$ git commit

drupal-nexen$ tar zxf /home/encolpe/Desktop/fr-6.x-1.x-dev.tar.gz

drupal-nexen$ git status

drupal-nexen$ git add */*/translations *.fr.txt
drupal-nexen$ git commit

La prise en main de git semble simple jusque là.
Faire un ‘git add .’ est beaucoup plus explicite que la commande ‘svn import’: c’est le dossier courant qui est importé, pas de doute possible.

Il faut ensuite configurer un client FTP pour déposer vos fichiers sur votre compte hébergé. Je choisi le logiciel en ligne de commande ‘ncftp‘ dans l’espoir de pouvoir le coupler avec les commits dans la branche principale de git pour gagner un peu de temps.
Ce couplage devra être asynchrone…

J’ai maintenant un beau site qui me montre sa page d’installation sans me demander de mot de
passe (sic). D’ailleurs il ne semble pas très content. Soit disant il faut que je copie ‘sites/default/default.settings.php‘  dans ‘sites/default/settings.php‘ . Pas de panique.

drupal-nexen$ git mv sites/default/default.settings.php sites/default/settings.php
drupal-nexen$ git commit sites/default

Ensuite vous pouvez modifier le paramètre db_url pour les accès à votre base (notez la triple présence de username) :

$db_url = ‘mysql://username:********@mysql.username.nexenservices.com/username’;

Après un nouveau commit et le transfert du fichier vers votre compte hébergé vous pouvez maintenant terminer l’installation en choisissant la langue de votre site et en laissant faire l’installeur… ou non.

Erreur en installant Drupal

Erreur en installant Drupal

Vu d’ici cette histoire de ‘register_globals‘ à désactiver semble un brin complexe. Est-il possible de configurer ce genre de paramètre avec mon compte Nexen ?

Il faut aller voir sur la page d’accueil du compte http://www.nexenservices.com/webmestres/index.php pour aller chercher la solution. Une fois connecté il faut choisir votre site mutualisé en bas de la colonne de gauche puis cliquer sur ‘Configuration avancée‘ à nouveau en bas de la colonne de gauche.

Il faut configurer la racine du site, soit le dossier ‘/‘ et désactiver ‘register_globals‘, ce qui se fait en deux étapes et en image :

Choisir php et / pour le dossier racine

Choisir php et / pour le dossier racine


Il suffit de laisser les choix par défaut et de valider

Il suffit de laisser les choix par défaut et de valider

Maintenant il faut reprendre l’installation en allant sur la page http://mysite.nexenservices.com/install.php et en recommençant la procédure complète. L’installation se termine bien cette fois.

La prochaine étape sera de créer un thème pour le site. Nom de code: Opération Zèbre.

Publicités

Write a toolbox for a Plone 2.5 product


For years we have had the need to embed a utility in Plone products that allows us to execute private methods in restricted Python mode. You need such a utility when using a ZMI Python script in a Page Template or in an Expression. The last one is a CMFCore class that is used in workflow transition condition or in Archetypes field condition for example. To be able to do this utility you need to create a ‘portal tool’ for your site with some public methods. Here I will show you how to build a very basic utility that I can use in the next blog entry.

What is a tool

In pure Zope 2/CMF, a tool is a unique item with a forced id that inherits from the SimpleItem class. An instance of a tool is always created on the root of your Plone site to be acquirable from everywhere in the site.

The CMFCore product provides a function that allows us to call a tool in an unique way: ‘getToolByName’.
In python modules, external methods, or python scripts, you can use following code:

from Products.CMFCore.utils import getToolByName
mytool = getToolByName(obj or context, 'tool id', default value is not found - None if not specified)

You can use it in Page Template too, using the ‘module’ call:

python:modules['Products.CMFCore.utils'].getToolByName(here, 'tool id')

Implementation

What should a tool module contain

Now back to our implementation.

First you need to have a product to write in. To create a new product please read this howto , or download someone else’s to play with.
In your product create a file called ‘tool.py,’ if there will be only one tool in your product, or ‘myfunctiontool.py’ if there will be more than one. As a best practice, I recommend to always choose the second way.

A simple tool code could be:

from OFS.SimpleItem import SimpleItemfrom Products.CMFCore.utils import UniqueObject

from AccessControl import ClassSecurityInfo

from Globals import InitializeClass

class ProductNameTool(SimpleItem, UniqueObject):

    """ Description of what your tool handle
    """

    id = 'portal_productname'

    meta_type = 'Product Name Tool'

    manage_options = SimpleItem.manage_options
    security = ClassSecurityInfo()

InitializeClass(ProductNameTool)

Description of imported items:

  • SimpleItem is a class coming from Zope that ensures us that we have persistence and base views available in ZMI.
  • UniqueObject is a utility class coming from CMF that ensures us that nobody can rename an instance of it. It’s important for us because our tool must never be renamed by error.
  • ClassSecurityInfo is the class to use in every Zope persistent class in order to define the security of each method.
  • InitializeClass is the helper function that registers our class in the Zope context.

Description of class attributes:

  • The id must be unique on your site root and should start with ‘portal_’ or end with ‘_tool’. If your tool unherit from ZCatolog the id must be suffixed by ‘_catalog’.
  • All classes must have a meta type. You can just extend your class name with spaces.
  • manage_options contains the tabs displayed in the ZMI.
  • security defines the security in your class. All classes must contain such a declaration.

Initialize our tool at Zope startup

Now that Zope knows that you have a tool, what about Plone? Plone requires an extra step in order to register our tool (full details in: « Write your first Zope 2 product« .
We have to edit the __init__.py file of our product and add following lines:
 

from Products.CMFCore.utils import ToolInit

from myfunctiontool import ProductNameTool

tools = (ProductNameTool,)


def initialize( context ):

    ToolInit( 'My Product Tools'
                , tools=tools
                , product_name='ProductName'
                , icon='tool.gif'
                ).initialize( context )

ToolInit is a class that handles tool registration for us. We can register all tools defined in our product in only one pass.
ProductNameTool is our tool class. Here we need to import all tool classes we want to register.

At last, we call the ToolInit constructor and run its ‘initialize‘ method to build our tool factories:

  • the first parameter is the name viewed in the Add dropdown menu in the ZMI
  • tools is a tuple of classes
  • product_name should contain the name of your product
  • icon is the name of the icon displayed in the ZMI (16×16) that must be on the root of your product

We can restart Zope then add the tool in the ZMI. After that, we can add methods to this tool. Most often these methods are public or protected by ‘View’ or ‘Manage portal’ permissions.

Future of Zope 2 tools

In Zope 3 tools are becoming utilities. In Plone 3 we are in limbo, with all old Zope 2 tools registered both as tools and as utilities. In the near future, however, only the utilities will be used. Use Tool for Plone 2.5 development only.

You can read more about utilities in Zope 3 and Plone 3 documentation.

How to hide a column in CPS with CPSSkins


Since few weeks I went back in CPS to make maintenance on it. I was a CPS core developper, three years ago…
I’m customing a CPS theme with CPSSkins. It could be a very cool product if a documentation exists.
It was so in advanced on web2.0 that only few people really used it outside its main developper and Nuxeo team.

It’s the first article on CPS and not the last one.

a quick recipe to explain how to hide a skin in a part of your site

The goal is to hide the right column when the ‘projects_results’ template is used

  1. login with site Manager rights
  2. in the portal box cloick on ‘Edit themes’
  3. duplicate ‘Fille’ page and named it ‘SansColonne’
  4. switch to layout mode
  5. set column number to 1 in the main block
  6. go in the ZMI on the site root and edit the .cpsskins_theme script with the following code
theme_id = 'mysitetheme'

if REQUEST is None:
    REQUEST = context.REQUEST

if not context.portal_membership.isAnonymousUser():
    return '%s+Authenticated' % theme_id
elif REQUEST.get('PUBLISHED').getId() == 'index_html':
    return '%s+HomePage' % theme_id
elif REQUEST.get('URL').endswith('projects_results'):
    return '%s+SansColonne' % theme_id
else:
    return '%s+Fille' % theme_id