By Ingeniweb. A Django site.
Novembre 18, 2008
Gael Pasgrimaud
gawel
Gawel's blurb
» Get thumbnails the WSGI way

A few month ago I've created a middleware to generate and cache images thumbnails. I need this to evaluate the image size from the browser's window on the client side and then get the thumbnail at an url based on this size.

The result is iw.thumbs. The package provide a highly configurable middleware to serve images thumbnails.

The principle is to map an uri to a file system directory. Then if an uri match the specified regexp, a thumbnail is served by the middleware.

For example, with the default configuration, the url http://localhost/thumbs/100x100/image.png will render a thumbnail of /var/mapped_dir/image.png.

There is also a "size" uri parser to use named size and prevent potential DoS attacks.

That what i'm using here, for my blog. I have two size: blog (490x490) and large (750x750). Here the Paste configuration:

[app:thumbs]
use = egg:iw.thumbs
url_regexp = ^/(?P<size>%s)(?P<path>/.+)
url_parser = iw.thumbs.url:size_parser
image_dir = %(here)s/var/rst/images
cache_dir = %(here)s/data/thumbs
sizes =
    blog = 490x490
    large = 750x750

As you can see, the package also provide an application factory in case of you just want to math a specific prefix.

Then I just have to map it in my url mapper section:

[app:main]
use = egg:Paste#urlmap
/thumbs = thumbs
/ = pylons # my pylons application

Another middleware exist to generate thumbnail with a different approach. repoze.bitblt allow you to generate thumbnail from the size specified in your image tag. It also add a secure part to the image url to prevent DoS attacks. I think both package have their place.

What I like with iw.thumbs is that I only need to change a configuration parameter instead of all image tags if the width of my blog column change in the future. The other good point is that you can generate image tags on the client side wich seems not really possible with repoze.bitblt.

But well, both middleware are another good reason to use WSGI applications.

And as an example, here is Alain, the AFPy mascot render with the blog size. If you click on it, you'll get the large size in a popup.

/thumbs/blog/alain_at_rennes.jpg

Novembre 9, 2008
» How to receive email alerts when someone talks about something - 6 steps tutorial using Atomisator


I like Google Alert, the idea of receiving a mail every day that summarizes all articles related to a given topic is really helpfull when you need to focus on a specific subject for a while.

But this is not enough. I want to receive a mail that points me to any mailing list or planet feed or blogs out there as well, that talks about the topic.

You can’t do it with Google Alerts as far as I know.

Let’s take an example:

I want to receive a daily mail that points me to any mail thread or blog entry, that is related to the word “buildout” or to the word “pycon”.

Basically, to do it manually, I need to read Planet Python, Planet Zope, then take a look at the Python, Zope and Plone mailing lists. It takes at least 10 minutes, and more if you want to read all entries to make sure you won’t miss anything.

Since online systems like Nabble provides RSS feed for mailing lists (don’t find yours ? just add it there !), it is easy to read them as they where regular feeds.

From there, a script that reads all the selected feeds and sends a mail pointing to the entries that match the selected words is simple to write as well, and fill the need.

But don’t code it : Atomisator will let you do this with a few lines of configuration.

Here’s a step-by-step tutorial.

Step 1 - install easy_install

Step 2 - install Atomisator and SQLite

Step 3 - create an “atomisator.cfg” file

The content of the file has to be:

[atomisator]
store-entries = false

sources =
  rss http://www.nabble.com/Python---python-list-f2962.xml
  rss http://n2.nabble.com/Plone-f293351.xml
  rss http://www.nabble.com/Zope---General-f6715.xml
  rss http://planet.python.org/rss10.xml
  rss http://www.zope.org/Planet/planet_rss10.xml
filters =
  buzzwords words.txt
outputs =
  email email.cfg

This file will look into Planet Python, Planet Zope and various mailing lists (Python, Plone, Zope). Of course you can add or remove feeds in the sources option.

Step 4 - Create the words.txt file

This file contains regular expressions, one per line, that will be used to match the entries. The file has to be saved besides atomisator.cfg.

For our example:

buildout
pycon

You can put any expression you want in this file, as long as you have one matching expression per line.

Step 5 - add an email.cfg configuration file.

This is where you define the target emails that will receive the alerts (tos option). You can also specify the from email, or the smtp server location. The file has to be saved besides atomisator.cfg.

In our case it can be:

[email]
tos = tarek@ziade.org
from = tarek@ziade.org
smtp_server = smtp.neuf.fr

Step 6 - Run it !

The command to be called is atomisator (installed by easy_install) followed by the configuration file:

$ atomisator atomisator.cfg
Reading data.
Launching worker for rss - ('http://www.nabble.com/Python---python-list-f2962.xml',)
Launching worker for rss - ('http://n2.nabble.com/Plone-f293351.xml',)
Launching worker for rss - ('http://www.nabble.com/Zope---General-f6715.xml',)
Launching worker for rss - ('http://planet.python.org/rss10.xml',)
Launching worker for rss - ('http://www.zope.org/Planet/planet_rss10.xml',)
Retrieving from rss - ('http://www.nabble.com/Python---python-list-f2962.xml',)
Retrieving from rss - ('http://www.nabble.com/Zope---General-f6715.xml',)
Retrieving from rss - ('http://n2.nabble.com/Plone-f293351.xml',)
Retrieving from rss - ('http://planet.python.org/rss10.xml',)
Retrieving from rss - ('http://www.zope.org/Planet/planet_rss10.xml',)
.................................................................................................................................................
Writing outputs.
Data ready.

Check your mails. This call can be put in a daily cron.

Tested under Mac OS X and Linux.

      

Novembre 8, 2008
» Promoting Python and Plone in Africa


It seems that only South Africa had an event listed as part of the World Plone Day set of local events. As an african, I am of course interested by this fact, and I would have expected some Plone presence in another region. Hopefully, we can fix that for next year’s edition !

I am promoting an effort called Python African Tour which aims at sending volunteers, within the next couple of years, in the different regions of Africa, based on sponsoring, to train beginner developers there on Python and its related technologies. It’s a way to introduce newbies there to a programming language that helps the developer get his job done, as well as all the community practices that help us improve our daily work. It’s also a way to get new developers join the Python community.

The first country the tour will visit is Morocco, in December, from the 18th to the 22nd. Among the possible countries to plan in 2009 are Nigeria and South Africa. Obviously our plans will depend on discussions with local contacts we get, and sponsoring possibilities.

For Morocco, Amine Soulaymani, a developer living in Morocco, and Daniel Nouri have volunteered to participate as instructors for the students at Ecole Mohammedia d’Ingenieurs, ­the school that will host the Python training session.
In addition to the training session during the first 2 days, we plan to have 3 days of community activities: an unconference-style open event with demos and talks related to Python, followed by a sprint that will be hosted in the offices of Nextma, a solution provider doing Python. Talks and sprint activities should cover Plone, with the participation of a PloneGov / CommunesPlone team joining us from Belgium, WSGI / Repoze and ­OpenERP with contributors from Nextma.

On a side note, I have proposed a talk with Roberto Allende for next year’s Pycon to present our ideas and actions to help spread Python in both South America and Africa.

If you want to contribute in any way, ­­contact us through the project’s mailing list.

      

Novembre 6, 2008
» Plone Conference 2008 in Washington D.C. - summary


I am back from the Plone Conference in D.C., and the jetlag is gone. The jetlag is gone for weeks now but it’s hard to find the time to blog these days :/

On the talks I have seen and topics I have chatted about

There were a lot of great talks in D.C., and it was hard to decide which one to look at. In any case it was easy to meet the speaker if I had missed the talk, because the Plone Conference, unlike big conferences like OSCON, is a place where everyone hangs around the same spot after a talk is over.

Here’s a list of some topics I have seen or I have talked about with some people.

Deliverance - Ian Bicking

If you look at what Ian has produced in the past 5 years, he is one of the most prolific contributor of tools that become standards in the Python web development web community. Think about Python Paste or virtualenv, and many others. Deliverance might be the next big one.

Take a bunch of micro web applications you want to join to build a full web system, for historical reasons or just because you believe a particular feature just won’t fit in Plone but will do great in Pylons.

Now ask a designer to glue everything together under the same look. He (or the guy that integrates his design) will probably hates you: he will have to learn how to integrate in heterogeneous environments. This is easy under some systems that let you stick a layout and a css in a simple way. This is not easy under Plone, unless you learn how to do it (but this will be improved in the future).

Deliverance is a proxy that let you skin any application that spits html content, by running some XPATH rules on the content and applying some changes to produce a new output. Basically, you have a simple html page that just provides the layout you want to have, without any content, and a xml file that explains how to extract some content from the page produced by the third-party application and where to inject it in your empty html page. The great thing is that you can call different third-party servers given the path you are in, and even call several servers to build one single page. This opens a lot of perspectives.

The first caveat of this approach is that you have to provide a Single-Sign On feature to avoid people having to connect several times. This can be a problem sometimes with some applications if they are not open enough to let you do it. But most of the time, it is not a problem : if the users are all located in a LDAP it is easiy.

Furthermore, if you use only Python-based applications, you can use a WSGI envrionment and a middleware like repoze.who to glue together let’s say, a Plone app and a Pylons app. Products.oopas is the PAS plugin that can be used for that on Plone side to grab the authentication context and use it.

The second problem I can see is about response headers. One example: if a page is composed of elements that comes from several pages, and if the page has a Last-Modifier header, I don’t think Deliverance handles this correctly yet, to make sure to present the newest Last-Modified header from all third-party servers that where called to build that page. But this more likely to be a detail compared to the single authentication problem.

In any case this is a very promising tool !

Content Mirror - Kapil Thangavelu

I didn’t see that talk, but I have talked about this tool with a few people. The idea is to serialize the content of a Plone instance into a relational database (eg Postgresql), as it happens, using events.

I need to give a try and check it deeper, to see how the overhead is dealt, and how the aggregator I have read about is doing (it collects mirorring operations to perform in a transaction, and optimize the calls at the end of the transaction to avoid redudant calls if I understood correctly). I don’t know yet for example if there’s a pool of jobs for the mirroring tasks to avoid a point of failure. But I am pretty sure this is taking care of. The other point I need to see if there’s a round trip. e.g. if there’s a way to apply a relational database change back into Plone.

But in any case I can already see various use cases for my customers. For instance, having a plone instance as a back office, with complex workflows for editors and contributors, and a lightweight Pylons application as the front application, that concentrates into displaying the relational database as fast as possible, makes a lot of sense in big environments. It just scales better.

So this is a interesting tool as well.

repoze.bfg - Chris McDonough

Chris gave a talk about repoze.bfg, which is a new web framework that takes back the good bits from Zope and push them into a WSGI world, using the Pylons approach I would say. That is : “here’s the template engine you can use in repoze, but really, use the one you like”.

Frankly, I am really seeing this new effort as one of the most promising one in the Zope community. Already, repoze.auth is a major middleware in WSGI : Zope’s Pluggable Authentication Service outside Zope, usable with any WSGI application. This is a blast !

And people are starting to contribute a lot of interesting middlewares under the repoze namespace.

Now I didn’t really try repoze.bfg itself yet, but given the people that are behind it, I am pretty sure this framework will meet success in the future. Having a MVC framework ala Pylons that let you use Zope packages with a “this zope package is repoze/wsgi compliant” label on each one of them is very cool.

collective.indexing - Andreas Zeidler and al

At the snow sprint, we worked with the Enfold crew that did a great work in integrating the Solr/Lucene system so it can be used from Plone. We replaced a few fields like the searchable text and indexed it on Solr side, just to give it a try. The snow work was really focusing on providing a buildout, a few recipes and a bench to say : “Hey, Plone community, this is a blast ! let’s do more of it”

Later Andreas Zeidler and a few other guys continued the work on indexing matter and they delivered collective.indexing, which provides two things:

  • a queue that collects all indexing to be done, and optimize the call to the catalog
  • a bridge to use collective.solr

I didn’t follow the latest development and I didn’t know how far the guys went, but I had the chance to hang around with Andreas and Tom Lazar in D.C., so now I know that this package is production ready :D

So in other words : I’ll probably use it as a mandatory package for all the big plones out there.

The queuing part imho, should go into the catalog itself because there’s no other way to make sure a third-party product is not calling the catalog during the transaction wile another product does the same.

Server-Side Include (SSI)

Tom Lazar worked during the Snow Sprint on lovely.remoteinclude to make Plone portlets accessible via unique URLs. From there, it is possible to push a page that contains a list of urls rather than the calculated page, to a front server that knows how to read SSI directive, and builds the page.

This is great for performances, and is a lot like ESI (Edge Side Include) we use to have in CPSSkins.

I am wondering if both could be implemented in the same tool in fact.

Tom told me that he will try to continue this work at the performance sprint in Bristol in december, so let’s keep an eye on this !

I have seen many other talks and topics, but these few ones where the ones I really needed to talk about.

On the conference organization

I am helping in the organization of Pycon FR in Paris since 2 years now. I know what is means to organize such events : it is a LOT OF WORK.

You know when an event is well organized when you don’t feel it is organized.

That was the case in D.C. Bravo Alex, Amy and all the others !

The only problem (wifi) was not the organizers fault, and I have never been to any event where it is not cahotic at some point (besides OSCON) so… :)

On the community

I love you all guys. It is an amazing community.

      

Novembre 3, 2008
Gael Pasgrimaud
gawel
Gawel's blurb
» Wonderful world of WSGI

This time it's really winter. When it's cold the only thing i like is geeking at home. So I decide to rewrite my website with a set of WSGI applications.

The first thing done was to initialize a Pylons project for my blog. I got something working after a few hours. Pylons really speed developments.

Then I need a skin. I decide to give a try to Deliverance. Skinning with Deliverance is quite easy. After reading the docs, I've create a layout based on my old html code and a set of rules. Add this to my configuration file:

[filter:deliverance]
use = egg:Deliverance
theme_uri = file:///%(here)s/themes/layout.html
rule_uri = file:///%(here)s/themes/rules.xml

That's it. My Pylons app looks good without any style sheet as you can see ;)

Another part of my website is my projects documentations which are generated by Sphinx and served by a static app. Those pages are now skinned with Deliverance and you can't really know that you browse another application.

I also use Trac to browse my svn repository so I've try to put it in my WSGI stack. Trac now support WSGI except that it do something strange with the output and/or stderr so you'd better not using an error middleware with it else you get a beautiful blank page. You can create a WSGI application with a few lines of code:

# -*- coding: utf-8 -*-
import os
from trac.web.main import dispatch_request
def make_trac(conf, trac_env):
    def application(environ, start_request):
        environ['trac.env_path'] = trac_env
        return dispatch_request(environ, start_request)
    return application

and skin it with Deliverance. Notice that in my case, Trac seems inserting different encoding in the same page so I need to hack it a bit.

The last thing done is to use a ProxyApp to serve and skin my buildbot. Of course, this part is also skinned with Deliverance.

I now have only one process to serve all my python apps so I can use repoze.who to manage authentication for all apps. I have a ldap server, so I've write a small plugin for it. This work perfect, and I'm now able to log in Pylons and Trac.

I'm using Deliverance as a WSGI middleware and it seems a bit different than when you use it as a proxy. I encounter a few bugs. I have to only use XPath to find nodes in the DOM. Other expressions just don't work. You also can't remove nodes. But, well, this seems promising.

Octobre 29, 2008
» PloneConf’08 slides + screencasts : delivering applications with zc.buildout and a distributed model


I was totally drowned into some customer projects since I came back from the Plone Conference. But things are looking better now, so I can take a bit of time to start blogging about the conference. I’ll probably do three blog posts: this one about my tutorial, the next one about the conference itself and last, an entry about the sprints.

So I gave a tutorial about zc.buildout. The length was a bit challenging, since I had 90 minutes. Enough time to explain more things than in a regular talk, but not enough time to get into great details, as a tutorial should be.

The other thing was about the topic: two talks were covering zc.buildout, Clayton Parker’s one and mine. So my goal was to make sure they were not overlapping too much.

I had the chance to meet Clayton before we both gave our talk, since the Six Feet Up crew gave me shelter in the house they rented (nicest guys in the block). Even if we didn’t exchange a lot on the slides themselves, I could figure what Clayton was going to present. So I…. started my slides from scratch two days before my tutorial and worked carefully on their scope :D

Alex Clark came and backed me up during the talk, since we are working together one plone.org for months now and since the talk presented the new plone.org that is coming up.

I think I did quite well during the talk, because we had a pause half way, and when we started back, the room stayed full ;)

This is the second time I record all the console work in small screencasts, to avoid live problems, and I think this is the best way to go if you need to do some demos, so I’ll keep on doing it. Plus, it’s nice to provide them to people after the talk.

Anyway, the talk was videotaped so you can to judge by yourself:

And everytime you see a “get the screencast at http://ziade.org/ploneconf” in there, well get them :)

In detail:

  1. Distutils demo
  2. setuptools demo
  3. collective.eggproxy demo
  4. PloneSoftwareCenter installation
  5. collective.dist demo
  6. new.plone.org demo
  7. collective.releaser demo
  8. plone 3 buildout demo
  9. Multiple target releasing demo

What’s next ?

  • We need to finish the work with Alex on plone.org. It’s not hard, it just takes time, and we both are quit busy in our jobs :)
  • I need to polish collective.releaser and collective.eggproxy. They are brut de fonderie, and the code suck a bit. If you are using them and want to help, or have some feedback/issues, please, pretty please, let me know.
      

Octobre 21, 2008
» 3 Colors Theme : a collective phantasy based theme


Since Plone base properties style could seems too rich for a standard use case, phantasy skin edit forms could be also too complex.

When i saw how easy it is to change some skin properties in a blog system like word press ( …),  i thought we need the same feature in Plone.

Collective Phantasy is done for that.

Building a new skin product with a standard static theme and a customized skin schema is something you can do easily with collective phantasy.

If you want an example, just test the “3 colors theme” plone product.

In your buildout :

in instance eggs section add :

    collective.threecolorstheme

in zcml section add :

    collective.threecolorstheme
    collective.threecolorstheme-overrides

Relaunch your buildout.
Launch your zope instance.

In plone_control_panel you will get :

Check for “Three Colors Theme” Product, this will install the product and its dependencies :

Go back to the home page, of course the “static” theme has changed (my poor contribution to plone themes community)

We want to change the dynamic properties, so we click on “Contents” tab, and we can see that everybody is here : the dynamic root skin for portal, and the phantasy skins repository (read previous posts …) :

We want to build a new skin, so as we have seen in previous posts, in phantasy skins repository we add a new skin :

In this form you could see differences with a classic phantasy skin form (for developpers/integrators look at the code it’s just some easy Archetypes bidouille) :

- 3 colors only + mutators to change all colors

- an entire fieldset removed

- many fields unuseful in this theme are hidden

- some skin attributes added in schema

Go back to reality : just change some colors

Now we will import a skin sample provided in “three colors theme product”.

In alternate_skin folder you will find a zip file and a txt file (howtouseit.txt).

Click on “import images and files”, choose the alternate_skin.zip file

Read howtouseit.txt and change some colors or properties

Use plone kss power to change images’ names quickly

CTRL-F5 to refresh the page, of course you need some design feeling to understand what’s happen here, but it’s not so complicated (…)

In the product you will find another example with another howtouseit.txt, here, then just add a folder and choose the good phantasy skin and you will get :

Loving Plone :-)

      

Octobre 16, 2008
Bertrand Mathieu
bertrand
Paste here is about »
» How to change add permision of another product content

In a customer project I have had to use CalendarX. CalendarX uses "Add portal content" for content add permission. But they wanted that only "Manager" be able to add a calendar. I could have gone straightforward by overriding "getNotAddableTypes" script in portal_skins, but I chose to try to patch the product from mine (let's call it "my.product").

I first tried to import CalendarX and change the permission name with a simple monkey patch, but I immediately had to dig into zope initialization process: "my.product" is imported after Products.CalendarX, because "my.product" gets loaded by Products.Five initialisation, and Five is loaded after CalendarX.. so my patch arrives too late in the init process. What to do? try harder! I found I could reload the product after having patched the permission.

Honestly I don't know if it can raise issue, and I would prefer something that looks less "hacky", but...
So, here is the guilty code!

# this is my/product/__init__.py
import logging
LOG = logging.getLogger(__name__)

def initialize(context):
"""Initializer called when used as a Zope 2 product."""

from Products import CalendarX
cxf_perm = "%s: Add CalendarX content" % (PROJECT_NAME,)
setDefaultRoles(cxf_perm, ('Manager',))
CalendarX.DEFAULT_ADD_CONTENT_PERMISSION = cxf_perm
CalendarX.config.DEFAULT_ADD_CONTENT_PERMISSION = cxf_perm

# also patch this, else it will try to register the profile twice
# and the registry will complain
from Products.GenericSetup.registry import ProfileRegistry
dummy_registry = ProfileRegistry()
std_registry = CalendarX.profile_registry
CalendarX.profile_registry = dummy_registry

# FIXME: is there anything cleaner to get app?
app = context._ProductContext__app
from OFS import Application
Application.reinstall_product(app, 'CalendarX')
CalendarX.profile_registry = std_registry
LOG.info("patched CalendarX.DEFAULT_ADD_CONTENT_PERMISSION: use '%s'"
% cxf_perm)

Octobre 13, 2008
» Using Collective phantasy with another plone theme product


When installing collective phantasy it will takes its skin properties from the current available plone theme.

You could see in screenshots below a customization of qPloneSkinWhiteBlack plone theme, using phantasy :

      

» Collective Phantasy


Today we will work on skinning Plone, you will see how easy it is, especially when using collective.phantasy.

This product is only plone3.1.x (and perhaps ++) compliant.

I suppose you know how to build a new plone instance using buildout. I know it’s not always so easy for Windows users, but keep cool, read documentations about buildout (it’s a really powerful feature), and send a comment here if you get problems with this question, i will try to help you .

So, in your plone3.1.x buildout.cfg, just add these two lines : In instance - eggs sections :

    collective.phantasy

In instance -zcml section :

    collective.phantasy

Now you could launch your buildout :

    bin/buildout -vvv

Then launch your Plone instance.

    bin/instance start

OK.

Install collective.phantasy in Plone

Go on your plone site > Add/Remove Products You will get this screen :

Check for “Collective Phantasy” product and Save the form.

This will install “Collective Phantasy” product and its dependency “Smart Color Widget” :

The portal look is changed, but it’s just an example, not the best wonderful design ever seen ;-),
so we will change it.

Change the portal skin

Go to your portal root, click on Contents :

You will get two new items :

- An Item called “Phantasy Skin repository”, it’s a folder containing alternate skins for folders

- An item called “Plone’s logo, colors and border defaults”, it’s the dynamic skin used for your portal, you can delete it and recreate it, but now we will just change it click on this item,
then click on “edit” tab

Click on “Colors” tab, change the background color value for “#f3f3fb” :

And save the form, here is the result :

Re-click on edit tabs, then on “dimensions” tab,

change the values for ‘portal width’ and “Portal horizontal position” like this :

And save the form :

hmm it’s better but we will do some new things.

First we will add our logo.

Go back to your skin, use the contextual menu : “Add new…”, choose “Skin Image” :

Click on Browse (”Parcourir” in french ), choose your logo image on your HD :

Save the form. Go Back to your skin.

We will change the logo name in skin. Click on edit tab, then on “images” sub-tab.

Change the logo name value for “logo.gif” (the image id you’ve just uploaded), and save the form.

Here is the result :

Go back to your portal home page and refresh the page, CTRL-F5. If you want to see the left column as shown in next image you also need to change the portlet navigation property with “Manage portlets” …) :

Setting a new skin and choose this skin for a particular folder

See global tabs at top, Click on “Folder with other skin”

You see that the portal look is changed here. Ok. Go back to the Phantasy Skins Repository, click on Contents, you see here alternate skins which can be used by any folder :

Click on the only skin present here :

Oh, oh … the same look as we’ve seen somewhere before.

OK, now we will change everything, go back to the portal root > Contents tab, select the dynamic root skin and click on “copy”. :

Go back to the Phantasy Skins Repository, and click on “Paste” :

We will rename this skin, it could be practice, check the second skin and click on “rename” :

Then click on this skin to go on it. Now we will do always the same thing, click on “edit” and change background color, but take care because now the color value must cohabit with a future background image (use Firebug extension to help you) :

Create a css for your skin

Now we will do something special that’s not embed in Phantasy skin parameters. Edit a text file, save it on your HD as a a css file, here we call it “ornicat.css”, we add a little new selector in this css, this selector add

a large left violet border to the page :

Create some images used by your skin

We create a global background image which can cohabit with the background color, using Photoshop or any picture dedicated software (we save it on local disk as “portal-background.gif”) :

We create a new logo with the same software (we save it as “logo-2.gif”) :

Post all these files in your skin

Create a zip archive with the 3 precedent files :

Go back to your browser, to your site and to your skin, click on “Import images and files” :

Click on “browse”, choose your zip file on your local disk.

Click on import, wait during upload …

Upload is done

Setting up your special skin

Click on “Edit” tab, enter the css file id (ornicart.css here)

Click on “images” sub tab

- Change the logo name for the new logo id (logo-2.gif)

- add a body background image name with your background image id posted first (portal-background.jpg)

- change background image position for “Top right”

- change background image repeat for “Vertcal repeat”

- Save the form

Here is the result

Ah, i think it’s better

Give a folder a new skin

Go to “Folder with another skin”, click on Edit, Below Phantasy skin, click on “Add”, now you can browse the site for a new skin, Choose the “Alternate skin” we’ve made before.

Save the form Click on CTRL-F5 to refresh the page.

Now you can say “Skinning Plone is not so complex”. :-)

      

Octobre 11, 2008