Injustice - Developers Among Us (SciFiDevCon 2024)
eZ Publish Free Developer Basics Training - London - 2011 April 13th by Nicolas Pastorino
1. Agenda
●
Installing eZ Publish
●
Content management
●
Internal structure
●
Design
●
Templates
●
Common templates tasks
●
Template override system
1
London, 2011, April 13th, free training - http://share.ez.no
2. Agenda
●
8:30am - 9:00am Registrations and Breakfast
●
9:00am - 10:00am Non technical presentation of eZ Publish
●
10:00am - 12:00am eZ Publish introduction training
●
12:00am - 13:00 - Lunch break
●
13:00 - 15:00 eZ Publish introduction training
●
15:00 - 15:30 - Break
●
15:30 - 17:00 eZ Publish introduction training
●
17:00 and on Chill-out and social
2
London, 2011, April 13th, free training - http://share.ez.no
3. Hello
I am Nicolas Pastorino, taking care of the eZ
Publish Community.
You can reach me at :
Email : nfrp@ez.no
Twitter : @jeanvoye
Code illustrating the notions covered in this training
can be found here :
https://github.com/nfrp/eZ-Publish-Training-
examples
3
London, 2011, April 13th, free training - http://share.ez.no
4. Installation
4
London, 2011, April 13th, free training - http://share.ez.no
5. Components
●
Hardware (server)
“enough” speed and memory; disk space
●
Network connection (http, ssh + ftp)
●
Operating System: Linux, Windows, Solaris
●
Webserver: Apache, IIS
●
PHP
●
Database: MySQL, PostgreSQL, Oracle
●
Helper tools
●
eZ Publish
5
London, 2011, April 13th, free training - http://share.ez.no
6. eZ Publish downloads
●
eZ Publish Enterprise version
http://ez.no/
●
eZ Publish Community Project
http://share.ez.no/download
●
All-inclusive stack (not for production)
http://bitnami.org/stack/ezpublish
6
London, 2011, April 13th, free training - http://share.ez.no
7. Full AMP stack downloads
●
http://www.easyphp.org/ (win)
●
http://www.apachefriends.org/en/xampp.html
(win, mac, linux, solaris)
●
http://www.mamp.info/en/index.html (mac)
●
http://www.wampserver.com/ (win)
7
London, 2011, April 13th, free training - http://share.ez.no
8. Requirements, eZ Publish 4.x
●
Detailed list of requirements:
http://ez.no/ezpublish/requirements
●
3 levels of platform support:
– Reference
– Approved
– Compatible
●
“Cluster mode” is whenever multiple webservers
are used for a single eZ Publish installation
8
London, 2011, April 13th, free training - http://share.ez.no
9. Requirements, eZ Publish 4.x
●
Apache
– httpd.apache.org
– Version 2.2.x, prefork mode only
– mod_rewrite required for vhost modes
– Also IIS or (unsupported) NginX, Lighttpd
– Testing the configuration: mod_status,
mod_info
9
London, 2011, April 13th, free training - http://share.ez.no
10. Requirements, eZ Publish 4.x
●
PHP
– www.php.net
– Minimum PHP 5.2.1 or later, Preferably 5.3+
– Extensions: all listed on the website
– GD extension needed if no Imagemagick
– Cli version recommended
– Please no CGI mode
– An accelerator recommended (eg. APC)
10
London, 2011, April 13th, free training - http://share.ez.no
11. Requirements, eZ Publish 4.x
●
php.ini configuration:
memory_limit 256 MB
max_execution_time 720 secs
date.timezone
●
Testing the configuration: phpinfo.php
● On the command line: php -i
●
The finetune button of the setup wizard checks
for proper php configuration and filesystem
permissions
11
London, 2011, April 13th, free training - http://share.ez.no
12. Requirements, eZ Publish 4.x
●
Zeta Components
– Enterprise-ready general-purpose PHP
components library
– Download and documentation at
http://zetacomponents.org
– Can be installed via PEAR, tarball download
or directly within the eZ Publish bundle
12
London, 2011, April 13th, free training - http://share.ez.no
13. Requirements, eZ Publish 4.x
●
MySQL
– 5.0 or 5.1 (recommended)
– unicode charset (UTF-8) required
– InnoDB storage engine required
– Also supported: PostgreSQL, Oracle
●
Database structures created automatically by
the setup wizard
●
Database itself has to be created by hand
●
Web-based administration tool: phpMyAdmin
http://www.phpmyadmin.net/
13
London, 2011, April 13th, free training - http://share.ez.no
14. Requirements, eZ Publish 4.x
●
Imagemagick
– http://www.imagemagick.org/
– Command line tool
– Needed if no PHP GD extension
●
CLI converters to plaintext for indexing
binary files (pdf, word, ...)
●
JAVA VM for eZ find
14
London, 2011, April 13th, free training - http://share.ez.no
15. Installation
15
London, 2011, April 13th, free training - http://share.ez.no
16. Content Management
16
London, 2011, April 13th, free training - http://share.ez.no
17. eZ Publish Content
Management
●
Content Management System = CMS
●
Easily organize, store, retrieve and present
information
●
Not a one-size-fits-all approach
●
Ready-to-use built-in data structures
●
On-the-fly modification of content structure
●
Possibility to add custom content structures
●
Via the Administration Interface
17
London, 2011, April 13th, free training - http://share.ez.no
18. Separation of content and
design
18
London, 2011, April 13th, free training - http://share.ez.no
19. Separation of
content and design - benefits
●
Content authors and designers can work
separately without conflicts
●
Content can be published easily in
multiple formats
●
Easy to do global redesigns / changes of
site appearance
●
Content can easily be transferred and
reused
19
London, 2011, April 13th, free training - http://share.ez.no
20. Content engine
●
Object oriented approach
●
Concurrency control with
– Version management
– State (draft, published, archived)
●
Transaction safe
●
Translation management
20
London, 2011, April 13th, free training - http://share.ez.no
23. Content
object
versioning
The state of a version is
indicated by a status:
●
Draft (newly created)
●
Published (at most 1)
●
Pending
●
Archived
●
Rejected
23
London, 2011, April 13th, free training - http://share.ez.no
25. Content nodes
●
A node is the published version of a content
object (a web page)
●
A node encapsulates exactly one content
object, and represents the object's location
●
Nodes are organized in a hierarchy (called the
“content node tree”)
●
Both objects and nodes have unique IDs
25
London, 2011, April 13th, free training - http://share.ez.no
26. Objects, nodes and the content
node tree
26
London, 2011, April 13th, free training - http://share.ez.no
27. Content node tree – user
perspective
27
London, 2011, April 13th, free training - http://share.ez.no
28. Content node tree properties
●
Each node references one parent node (except for
root node)
●
Each top-level node is the starting point of a
branch
●
Each node can be the parent node of zero, one or
multiple child nodes
●
The content objects capable of having sub-items
are called “containers”
●
New nodes are automatically created and added to
the tree when publishing a new content object
28
London, 2011, April 13th, free training - http://share.ez.no
29. Multiple locations – system
perspective
29
London, 2011, April 13th, free training - http://share.ez.no
30. Multiple locations – user
perspective
30
London, 2011, April 13th, free training - http://share.ez.no
31. Summary of Content Engine
●
Content class ●
Content node
●
Attribute ●
Content node tree
●
Data type ●
Top-level nodes
●
Content object ●
Multiple locations
●
Object versioning
●
Multi-language
support
31
London, 2011, April 13th, free training - http://share.ez.no
32. Demo of content
engine
32
London, 2011, April 13th, free training - http://share.ez.no
33. Internal Structure
33
London, 2011, April 13th, free training - http://share.ez.no
34. Storage of data
34
London, 2011, April 13th, free training - http://share.ez.no
35. Libraries, kernel and modules
35
London, 2011, April 13th, free training - http://share.ez.no
36. MVC architecture
eZ Publish implements an MVC pattern
The execution order is:
1.Index Controller (1st level) index.php
nd
2.Module Controller (2 level) .php
3.View Model .php
4.Template View .tpl
36
London, 2011, April 13th, free training - http://share.ez.no
37. Execution flow
37
London, 2011, April 13th, free training - http://share.ez.no
38. Modules & Views
38
London, 2011, April 13th, free training - http://share.ez.no
39. Modules
●
A module provides
– Views
– Fetch functions (for templates)
– Access functions (for the policy system)
– Operations
●
The system comes with modules for typical
everyday tasks (Content, User, Role, ...)
●
It is possible to add custom modules via
extensions
39
London, 2011, April 13th, free training - http://share.ez.no
40. Views
●
An interface to the system, providing access to
its functions
●
Generates the result via a template
●
Name of view appears in URL after name of
module, separated by a slash
– content/edit
– user/login
●
Access to the views of a module is controlled by
permissions set for the related access functions
●
Web pages displaying content use content/view
40
London, 2011, April 13th, free training - http://share.ez.no
41. The idea of sites : siteaccess
41
London, 2011, April 13th, free training - http://share.ez.no
42. Siteaccess : concept
42
London, 2011, April 13th, free training - http://share.ez.no
43. Siteaccess configuration
●
Available siteaccesses must be specified in the
global override for site.ini.
●
The siteaccesses are located in a dedicated
subdirectory within /settings/siteaccess
●
The name of the sub-
directories are the
names of the actual
siteaccesses
43
London, 2011, April 13th, free training - http://share.ez.no
45. Design
●
Design is the way content is marked up, styled
and presented
●
An eZ Publish installation is capable of handling
a virtually unlimited number of designs
●
An eZ Publish design contains:
templates, CSS files, JS files, non-content-
related image files, font files, flash files etc...
●
A siteaccess dictates the design to be used via
the [DesignSettings] parameters in site.ini
45
London, 2011, April 13th, free training - http://share.ez.no
46. Design directories
● All design-specific files are located in design/ or
extension/<extname>/design
– Each design has its own subdirectory within design/
– The name of the subdirectory also functions as the
name of the design
●
Typically contains the following subdirectories:
fonts/ font files for the texttoimage template operator
images/ non-content-specific images
override/ custom templates triggered by override rules
stylesheets/ CSS files
templates/ custom/main templates
46
London, 2011, April 13th, free training - http://share.ez.no
47. Design fallbacks
47
London, 2011, April 13th, free training - http://share.ez.no
48. Extensions can provide design
directories
Suppose the website has:
●
Main design: my_design
●
Additional designs: ezflow, ezwebin, base
●
Default design: standard
●
The following extensions providing design
elements: my_extension, ezflow, ezwebin,
ezwt, ezoe
That means 30 directories will be scanned for
design elements
48
London, 2011, April 13th, free training - http://share.ez.no
49. Design fallbacks example
Location: design/... extension/ extension/ extension/ extension/ extension/
ezoe/ ezwt/ ezwebin/ ezflow/ my_ext/
design/... design/... design/... design/... design/...
Design:
In
.../my_design
…/ezflow
…/ezwebin
…/base
Out
…/standard
49
London, 2011, April 13th, free training - http://share.ez.no
50. eZ Publish Template Engine
50
London, 2011, April 13th, free training - http://share.ez.no
51. Templates
●
Fundamental unit of site design
– describe how a particular type of content should be
visualized
●
Custom extended HTML file
– markup follows XHTML 1.0 Transitional
– .tpl filename extension
– with eZ Publish-specific code, no PHP code
– can extract information from the system
– solve common programmatic issues (branching,
looping, etc.)
51
London, 2011, April 13th, free training - http://share.ez.no
52. Template code
<h1>My title</h1>
<p>
The current time is: {currentdate()|
l10n( time )}
</p>
{* this is a comment *}
52
London, 2011, April 13th, free training - http://share.ez.no
53. Component-based system
●
A web page is made up of several templates. At
the minimum, eZ Publish always renders the
main template (the pagelayout)
– templates can come from different designs
– a template can include another one
● pagelayout.tpl
– is the main template
– dictates the overall look of a site
– displays the result of the module execution in
its middle
53
London, 2011, April 13th, free training - http://share.ez.no
54. Pagelayout and module result
54
London, 2011, April 13th, free training - http://share.ez.no
55. Location pagelayout.tpl
Design specified in [DesignSettings]
block of site.ini for current siteaccess
55
London, 2011, April 13th, free training - http://share.ez.no
56. Structure pagelayout.tpl
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
@import url({'stylesheets/core.css'|ezdesign});
@import url({'stylesheets/debug.css'|ezdesign});
</style>
{include uri='design:page_head.tpl'}
</head>
<body>
{$module_result.content}
<!--DEBUG_REPORT-->
</body>
</html>
56
London, 2011, April 13th, free training - http://share.ez.no
57. Module views and templates
●
Every view generates a chunk of HTML code by
making use of a template:
– whenever a view has finished, it will issue an
internal template request
– the requested template will be processed and
converted to HTML
– after processing (module finishes), the
generated HTML will be available in the
pagelayout (as $module_result variable)
57
London, 2011, April 13th, free training - http://share.ez.no
58. View templates
●
Templates used by views are called ”view
templates”
●
Two types of view templates:
– node template: displays a content node
– system template: all views but content/view
●
Difference between the two:
– template name and location
– available template variables ($node etc.)
– override rules that can be used (more flexible
for node templates)
58
London, 2011, April 13th, free training - http://share.ez.no
59. Default view templates
●
An eZ Publish distribution provides default
templates for all views
●
The default templates are located in the
templates directory of the standard design
●
For display of content, the default template is
node/view/full.tpl
●
System templates have the same name as the
view, located inside a directory that has the
same name as the module to which the view
belongs
59
London, 2011, April 13th, free training - http://share.ez.no
60. Custom view templates
●
Creating a custom design that provides templates
for all possible scenarios would be too much work
●
The automatic fallback system makes it possible to
use a mixture of both custom and standard/default
templates
●
Custom system templates are usually just modified
copies of the standard templates, located in the
custom design
●
Custom node templates make it possible to display
various types of nodes in different ways
– created using override rules
60
London, 2011, April 13th, free training - http://share.ez.no
61. Node template composition
When a node is requested
and there is no matching
template override, eZ
Publish will generate a
page that is built up of the
following elements:
61
London, 2011, April 13th, free training - http://share.ez.no
62. Location of node templates
● Are placed in the /templates/node/view of a design
directory
●
If the requested file is not found, eZ Publish will
attempt to locate it within one of the fallback/additional
designs
● Location of pagelayout.tpl
and full view node template
in example design:
62
London, 2011, April 13th, free training - http://share.ez.no
63. Structure full.tpl
<h2>{$node.name|wash()}</h2>
{foreach $node.data_map as $attribute}
<p>
{attribute_view_gui attribute=$attribute}
</p>
{/foreach}
{if $node.children|count()}
<h3>{'Children'|i18n()}</h3>
<ul>
{foreach $node.children as $child}
<li>{node_view_gui content_node=$child view='line'}</li>
{/foreach}
<ul>
{/if}
63
London, 2011, April 13th, free training - http://share.ez.no
64. The $node variable
●
Whenever the system makes use of a node
template, a variable called $node is available in the
template that is used
● $node is set by the system and contains an
ezcontentobjecttreenode object that represents
the requested node
● $node allows the extraction and display of various
information about the node and the object that it
encapsulates
● $node is not available in pagelayout.tpl
64
London, 2011, April 13th, free training - http://share.ez.no
65. eZ Publish Template Language
65
London, 2011, April 13th, free training - http://share.ez.no
66. Variable types
●
The eZ Publish template ●
While some variable types
language supports the can be created on the fly,
following variable types: others need to be created
using an operator
– Number
– String
●
Types that may be created
directly are numbers and
– Booleans strings; booleans and arrays
– Arrays must be created using
operators
– Objects
●
Objects may be created
using miscellaneous
functions and operators
66
London, 2011, April 13th, free training - http://share.ez.no
67. Variable usage 1/2
{def $weather='warm' $celsius=32 $fahrenheit=90}
The weather is
{$weather}: {$celsius} C / {$fahrenheit} F <br />
{undef $celsius $fahrenheit}
The weather is still {$weather}. <br />
{undef}
The output of this example will be:
The weather is warm: 32 C / 90 F
The weather is still warm.
67
London, 2011, April 13th, free training - http://share.ez.no
69. Arrays / hashes
{def $sentence = array( 'Life', 'is', 'very',
'good!' )}
The 1st element is: {$sentence.0} <br />
The 2nd element is: {$sentence.1} <br />
The 3rd element is: {$sentence[2]} <br />
The 4th element is: {$sentence[3]} <br />
{def $prices = hash( 'apple', 2, 'pear', 3 )}
Apples cost {$prices.apple} <br />
Pears cost {$prices['pear']} <br />
{undef}
69
London, 2011, April 13th, free training - http://share.ez.no
70. Array and object inspection
{$node|attribute()}
{$node.creator|attribute( show )}
{$node.creator.data_map|attribute( show, 1 )}
{debug-log var=$node msg='My node'}
●
“show” is used to display values, not just keys
●
“1” is the level of recursion used
70
London, 2011, April 13th, free training - http://share.ez.no
71. Template control structures
{if eq( $fruit, 'apples' )}
Apples <br />
{elseif eq( $fruit, 'oranges' )}
Oranges <br />
{else}
Bananas <br />
{/if}
71
London, 2011, April 13th, free training - http://share.ez.no
72. Template control structures
{for 0 to 7 as $counter}
Value of counter: {$counter} <br />
{/for}
{foreach $objects as $object
sequence array( 'dark', 'light' ) as $style}
<div class="{$style}">
{$object.name|wash()}
</div>
{/foreach}
72
London, 2011, April 13th, free training - http://share.ez.no
73. Template functions
and operators
●
Template functions take named parameters,
separated by spaces
{node_view_gui content_node=$my_node view='full'}
●
Template operators take positional parameters,
separated by commas, and input via the pipe
{concat( 'To ', 'The ' )|
prepend( 'Back ' )|append( 'Future' )}
●
New functions and operators can be added in
extensions
73
London, 2011, April 13th, free training - http://share.ez.no
76. Template Language : daily
tasks
76
London, 2011, April 13th, free training - http://share.ez.no
77. Selected variables / pagelayout
● $current_user (object)
● $module_result (array)
– $module_result.path (array)
– $module_result.content (string)
●
The complete list is available online at
http://doc.ez.no/eZ-Publish/Technical-
manual/4.x/Templates/The-pagelayout/Variables-
in-pagelayout
77
London, 2011, April 13th, free training - http://share.ez.no
78. Template tasks
information extraction
●
Fetch single node
{def $my_node = fetch( content, node
hash( node_id, 13 ) )}
●
Fetch multiple nodes
{def $my_node = fetch( content, list,
hash( parent_node_id, 13 ) )}
●
Fetch multiple nodes filtering on class and total number
{def $my_node = fetch( content,list,
hash( parent_node_id,13,
limit, 10,
class_filter_type, 'include',
class_filter_array, array( 'article' ) ) )}
78
London, 2011, April 13th, free training - http://share.ez.no
79. Template tasks
node/object metadata
●
Node name
{$node.name|wash}
●
Time published
{$node.object.published|l10n( 'shortdatetime' )}
●
Creator
{$node.object.owner.login|wash}
●
Class
{$node.object.class_name|wash()}
● For a complete list of attributes, look up ezcontentobject
and ezcontentobjecttreenode in the manual
79
London, 2011, April 13th, free training - http://share.ez.no
80. Template tasks
node/object attributes
●
Raw output
{$object.data_map.my_text_attribute.content}
{$object.data_map.my_xml_attr.content.output.output_text}
<img
src={$object.data_map.my_image.content[image_size].full_pa
th|ezroot()} ... />
It depends on the datatype. See manual for details
●
Formatted output
{attribute_view_gui
attribute=$node.object.data_map.my_attribute}
80
London, 2011, April 13th, free training - http://share.ez.no
81. Template tasks
full node view
<h2>{$node.name|wash}</h2>
{foreach $node.data_map as $attr}
{attribute_view_gui attribute=$attr}
{/foreach}
{* sort children by date, regardless of backoffice *}
{def $subel = fetch('content','list',
hash( 'parent_node_id', $node.node_id,
'sort_by', array( 'modified', true() ) ) )}
{foreach $subel as $item}
<a href={$item.url_alias|ezurl}>{$item.name|
wash}</a>
<br />
{/foreach}
81
London, 2011, April 13th, free training - http://share.ez.no
82. Template tasks
menu
{* sort children as set in backoffice *}
{def $menuitems=fetch('content','list',
hash('parent_node_id', $mymenu.node_id,
'class_filter_type', 'include',
'class_filter_array', array('folder'),
'sort_by', $mymenu.sort_array))}
<h3>Menu:</h3>
{foreach $menuitems as $item}
<a href={$item.url|ezurl}>
{$item.name|wash}
</a> <br />
{/foreach}
82
London, 2011, April 13th, free training - http://share.ez.no
83. Template tasks
printable version / sitemap
●
Printable version
<a href={concat("/layout/set/print/"
$requested_uri_string)|ezurl}>Printable version of
current page</a>
●
Sitemap
<a href={'content/view/sitemap/2'|
ezurl}>Sitemap</a>
83
London, 2011, April 13th, free training - http://share.ez.no
84. Template tasks
tip a friend / search box
●
Tip a friend
<a
href={concat('/content/tipafriend/', $node.node_id)|
ezurl}>
Send this to a friend
</a>
●
Search box
<form method="get"
action={'/content/search'|ezurl}>
<input type="text" name="SearchText" value="" />
<input type="submit" name="SearchButton" value="Search" />
</form>
84
London, 2011, April 13th, free training - http://share.ez.no
89. Template override system logic
Once the template to be used is determined, it is
searched for across the template fallback chain
89
London, 2011, April 13th, free training - http://share.ez.no
90. override.ini.append.php
●
Consists of override blocks
– named sets of rules that tell eZ Publish to
use an alternate template in a specific
situation
●
For each block, the following information must
be specified:
– A unique name for the override
– The template that should be overridden
– The template that should be used instead
– The directory where the override template is located
– A set of conditions/rules that control when the
override should be activated
90
London, 2011, April 13th, free training - http://share.ez.no
91. Override block
91
London, 2011, April 13th, free training - http://share.ez.no
92. Example 1/5
92
London, 2011, April 13th, free training - http://share.ez.no
93. Example 2/5
●
Without any overrides, eZ Publish will
display all nodes using the same template
●
However, we want the system to do the
following:
– Display a special ”welcome” template when the ”My site”
node is accessed
– Display a custom folder template when a folder is
accessed
– Display a custom article template when a news article is
accessed
– Display a custom product template when a product is
accessed
93
London, 2011, April 13th, free training - http://share.ez.no
94. Example 3/5
# Override for welcome page (1) # Override for articles (3)
[welcome_page] [news_articles]
Source=node/view/full.tpl Source=node/view/full.tpl
MatchFile=welcome.tpl
MatchFile=my_article.tpl
Subdir=templates
Match[node]=2 Subdir=templates
Match[class_identifier]=article
# Override for folders (2)
[my_folder] # Override for products (4)
Source=node/view/full.tpl [products]
MatchFile=my_folder.tpl Source=node/view/full.tpl
Subdir=templates MatchFile=my_product.tpl
Match[class_identifier]=folder Subdir=templates
Match[class_identifier]=product
94
London, 2011, April 13th, free training - http://share.ez.no
95. Example 4/5
●
The alternate templates should be placed
in the override/templates subdirectory
of the main design that is used by the
siteaccess:
95
London, 2011, April 13th, free training - http://share.ez.no
96. Example 5/5
96
London, 2011, April 13th, free training - http://share.ez.no
97. What was NOT covered today
97
London, 2011, April 13th, free training - http://share.ez.no
98. TODO :
●
Workflows ●
eZ Flow
●
Cronjobs ●
eZ Find
●
Caches, ●
URLs
●
Extensions ●
Permission system
●
Clustering support ●
Sections
●
3rd party integration ●
Object states
98
London, 2011, April 13th, free training - http://share.ez.no
99. Further resources for self-
learning
99
London, 2011, April 13th, free training - http://share.ez.no
100. Resources
Examples code : https://github.com/nfrp/eZ-Publish-Training-examples
eZ Publish Community : http://share.ez.no
eZ Community presentation : http://share.ez.no/get-involved
Documentation : http://doc.ez.no
Demo videos : http://ez.no/Demos-videos
eZ Publish tutorials : http://share.ez.no/learn
Download eZ Publish Community Project : http://share.ez.no/download
eZ Publish Extensions Forge : http://projects.ez.no
How to contribute to eZ Publish using GIT : http://share.ez.no/learn/ez-
publish/how-to-contribute-to-ez-publish-using-git
eZ Community on Twitter : http://twitter.com/ezcommunity
100
London, 2011, April 13th, free training - http://share.ez.no
101. Thank you !
You can reach me at :
nfrp@ez.no
twitter : @jeanvoye
101
London, 2011, April 13th, free training - http://share.ez.no