Re: Good form library for pyramid ? Better doing it by hand ?

1,101 views
Skip to first unread message

Malthe Borch

unread,
Dec 6, 2012, 4:35:57 AM12/6/12
to pylons-...@googlegroups.com
Hey Nicolas,

I had a realization at some point that form libraries ultimately
aren't a joy to work with.

Instead, I wrote `repoze.formapi` (see docs at http://docs.repoze.org/formapi/).

It basically just helps you validate input and help with error
reporting, but it doesn't know about HTML at all – you simply write
your own.

For instance, in my application we have a page type which is basically
just a document:

The "page form" template (written in Chameleon's page template language):

http://pastie.org/5487945

The `form` variable in here is a `repoze.formapi.Form` object.

The markup is based on Twitter's Bootstrap.

Note that there's a bit of Javascript in there which automatically
generates and displays a human-readable URL fragment id based on the
provided page title.

The template also demonstrates how to set up a simple checkbox.

\malthe

On 6 December 2012 10:27, Nicolas Di Pietro
<nicolas....@icareweb.com> wrote:
> Hi All,
>
> I'm pretty new in the Pyramid world and still in the learning process.
>
> My question is about the forms generation and validation libraries, is there
> a really good one usable with Pyramid AND with good documentation ? For the
> few last days, I was trying pretty hard to have something working with some
> of those libraries but I'm at the point where nothing works like I would
> like.
>
> I've tried Deform but I really have problems with the errors, I mean, I find
> pretty hard to define customized error messages, i.e., you want to generate
> a login page, this login page must be able to display an error message above
> the box if the user/password combination is not valid (or another error is
> occuring). It's pretty easy to get rid of the huge box above the form (There
> was a problem with your submission, Errors have been highlighted
> below)(changing the template used), but I'm not able to replace this box by
> a customized error message that can depend of the error (and keeping also
> the individual messages for each field (i.e: Required) or changing easily
> those individual error messages.
>
> I've also tried the ToscaWidget2 Lib, the problem I had with this one are:
> I'm not able to use the i18n, I'm not able to get the tooltips on the fields
> and the doc is not very very useful (or complete :'( )
>
> I've also tried another one (don't remember, I think it was WTForms) but if
> I remember well, I had problems also with the i18n.
>
> So, as I'm loosing a lot of time (let's say about 3-4 days) trying the
> different libraries, reading the docs, reading the sources (i.e., trying to
> understand what are the possible parameters for TW2 widgets), and not having
> exactly what I want, I ask to the list, do you know about a form generation
> and validation lib, with support for i18n, easy error customization, and
> ability to use all (or almost all) html attributes (i.e. the title attribute
> to have tooltips in recent browsers).
>
> If some of you don't use at all such a library, do you have a good pointer
> to resources to validate input in a safe and clean way by hand ?
>
> Thank a lot for your comments and ideas.
>
> Have a nice day,
>
> Nicolas
>
> PS: maybe I missed the features of deform and tw2 (and WTForms), I'm sorry
> if I offense the different authors of those libs and even if what I
> want/need is not in their libs, I want to say thanks for each bit of the
> open-source ecosystem.
>
> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/pylons-discuss/-/sXm8e2r1R-IJ.
> To post to this group, send email to pylons-...@googlegroups.com.
> To unsubscribe from this group, send email to
> pylons-discus...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/pylons-discuss?hl=en.



--
Au revoir, et tous mes voeux pour un avenir plein de succès et de bonheur ––

Malthe Borch
mbo...@gmail.com

Chris Lambacher

unread,
Dec 6, 2012, 1:18:32 PM12/6/12
to pylons-...@googlegroups.com
Hi Nicolas,

pyramid_simpleform ties together webhelpers and FormEncode. It gives good separation between form generation and form validation and also a structured way to deal the any errors that occur. I currently use this setup with French/English bilingual sites and tere is a well defined and easy way to override the messages if you don't like the default messages on the validators.

-Chris


On Thu, Dec 6, 2012 at 4:27 AM, Nicolas Di Pietro <nicolas....@icareweb.com> wrote:
Hi All,

I'm pretty new in the Pyramid world and still in the learning process.

My question is about the forms generation and validation libraries, is there a really good one usable with Pyramid AND with good documentation ? For the few last days, I was trying pretty hard to have something working with some of those libraries but I'm at the point where nothing works like I would like.

I've tried Deform but I really have problems with the errors, I mean, I find pretty hard to define customized error messages, i.e., you want to generate a login page, this login page must be able to display an error message above the box if the user/password combination is not valid (or another error is occuring). It's pretty easy to get rid of the huge box above the form (There was a problem with your submission, Errors have been highlighted below)(changing the template used), but I'm not able to replace this box by a customized error message that can depend of the error (and keeping also the individual messages for each field (i.e: Required) or changing easily those individual error messages.

I've also tried the ToscaWidget2 Lib, the problem I had with this one are: I'm not able to use the i18n, I'm not able to get the tooltips on the fields and the doc is not very very useful (or complete :'( )

I've also tried another one (don't remember, I think it was WTForms) but if I remember well, I had problems also with the i18n.

So, as I'm loosing a lot of time (let's say about 3-4 days) trying the different libraries, reading the docs, reading the sources (i.e., trying to understand what are the possible parameters for TW2 widgets), and not having exactly what I want, I ask to the list, do you know about a form generation and validation lib, with support for i18n, easy error customization, and ability to use all (or almost all) html attributes (i.e. the title attribute to have tooltips in recent browsers).

If some of you don't use at all such a library, do you have a good pointer to resources to validate input in a safe and clean way by hand ?

Thank a lot for your comments and ideas.

Have a nice day,

Nicolas

PS: maybe I missed the features of deform and tw2 (and WTForms), I'm sorry if I offense the different authors of those libs and even if what I want/need is not in their libs, I want to say thanks for each bit of the open-source ecosystem.

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pylons-discuss/-/sXm8e2r1R-IJ.
To post to this group, send email to pylons-...@googlegroups.com.
To unsubscribe from this group, send email to pylons-discus...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.



--
Christopher Lambacher
ch...@kateandchris.net

Christian Ledermann

unread,
Dec 6, 2012, 5:08:18 AM12/6/12
to pylons-...@googlegroups.com
sound nice I give it a try :)
Best Regards,

Christian Ledermann

Nairobi - Kenya
Mobile : +254 702978914

<*)))>{

If you save the living environment, the biodiversity that we have left,
you will also automatically save the physical environment, too. But If
you only save the physical environment, you will ultimately lose both.

1) Don’t drive species to extinction

2) Don’t destroy a habitat that species rely on.

3) Don’t change the climate in ways that will result in the above.

}<(((*>

ian marcinkowski

unread,
Dec 6, 2012, 1:31:49 PM12/6/12
to pylons-...@googlegroups.com
The project I spend most of my time working on uses a combination of
FormEncode and custom Mako template widgets for rendering the fields.
We are using SQLAlchemy as our ORM, so we also use FormAlchemy for
most simple (and some not-so-simple) database updates.

FormEncode allows you to define schemas:

from formencode.validators import Int, StringBool, String, Email
from formencode import ForEach
from formencode.compound import All
from formencode import Schema

class SimpleFormSchema(Schema):
name = String(max=20, not_empty=True)
enabled = StringBool(not_empty=True)
count = Int()

You can also do some really cool things with nested schemas. Say you
have a Person and a Contact, you could validate the list of Contacts a
person has something like this:

class PersonSchema(Schema):
pre_validators = [formencode.variabledecode.NestedVariables()]

name = String(min=3, not_empty=True)
email = Email()
address_book = ForEach(ContactSchema())

class ContactSchema(Schema):
name = String(min=3, not_empty=True)
email = Email()

The pre_validators run on the Request parameters before validation
begins. the NestedVariables pre_validator will compile parameters
such as address_book-0-name, address_book-0-email in to a list of
dictionaries:
address_book = [{'name': 'John Smith', 'email': 'jsm...@example.com'},]

In your template you could then use WebHelpers to construct your HTML
fields, or create your own template widgets for convenience.

FormAlchemy is nice because it does most of this work for you by
binding a 'FieldSet' to a model and allowing you to call .render() on
the FieldSet in your template to generate a form. You can also
override the default templates that are used by FormAlchemy to fit in
with the markup of your application.

I could go in to a lot more detail, but the docs are pretty good.
Ian Marcinkowski
ianmarc...@gmail.com

appetito

unread,
Dec 7, 2012, 10:04:25 AM12/7/12
to pylons-...@googlegroups.com
strongly advise WTForms. IMHO it's flexible and powerfull, can generate forms for SQLAlchemy models, can work with JSON request data (via wtforms_json), well documented, small readable code base (if docs miss), and have no i18n problem for me.

Mike Orr

unread,
Dec 7, 2012, 12:41:53 PM12/7/12
to pylons-...@googlegroups.com
I was interested in  Malte's description of 'formapi' so I looked at the docs. It looks like it covers part of FormEncode's scope but with a significantly simpler API. The only concern that struck me is it seems you're on your own for redisplaying the form if the validation fails, and that means exporting the input values back to HTML and placing the error messages. Also, if you have a composite data structure (e.g., the form has one or more address sections which go into address objects, you have to (un)flatten it to HTML yourself. These are all things FormEncode/pyramid_simpleform has built-in. So, FormEncode's API is not the most streamlined and the docs are a bit obtuse, but it *has* been widely used for several years so it's pretty stable and well known if you find anything you need help with.


On Fri, Dec 7, 2012 at 7:04 AM, appetito <_yu...@inbox.ru> wrote:
strongly advise WTForms. IMHO it's flexible and powerfull, can generate forms for SQLAlchemy models, can work with JSON request data (via wtforms_json), well documented, small readable code base (if docs miss), and have no i18n problem for me.

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pylons-discuss/-/-Db3O8yR9QcJ.

To post to this group, send email to pylons-...@googlegroups.com.
To unsubscribe from this group, send email to pylons-discus...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.



--
Mike Orr <slugg...@gmail.com>

Nikolay Kim

unread,
Dec 10, 2012, 1:54:38 PM12/10/12
to pylons-...@googlegroups.com
Nicolas,

You can try this form library https://github.com/fafhrd91/pform
it doesnt have much doc yet, but you can check example. I use it in my company.


On Dec 6, 2012, at 1:27 AM, Nicolas Di Pietro <nicolas....@icareweb.com> wrote:

Hi All,

I'm pretty new in the Pyramid world and still in the learning process.

My question is about the forms generation and validation libraries, is there a really good one usable with Pyramid AND with good documentation ? For the few last days, I was trying pretty hard to have something working with some of those libraries but I'm at the point where nothing works like I would like.

I've tried Deform but I really have problems with the errors, I mean, I find pretty hard to define customized error messages, i.e., you want to generate a login page, this login page must be able to display an error message above the box if the user/password combination is not valid (or another error is occuring). It's pretty easy to get rid of the huge box above the form (There was a problem with your submission, Errors have been highlighted below)(changing the template used), but I'm not able to replace this box by a customized error message that can depend of the error (and keeping also the individual messages for each field (i.e: Required) or changing easily those individual error messages.

I've also tried the ToscaWidget2 Lib, the problem I had with this one are: I'm not able to use the i18n, I'm not able to get the tooltips on the fields and the doc is not very very useful (or complete :'( )

I've also tried another one (don't remember, I think it was WTForms) but if I remember well, I had problems also with the i18n.

So, as I'm loosing a lot of time (let's say about 3-4 days) trying the different libraries, reading the docs, reading the sources (i.e., trying to understand what are the possible parameters for TW2 widgets), and not having exactly what I want, I ask to the list, do you know about a form generation and validation lib, with support for i18n, easy error customization, and ability to use all (or almost all) html attributes (i.e. the title attribute to have tooltips in recent browsers).

If some of you don't use at all such a library, do you have a good pointer to resources to validate input in a safe and clean way by hand ?

Thank a lot for your comments and ideas.

Have a nice day,

Nicolas

PS: maybe I missed the features of deform and tw2 (and WTForms), I'm sorry if I offense the different authors of those libs and even if what I want/need is not in their libs, I want to say thanks for each bit of the open-source ecosystem.


--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pylons-discuss/-/sXm8e2r1R-IJ.

Whit Morriss

unread,
Dec 10, 2012, 3:31:47 PM12/10/12
to <pylons-discuss@googlegroups.com>
man, someone would get a beer from me if they wrote up and maintained a web form in python shootout page.

-whit

On Dec 10, 2012, at 12:54 PM, Nikolay Kim <fafh...@gmail.com>
 wrote:

Nicolas Di Pietro

unread,
Dec 11, 2012, 10:59:09 AM12/11/12
to pylons-...@googlegroups.com
Hi Chris,

I've tried pyramid_simpleform and it seems to be good but I was not able to get the i18n working (and the doc here http://packages.python.org/pyramid_simpleform/#localization-and-state is not very very specific) I've set the _ method in a State object without any good result.

If I can get it working, I will try to customize the messages but I'm a bit concerned about the developpement of pyramid_simpleform since the dev sounds stopped for more than one year and it was in the process of moving from formencode to colander. I mean, if all the dev I've to do today (at least 4 projects) use i.e. formencode and simple_form and tommorow the dev start again and go with colander... ;-) (in fact, the dev will restart and use colander IF and ONLY IF, i choose to use it with formencode :-D )

Thank you for your answer

PS: also tried this without success; http://stackoverflow.com/questions/10681181/how-to-work-on-internationalization-of-pyramid-forms

Nicolas Di Pietro

unread,
Dec 11, 2012, 11:03:16 AM12/11/12
to pylons-...@googlegroups.com
Hi Jensens,

This sounds nice, but, reading the doc (a bit fast, I've to admit) it sounds like to define new widgets, you have to define it using YAML, right ?

Thank you for your previews answer

Regards, Nicolas

Le vendredi 7 décembre 2012 16:48:45 UTC+1, Jens W. Klein a écrit :
Anyway, not that popular yet, but I recommend to use YAFOWIL for forms in pyramid. Ok, I'am biased, because I'am one of the authors.

Include the yafowil.webob and yafowil.bootstrap packages and get started. Dcumentation and live-example are at http://yafowil.info

Example registration form here: http://pastebin.com/GFqrZj0r

template has to have i.e.

        <div class="row">
            <div class="span12">
               <h1>Register</h1>
               ${structure: view.form()}                  
        </div>

Questions? Just ask. I try to help.

regards Jensens

Jonathan Vanasco

unread,
Dec 11, 2012, 12:07:55 PM12/11/12
to pylons-...@googlegroups.com

On Thursday, December 6, 2012 4:35:57 AM UTC-5, malthe wrote:
Hey Nicolas,

I had a realization at some point that form libraries ultimately
aren't a joy to work with.

Instead, I wrote `repoze.formapi` (see docs at http://docs.repoze.org/formapi/).


I did something similar.

I wrote pyramid_formencode_classic, which mimics the pylons formencode implementation but is much simpler


it doesn't do the form generation, but it will 'reprint' a form on failure.

for the form generation, i just use mako functions

in /-partials/forms.py  i have things like:

    def form_textarea_a
    def form_textfield_a

( 'a' denotes the style )

then when rendering the forms, my templates look like (in psuedocode):

   include /-partials/forms.py as t_forms   
   <form action="/path">
      t_form.form_textfield_a('name',request.form.name)
      t_form.form_textfield_a('email',request.form.email)
   </form>

i wanted the form styles to be mako defs, because it centralizes them but also moves them in the source tree to the templates section.  with a lot of the widget based form solutions, team members who shouldn't be touching backend stuff will need to touch backend stuff.  

Arndt Droullier

unread,
Dec 11, 2012, 1:21:48 PM12/11/12
to Pyramid on google groups
Forms have the nasty habit to connect to everything from css styling to your data model and application logic.
And most libraries do this by defining their own scheme: 

- So the first thing you have to do is to write a wrapper and adapt the form scheme to your application...
- Second: find the right places to customize the library, templates, validators 
- Third: if you need more than standard forms and still haven't quit -> You end up with your own form library! 
(and yes, I have one too)  

Honestly, I think the easiest and fastest way is to use a validation and serialization library like colander to handle
the server side processing and manually build the form in html/ templates. The good thing is you can 
simply toss in any jquery form/input field modules and build the form just the way you need it. 

Well, you will have the form fields listed twice, in the template and the validation/serialization function, but
if you don't have too many forms this approach is still easier and faster than handling a form library.

Arndt. 


2012/12/11 Jonathan Vanasco <jvan...@gmail.com>

--
DV Electric / Arndt Droullier / Nive cms cms.nive.co

Joe Dallago

unread,
Dec 11, 2012, 1:25:56 PM12/11/12
to pylons-...@googlegroups.com
I don't think it's been mentioned yet, but I use colander(https://github.com/Pylons/colander).  If form helpers are what you seek, then you can use Deform instead(built on top of colander).  I just like to write my forms manually, and validate the POST data sent to the server with my colander schemas.

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pylons-discuss/-/ZGZ6LdvGvaMJ.

Chris Withers

unread,
Dec 11, 2012, 1:35:06 PM12/11/12
to pylons-...@googlegroups.com, Nicolas Di Pietro
I'm surprised no-one mentioned deform yet... why is that?

http://docs.pylonsproject.org/projects/deform/en/latest/index.html

Chris
> --
> You received this message because you are subscribed to the Google
> Groups "pylons-discuss" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/pylons-discuss/-/sXm8e2r1R-IJ.
> To post to this group, send email to pylons-...@googlegroups.com.
> To unsubscribe from this group, send email to
> pylons-discus...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/pylons-discuss?hl=en.
>
> ______________________________________________________________________
> This email has been scanned by the Symantec Email Security.cloud service.
> For more information please visit http://www.symanteccloud.com
> ______________________________________________________________________

--
Simplistix - Content Management, Batch Processing & Python Consulting
- http://www.simplistix.co.uk

Chris Lambacher

unread,
Dec 11, 2012, 1:52:36 PM12/11/12
to pylons-...@googlegroups.com
Hi Nicolas,

My answers are below.


On Tue, Dec 11, 2012 at 10:59 AM, Nicolas Di Pietro <nicolas....@icareweb.com> wrote:
Hi Chris,

I've tried pyramid_simpleform and it seems to be good but I was not able to get the i18n working (and the doc here http://packages.python.org/pyramid_simpleform/#localization-and-state is not very very specific) I've set the _ method in a State object without any good result.

Does i18n work for the rest of your app? I am trying to figure out where I tell the app about FormEncode's LC_MESSAGES directory but I don't see it. I'll have to look deeper.

I invoke the Form object like:
form = Form(request, state=State(_=request.translate, request=request))


If I can get it working, I will try to customize the messages but I'm a bit concerned about the developpement of pyramid_simpleform since the dev sounds stopped for more than one year and it was in the process of moving from formencode to colander. I mean, if all the dev I've to do today (at least 4 projects) use i.e. formencode and simple_form and tommorow the dev start again and go with colander... ;-) (in fact, the dev will restart and use colander IF and ONLY IF, i choose to use it with formencode :-D )
 
I highly doubt that the maintainer is going to move to colander, since I am now the maintainer of both simpleform and FormEncode.

-Chris
 
To view this discussion on the web visit https://groups.google.com/d/msg/pylons-discuss/-/4HP4hBG4XmUJ.

To post to this group, send email to pylons-...@googlegroups.com.
To unsubscribe from this group, send email to pylons-discus...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.



--
Christopher Lambacher
ch...@kateandchris.net

Chris Lambacher

unread,
Dec 11, 2012, 2:44:41 PM12/11/12
to pylons-...@googlegroups.com
Hi Nicolas,

Okay, I was not adding the correct directory in my stuff so French was not working. What I did was added the result for formencode.api.get_localedir() to the translations directories. But that left me with multiple domains to work with between the standard validators and the messages I have for custom validators. I created a slightly modified version of pyramid.i18n.make_localizer that put everything in one domain and now it all works correctly.

-Chris
--
Christopher Lambacher
ch...@kateandchris.net

clemensherschel

unread,
Dec 11, 2012, 3:00:45 PM12/11/12
to pylons-...@googlegroups.com
I am happily using (bootstrap_)deform and in some situations like email
DNS mx and a record validating combining it with formencode validating.

Nicolas Di Pietro

unread,
Dec 11, 2012, 3:42:34 PM12/11/12
to pylons-...@googlegroups.com
Hi Jayd3e

It's what I'm trying right now but I didn't find yet the way to "internationalize" it. Do you use i18n with it ? Is it easy to change the default error messages with it ? (or do you catch the Invalid error and then rewrite the messages after parsing the msg ?)

Thx a lot for your answer,

Regards,
Nicolas

Nicolas Di Pietro

unread,
Dec 11, 2012, 3:47:59 PM12/11/12
to pylons-...@googlegroups.com, Nicolas Di Pietro
Hi Chris,

It's because it's the first thing I've tried and I'm not happy with it (customization of the error messages and presentation of it)

That's why I was looking for some alternatives.

Regards,

Nicolas

Chris Lambacher

unread,
Dec 11, 2012, 4:11:44 PM12/11/12
to pylons-...@googlegroups.com
Hi Nicolas,

I realized that my instructions were not going to do you much good if you followed any of the normal i18n instructions for Pyramid since the normal entry point is get_localizer. So I've scrapped my idea of do an altered make_localizer. What you need to do is tell the translation engine which domain to use. I'm basically following these instructions:
http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/templates/mako_i18n.html

The idea is to get a method on request called translate that creates a TranslationString (using the TranslationStringFactory) and pass that to localizer.translate. We can use this to our advantage.
1. Add the result of formencode.api.get_localedir() to your translation directories.
2. Anywhere you create local (i.e. project specific) strings to translate that will be consumed through formencode (i.e. used in the messages dict) make your _ function be a TranslationStringFactory object.
3. Make your _ function that you pass to the State object detect TranslationStrings and anything that is not a TranslationString should be run through a TranslationStringFactory('FormEncode') object.

So your _ function to the state object becomes:

fe_tsf = TranslationStringFactory('FormEncode')

def formencode_translator(s):
   if not isinstance(s, TranslationString):
       s = fe_tsf(s)

    return request.localizer.translate(s)

I'm normally in the #formencode channel on freenode as lambacck if you need more real time help.
-Chris
--
Christopher Lambacher
ch...@kateandchris.net

Jens W. Klein

unread,
Dec 12, 2012, 2:34:20 AM12/12/12
to pylons-...@googlegroups.com
Am Dienstag, 11. Dezember 2012 17:03:16 UTC+1 schrieb Nicolas Di Pietro:
Hi Jensens,

This sounds nice, but, reading the doc (a bit fast, I've to admit) it sounds like to define new widgets, you have to define it using YAML, right ?

No, you do not need any YAML - it is only an option for those who do not like to write forms in python.

Writings forms in YAML is also not in YAFOWIL core, it is only an addon for yafowil.

hth Jens
 

Jonathan Vanasco

unread,
Dec 12, 2012, 1:42:05 PM12/12/12
to pylons-...@googlegroups.com
i agree with pretty much everything.

the issues for me have been in separating the customization points for the right team members.    my library just wraps validation & serialization by FormEncode, and helps automate the server side processing.

personally, i believe you should have form fields listed separately in the HTML templates and the setup/validation routines.  i dislike automated form creation - i find the UX it creates to be very rough.

Huub Bouma

unread,
Dec 14, 2012, 8:00:18 AM12/14/12
to pylons-...@googlegroups.com
Well, here's another one :-)

https://github.com/wyldebeast-wunderliebe/w20e.forms

You can create forms from python code, or with an XML definition. We've used it in Django, Plone and Pyramid

Cheers, Huub


Op donderdag 6 december 2012 10:27:00 UTC+1 schreef Nicolas Di Pietro het volgende:
Reply all
Reply to author
Forward
0 new messages