Using Magritte With Seaside

14

Click here to load reader

Transcript of Using Magritte With Seaside

Page 1: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

1/14onsmalltalk.com/using-magritte-with-seaside

On Smalltalkthoughts on Smalltalk and programming in general...

Using Magritte With SeasideBy Ramon Leon - 10 September 2007 under Magritte, Programming, Seaside, Smalltalk

One of the more tedious things one is faced with while writing web

applications is input forms. Forms suck because they're boring and repetitive.

Building them manually is the same thing over and over, but they're often just

different enough that fully automating them is rather difficult. I can't say I've

ever seen a perfect solution, but I've come to consider Magritte a pretty good

solution if your forms don't need to be too highly customized.

For an in depth look at the design of Magritte you should read Lukas' Master's

thesis, however, it's a bit much if you're just trying to get something done and

just want to understand how to get going with the basics. Magritte's capable of

more than you'll likely use if you're just wanting to build forms with Seaside.

I'm going to ignore those other abilities because frankly, I don't use them and

don't plan to.

The basic design of Magritte involves a few classes that you'll need to be

familiar with and often subclass to extend and customize.

MADescription

With Magritte you describe your objects with subclasses of MADescription,

this is where you'll always start, just describing the fields of your domain

objects that you'll want generated forms for. Descriptions contain the extra

metadata necessary to create user interfaces, and which component will be

used to render it. A simple description looks like this...

descriptionIsClosed ^ (MABooleanDescription new) selectorAccessor: #isClosed; label: 'Is Closed'; priority: 1000; yourself

Generally speaking you'll keep these descriptions on the class side of your

domain object. On occasion, you'll want some property of the description to be

dynamic and depend on the actual value of an instance side value, so you'll

move the description to the instance side. Strictly speaking, it doesn't matter

where you put them, sometimes you'll use them to build forms when you

don't even have a domain object, but this isn't the normal case.

There are two basic ways to create a form dynamically, one is simple and

includes all descriptions found on an object...

buildComponentFor: aModel ^aModel asComponent addValidatedForm

Search

Ajax (6)

Apache (5)

Databases (12)

Gemstone (2)

Linux (6)

Lisp (9)

Magritte (10)

Performance (8)

Profiling (1)

Programming (39)

Ruby (25)

Seaside (64)

Smalltalk (82)

Sql (13)

Squeak (6)

Updates (9)

about me | good books | popular posts | atom | rss

Page 2: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

2/14onsmalltalk.com/using-magritte-with-seaside

The other, a little more complex, but much more useful because you'll find

that rarely do you want "every" described field in a form. Often you'll have

multiple UI representations of a domain object within an app. Descriptions are

composable using a comma so you can build a form any subset of the fields...

buildComponentFor: aModel ^((ModelClass descriptionFieldOne, ModelClass descriptionFieldTwo, ModelClass descriptionFieldThree) asComponentOn: aModel) addValidatedForm; yourself

A Magritte form is generally wrapped with a form decoration via

#addValidateForm, which by default gives you a #save and #cancel button.

Magritte forms don't directly work on your domain objects. They work on a

memento of the values pulled from your object using the descriptions. When

you call #save, the values are validated using the descriptions, and only after

passing all validation rules are the values committed to your domain object by

the momentos via the accessors, which I'll describe shortly. For those

interested, this is a good place to plug in a custom container component and

integrate the #commit with Glorp, but that's another post.

Conditions

Descriptions can have predicates associated with them to validate the input

data which it calls conditions. There are two basic kinds of conditions (there

are actually more, but the block forms are what I use), both are simply blocks

that returns true or false to validate the data. One is the single field condition

which is passed the pending value directly and attached directly to your

descriptions. It's as simple as...

addCondition:[:value | value withBlanksTrimmed size > 3]

The other is the multi field validation which works on the memento which I'll

describe below.

addCondition: [:memento | (memento cache at: CAUser descriptionPassword) isNil or: [(memento cache at: CAUser descriptionPassword) = (memento cache at: CAUser descriptionConfirmedPassword)]] labelled: 'Passwords must match';

I've posted about these previously. They are attached to your containers

description which has access to all the fields.

Conditions are one of the few things about Magritte that I'm still iffy on. There

are advantages to having your rules outside your domain objects, especially if

you're taking advantage of Magritte as an Adaptive Object Model where users

can build rules from the UI. It also allows the mementos to easily test data for

validity outside the domain object and gives you a nice place to hook into the

validation system in the components. It bothers me a little because it weakens

the domain model, I'm still trying to find my balance here and decide just how

much I'll allow as conditions.

Magritte is very pluggable, should I decide I want all my rules in my domain

Page 3: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

3/14onsmalltalk.com/using-magritte-with-seaside

Magritte is very pluggable, should I decide I want all my rules in my domain

objects, I could plug in my own memento subclass to handle that, but I haven't

felt the need just yet.

MAMemento

When components read and write to domain objects, they do it using

mementos rather than working on the objects directly. The default memento

is MACheckedMemento, a subclass of MACachedMemento. The mementos

give Magritte a place to store invalid form data prior to allowing the data to be

committed to the object. It also allows Magritte to detect concurrency conflicts

for shared in image objects. By never committing invalid data to domain

objects, there's never a need to roll anything back. Should you feel the need,

just override #mementoClass on your domain object to provide your own.

MAAccessor

When a memento writes valid data to its model, it does so through accessors

which are also defined by the descriptions. MAAccessor subclasses allow you

to define how a value gets written to your class. For example, while I have a

read selector for my collections like #users, I prefer to encapsulate #add and

#remove on the domain object itself rather than having a writable selector for

#users:. When creating a description for that collection, I can specify my

custom #accessor: rather than using the default #selectorAccessor: which

then writes to my domain object with #addUser: and #removeUser:.

Another valuable use for accessors can be found when you want to flatten

several domain objects into a single form. Say you have a User object with an

Address object, and a CreditCard object but you want to edit them all as a

single form. You can create your form and dynamically wire up some

MAChainAccessors like so...

userTemplate ^((((CAUser descriptionEmail, CAUser descriptionPassword , CAUser descriptionConfirmedPassword) addAll: (CAAddress description collect: [:each | each copy accessor: (MAChainAccessor accessor: (MASelectorAccessor selector: #address) next: each accessor)]); addAll: (CACreditCard description collect: [:each |

each copy accessor: (MAChainAccessor accessor: (MASelectorAccessor selector: #creditCard) next: each accessor)])) yourself) asComponentOn: self session user) addValidatedForm: { (#save -> 'Update Profile')}; yourself.

Which basically just composes the users descriptions with the addresses and

credit cards descriptions while chaining the accessors together to allow the

addresses fields to be written to the address object rather than directly to the

customer object. Any non trivial UI will contain many such forms and this is

the ability I'm the most grateful for in Magritte. Also notice in the example

above how I changed the label for the save button to "Update Profile", also

something you'll need to do often that isn't immediately obvious how to do.

MADescriptionComponent

Page 4: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

4/14onsmalltalk.com/using-magritte-with-seaside

Components control how your objects display. Magritte widgets are subclasses

of this component. Some descriptions have an obvious one to one relationship

with a UI component while others could easily be shown by several different

components. For example, an MAMemoDescription would be represented by a

text area, but a MABooleanDescription could be a checkbox, or a drop down

with true and false, or a radio group with true and false.

Each description defaults to a component, but allows you to override and

specify any component you choose, including any custom one you may write.

For example, suppose I built a special component to render checkboxes as

fancy graphics rather than ordinary html checkboxes. I could plug it in by

changing the description as follows.

descriptionIsClosed ^ (MABooleanDescription new) selectorAccessor: #isClosed; label: 'Is Closed'; priority: 1000; componentClass: CAFancyCheckbox; yourself

These are essentially meta components written in standard Seaside. They work

on mementos and have access to your descriptions. This is where all that meta

data comes in handy. If you're building a dropdown list, it'll get its option list

from the description. When you render an element's label, that's also read

from the description.

When you build your own descriptions, you'll add fields to them for custom

data that you'll want available in your custom components. At first, you'll

mostly use built in descriptions and components, but as you grow comfortable

with Magritte you'll start wanting to build your own descriptions and

components because you'll want to do things beyond the basic framework like

Ajax. Magritte provides a solid foundation for extension.

MAComponentRenderer

By default, Magritte forms are rendered using MATableRenderer which

renders the fields in a table with errors at the top and labels to the left of input

fields. This is the default because it's the easiest thing to do automatically that

looks halfway decent. This can be overridden like so...

buildComponentFor: aModel ^((ModelClass descriptionFieldOne, ModelClass descriptionFieldTwo, ModelClass descriptionFieldThree) componentRenderer: MACssRenderer; asComponentOn: aModel) addValidatedForm; yourself

This hook allows you to render the form as you please, should you want to

display errors differently, or change how elements are wrapped, or how the

outer container itself is wrapped. It's handy to control how container classes

are tagged with css classes to have the form dynamically change its appearance

for various phases like valid/invalid. If you don't want your forms to look like

auto-generated forms, you will use this.

Page 5: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

5/14onsmalltalk.com/using-magritte-with-seaside

For each of the classes I just described, you'll want to pull up a hierarchy

browser and explore all the subclasses to see examples of how they are

specialized. Find some example projects in SqueakSource that use Magritte to

see how others create custom descriptions and components. As with any

framework, successful use depends on understanding it, and understanding

how the pieces fit together. Magritte will not doing everything you want out of

the box, it isn't meant to, but it's an excellent foundation to base your

application on. It will save you many hours of tedious work building forms by

hand. It will also give your objects extra metadata that you may find handy for

purposes other than building forms.

Along with Seaside, Magritte is also an excellent example of extremely well

written object oriented code that is worth reading to see exactly what it takes

to make a truly flexible and pluggable framework. Because it was originally a

masters thesis, it's also far better commented than you'd likely find in a

similar "real" world framework.

Related Posts

Small Reddit, A Seaside Sample Application

Making a Connection Pool for Glorp in Seaside

Interest in Seaside and Smalltalk Looking Good

A Simple File Based Wiki in Seaside

Maintaining Loose Coupling in Seaside Components

Comments (automatically disabled after 1 year)

1680 days ago

> It bothers me a little because it weakens the domain model,

I think the constraints should be defined, just once, alongside the domain

model. Whether these are converted to conditions that are checked the way

Magritte does should be a later bound decision, possibly dynamic.

Ramon Leon 1680 days ago

Care to expand on that thought further? Where would you define them?

How would such a model look?

1680 days ago

Can try :-) Consistency constraints should be defined on the domain model

itself, that is where they belong "definitionally". The constraints on Person

would be defined on class Person (modulo instance-specific specialization),

but represented in a form Magritte can traverse and reason with e.g.

Person constraintOn: #dateOfBirth is: [....]

Consider multiple channels that manipulate that domain model. On some

channels the consistency checks may be enforced in the UI layer itself, on

some other channels the checking should be done in a "server-side" call. This

decision can be late bound (in an extreme case, perhaps even entirely

dynamic on each call, if the call carries enough contextual info for

validations). Just as Magritte creates components by walking descriptions, it

Page 6: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

6/14onsmalltalk.com/using-magritte-with-seaside

validations). Just as Magritte creates components by walking descriptions, it

could follow a logic that knew something about the properties of a channel

(whether shallow or deep, determined dynamically on each call or relatively

static) to customize which, how, and where constraints are checked.

If some constraints vary depending on component used (e.g. free-form text

field for a date vs. a date picker) the composition would be a bit more

involved but same basic idea.

Ramon Leon 1679 days ago

To do so would require modifying Magritte to traverse the domain object for

its conditions, a workable approach, but maybe too much work.

Since the descriptions are part of the domain class, I could just consider

them the constraint system and give my domain objects the ability to

validate themselves against their descriptions anytime. I think that'd solve

my objections and meet the requirements you laid out above. I appreciate

your thoughts on the matter.

cdrick 1679 days ago

really cool, concise and clear !

I thinks this examples could be put in some magritte class comments...

Thanks Ramon, I was missing your posts ;)

Maybe a post on how to link seaside/magritte and database would be cool :)

Is it in relation to a special accesor, for instance MABlockAccessor ?

Thanks

1674 days ago

Should there be a more declarative way to use MAChainAccessor? Does

much of it boil down to a tree of symbols? (descriptionEmail

descriptionPassword descriptionConfirmedPassword address (street city zip)

creditCard * )

Ramon Leon 1674 days ago

Probably the cleanest thing to do would be to build a custom

ChainDescription, I just haven't found it necessary yet. A few more forms

like this and I might.

Sebastian 1668 days ago

Hey Ramon, your post covers details about using Magritte very useful to

evaluate using it. In fact it encouraged me to make a little experiment from

which I came out asking myself where is the real gain? by real gain I mean

what are the concrete savings of using Magritte? As probably happens with

every automagic form generator, they easily happen to become useful as a

factory of forms. That maybe good maybe don't. Todays if I want to make a

site, I mean, a web application which makes a difference in the user

experience, then I should think a lot about interface very carefully designed

for every step of the workflow. Said that (1), knowing that Magritte is

extensible enough to allow me to make my own canvas for any given control

like the fancycheckbox (2) and having in mind the trend that web apps have

Page 7: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

7/14onsmalltalk.com/using-magritte-with-seaside

like the fancycheckbox (2) and having in mind the trend that web apps have

interfaces highly customized for every step of their workflow (3), then I'm

definitively not convinced of the applicability of Magritte. Why? because is

not answered what a factory of forms can do for me if: 1 for everything I

need I need to generate a description, 2 if the standard build does not

satisfies (when it does really?) I have to emend the canvas 3 making simple

things can easily become complex 4 I have to pay the indirect costs of the

learning curve of programming describing instead of directly programming.

Also you have to ponder that you can have a nice factored hierarchy of

components of your own that does directly the boring thing in a simpler way.

So I say that I save if I don't use that factory at all and use the description

knowledge to build components myself and implement them myself well

fatored. Of course a final conclusion should be taken from making the real

numbers of forms and metrics as such for a formal applicability evaluation.

For my, using this rule of thumb, don't gets interesting. One thing that could

make a turn and justify using it is gaining OR mapping for the "same price".

But ActiveRecords are not yet ready to go and any OR designed to map tables

to classes I know are a real pain to scale in complexity. So I'm returning to

the same skeptical position. Anyway my curiosity to see where Magritte lead

others is far from being dead :) so I'm glad you write your comments.

Ramon Leon 1668 days ago

It's simple really, you get to describe your domain objects once and then

generate any number of validated forms from that single description.

While you can customize every part of Magritte for each project, you

generally don't. What you end up doing is customizing once, so it works the

way you like, and you reuse those customizations in every project you do.

The descriptions themselves can be auto generated by your IDE when you

create accessors, and quickly customized with properties like #beRequired,

#default:, #options:, #addCondition:labelled:,#min:, #max, etc. Believe it or

not, it does result in having to write much less code and a project wide

consistency in how forms look and feel that you won't get by manually

building your forms. It's also much faster than manually writing your forms.

A better way to think of it is this, if you manually build your forms, and then

factor your technique into something more reusable to save yourself time in

the future, at some point, you'll end up with something similar to Magritte.

At that point, you'll understand you should've just used something like

Magritte to begin with.

It's nothing more than a meta-model that allows you to add extra meta-data

to your objects so that generic view components have everything they need

to be bound to the model in a reusable fashion.

Bill 1641 days ago

> Magritte's capable of more than you'll likely use if you're > just wanting to

build forms with Seaside. I'm going to > ignore those other abilities because

frankly, I don't use > them and don't plan to.

Page 8: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

8/14onsmalltalk.com/using-magritte-with-seaside

frankly, I don't use > them and don't plan to.

Could you expand a bit on the other features Magritte offers, and why you

don't plan to use them? e.g. are the default Viewers not as useful as the

default Editors? Do you just need too many customizations to every viewer

to benefit from Magritte, and not so for forms? Are the editors easy to Ajax-

ify?

Also, is there a set of components you would recommend to get started with,

both for Seaside and Magritte?

Lastly, where (in your image) would I find the code that creates your IDE

customizations e.g. for description generation?

Thanks!

Ramon Leon 1641 days ago

Building forms is something you can do with Magritte, but I think Lukas

intended Magritte as a meta layer for further describing objects. At one point

I was using them to generate Glorp mappings, Pier uses them to search its

object model and at one point you could generate both Seaside forms and

Morphic forms from them.

However, in truth, I've become less and less enamored with Magritte as I

find myself having to jump through too many hoops and remember too

many details about its object model to really customize it.

Sebastian's comment above really got me to thinking about just how useful

Magritte is. Ajaxify'ing Magritte is no easy task especially when you want to

have several fields tied together in various ways.

I've come to realize the problem is Magritte is so meta that it forces you to

solve the meta problem you're having rather than the actual problem you're

having. You can't easily rig up something to solve a problem with a particular

form without having to solve it for all forms.

For example, making a select box be redrawn via Ajax when another one

changes. I did this, and I had to wire up descriptions to be dependents of

other descriptions, and then extend the container to send messages between

the individual views, it was a pain, I could have (and have) done this much

faster by just dropping into raw Seaside.

So, long story short, I've decided I prefer the approach taken by

WAFormDialog, a single superclass that can be extended to create specific

forms quickly. I don't actually use WAFormDialog because I also like using

metadata, so I'm hacking up my own form generator that uses pragmas from

the model to control how it renders forms based on a few simple

conventions that suite my style. It allows me to easily override the

automation on a per field basis to drop into Seaside and manually render

anything that needs to be Ajaxified or fancier than the defaults provide. So

far I'm liking this approach much better than Magritte.

So, I'd recommend taking a look at WAFormDialog and then hacking up

something similar that suits you. Seaside's reusable components are great,

but I'm finding that mostly, I don't want to reuse components I didn't build

myself because they are never quite what I want and it's so easy in Seaside to

Page 9: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

9/14onsmalltalk.com/using-magritte-with-seaside

myself because they are never quite what I want and it's so easy in Seaside to

simply build your own component that is exactly what you want, no more,

no less.

I doubt I'll be using Magritte much anymore, but I learned a lot from it. It's a

great framework, but it's just not what I need.

My browser customization can be found in the class SentorsaBrowser.

Sebastian, I appreciate the thoughtful comments, sometimes one spends so

much time learning something that you forget just how complicated it

seems, I'm glad I revisited my usage of Magritte and I much prefer my own

method to using it.

Bill 1624 days ago

> so I'm hacking up my own form generator that uses pragmas from the

model > to control how it render

Any chance you can share this? Even if very specific to your style I'm sure it

would be very useful to Seasiders in general.

Thanks.

Ramon Leon 1624 days ago

As always, my code is available in my image. The next time I update my

image that should be available as SSForm in the SentorsaSeaside package.

Joe 1603 days ago

Ramon,

I have had my eye on Magritte for many months now and I have been

reading your blog, mailing list posts, and Lukas's posts from the mailing list.

As with a good deal of frameworks/idioms/etc. written by others, I spend a

lot of time trying to listen to the "bad" chatter which is often more telling

than the good (I have reviewed the source and agree that it is great OO code).

Consequently, your last comment about how you've strayed from Magritte

has really made me question whether I should use it at all. I suppose it

depends on the particular project and what goals. I fear like you mentioned

in another comment that I will just end up building more or less the same

thing.

As part of a much larger system, I want to create a system that does some of

the following:

1) Allows the user to dynamically add fields to a form. A good example of this

in production is Microsoft SharePoint, albeit one that does it rather poorly

IMO.

2) Allows a user to add simple, but possibly chained dynamic validation

rules. This is something SharePoint sucks at beyond "required" fields, which

would be a simple #isRequired type idiom if I wanted to go that route.

3) Ability to define new simple business objects based off existing primitives,

for instance create a "Actress" based on a "Person" object, then add a

"Movies" (collection of movies) to the object.

Page 10: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

10/14onsmalltalk.com/using-magritte-with-seaside

4) AJAX, AJAX, AJAX. No, not for gimmicky purposes, but because parts of

this application are very "desktop" like and constant reloading really is more

of a pain in some places.

5) Lots of self-contained widgets that broadcast events if they need to talk

to/provide data to other widgets

I plan not to really use the built-in Magritte forms templates and instead

implement my own custom, theme-able forms. I think though what I am

really interested in is not so much generating these forms well

automagicallly, but the possibility of manipulating the meta-data at runtime.

For instance, creating a description at runtime. I would prefer to avoid the

meta-data route in some ways for reasons you mentioned because I really

would prefer to just have the application somehow generate a concrete

smalltalk class, but I am not so sure that is possible/good idea when you're

dealing with hundreds of images scaled out. Ideas?

I really like the way Lukas implemented security and other functionality in

Pier using Magritte. This is what originally attracted me, not really the forms

part, but it seems like it could be a daunting task really learning how to

effectively use what he built despite documentation. Building my own

system would take a lot of time, but in a sense it would do exactly what I

want without mucking things up by being too generic.

Do you think Magritte is still a good thing to use in a system like this?

Thoughts? Thanks.

Ramon Leon 1603 days ago

What you're describing is much more oriented towards what Magritte was

actually designed for, it already is a meta model and has the ability to allow

user generated objects and forms. The only place it's seriously lacking is

Ajax, and field to field interactions.

My problem with it isn't conceptual, it's practical. Every time I have to move

beyond a demo and build a real complex form with field to field interactions

and Ajax stuff, I have to start building custom seaside components and

figure out how to tie them together somehow when fields interact. Suddenly,

it's much easier to just build a single Seaside component for the whole form,

rather than a component per field.

Put simply, Magritte is too abstract, Seaside is the perfect level of abstraction

(for me) to allow the control necessary. Rather than composing forms from

subcomponents, it's easier to have a single form component that uses

metadata to render itself dynamically. This approach works better for very

customized programatically generated Ajaxy forms because I can drop into

raw Seaside whenever necessary to customize it. I don't want or need

runtime generated forms, frankly, users can't handle that no matter how

slick you try and make it. There will always be those who build things, those

who use them. People don't want to build their own forms... unless they're

developers. Dabbledb has found out just how many of their users are

actually semi-developers trying to use dabble to sell custom applications.

Page 11: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

11/14onsmalltalk.com/using-magritte-with-seaside

actually semi-developers trying to use dabble to sell custom applications.

If you want user built forms, Magritte is probably much more your cup of

tea, that's what it was designed for. Just be aware, if you want Ajax, you'll

likely have to build all of your own Magritte components anyway, the default

ones are very vanilla. But, runtime building and modification of descriptions

is what Magritte was meant for.

Joe 1603 days ago

Ramon,

You have a good point regarding the practicality of user generated forms. For

my particular application, user generated forms are a part of a whole, mainly

because that is what the client wants. In other words, most of the time I am

not creating components that use user generated forms, rather the forms are

more of an add-on for when the pre-canned stuff is not enough. It seems

whether I use pre-canned or user generated forms, I need to add metadata to

all my models because the canned objects may have to evolve to support a

user generated form, for instance when type Customer is extended to

VIPCustomer, necessitating 3 more fields.

I suppose I like the fact that Magritte seems to allow me some flexibility

designing the components. I can either just create a single component that

uses the meta-data as needed for things like the memento cache, or create a

series of components for the auto-generated forms. Obviously, the auto-

generated forms are not going to be as powerful, but I think they are better

than nothing at all.

Case in point, image a CMS system. With each page, there is a potentially

unknown amount of meta-data that needs to be added. In some cases, maybe

it is just keyword and tags will suffice, but in others it may be adding

business fields. I know that Pier does some of this and uses Magritte, but I

don't really like the user experience in Pier despite the quality of the code,

and it's not really that applicable for everything in my case anyway. How

would you add meta-data to something like this without a dynamic such as

Magritte? Would this always be time to have a developer intervene?

Certainly the surge in popularity of the numerous CMS and Portal products

(SharePoint again for example) prove that there is at least some desire for

user defined models. I think it's a bit different in the case of dabble db since

it's pretty much ground 0 until you do some work, vs a system where you

have a lot of pre-canned stuff and then realize the need to expand it. Where

these systems suck is the nightmare of XML, assembly/jar hell, and horrible

relational mapping (rows acting as columns ala SharePoint's database). The

Magritte way is probably a lot better compromise than the existing

implementations I have seen.

I certainly agree and appreciate your practicality. Coming from the

Assembly/C , Java, and .NET world myself mainly, I see my share of

ridiculous over engineering and complexity. If you've ever worked with

Microsoft CRM, Peoplesoft, SharePoint, or Oracle product, you are definitely

aware of just how badly these guys glue stuff together when it needs to be

Page 12: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

12/14onsmalltalk.com/using-magritte-with-seaside

aware of just how badly these guys glue stuff together when it needs to be

dynamic. I suppose the only way I'm going to find out for myself with this is

to move beyond my proof of concepts I have built with Squeak and into

something more tangible.

Ramon Leon 1603 days ago

"I know that Pier does some of this and uses Magritte, but I don't really like

the user experience in Pier despite the quality of the code"

Same here, the code is great, but I don't like the design. The problem with

Pier is the same as the problem with many frameworks... someone else

wrote them. I've come to the conclusion that the only CMS framework I'll

ever be happy with, is my own. Seaside gives me too much power to have to

put up with someone else's code.

So my advice is, build your own, there's nothing like knowing every line of

code inside and out, and you'll never be stuck trying to figure out how to

make it do something it wasn't intended for.

I gave up on the idea of end user programming, I'm a developer, and it's just

easier for me to hop in and add something that to build some uber meta

system that just serves to replace me. Smalltalk is my runtime configurable

uber system, and I can make changes just as fast in it as some homebrew

webified IDE that I'd cook up to give to users.

Joe 1601 days ago

Agreed, I can do/think the same. The problem is when you have clients who

get ideas in their head otherwise, i.e. hire me to do build something to

eliminate future need for developers (me and others). It sounds ridiculous

but it's true all the time now. There's also this huge push with bigger clients

towards COTS which I absolutely hate.

Smalltalk is definitely a breath of fresh air since there are few people

imposing that I generate GUIDS and XML files simply to write "hello world"

in some terrible bloated piece of garbage software. Working with everything

from windows driver programming to Outlook programming w/ MAPI to

ASP.NET w/ AJAX has really made me appreciate Smalltalk so much more

then when I first touched it in the 80s. I swear there was a time in C /MS

world especially where though you maybe had to write a VESA driver and

GUI for your app, it was easier doing that than dealing with some wannabe

developer end user system/framework/builder like we get now.

Ramon Leon 1601 days ago

"The problem is when you have clients who get ideas in their head otherwise,

i.e. hire me to do build something to eliminate future need for developers"

I'd just say no. You want something like that, go look at DabbleDB,

Salesforce, WuFoo, etc, and when you figure out that isn't really what you

want, come back, and we'll talk about what you want me to build and

maintain for you.

End user programming is a myth, they don't really want to program, they

Page 13: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

13/14onsmalltalk.com/using-magritte-with-seaside

just want to save money and think that's the answer. Once they try out such

a system and run into its limitations, they'll either accept them, or change

their mind and decide they have to pay a programmer to get what they really

want, which is usually something simple and highly custom.

Things like DabbleDB, Salesforce, and WuFoo are just way to complex for

your average user, they want apps to use, not meta apps that can build apps

they can use. The people who want meta apps, are middle men who think

they can build and brand apps to sell to end users.

Joe 1595 days ago

Ramon,

Agreed, but unless you are self employed, not always realistic. Microsoft

certain is in love with this direction and it is certainly not helping the

enterprise level consultant. See InfoPath, SharePoint "development

platform", Oracle, etc.

Ramon Leon 1595 days ago

Yea, I understand, but I decided a while back to find a gig that didn't force me

to do things I disagree with, it's just not worth the bitterness you eventually

develop. I take every opportunity to replace Microsoft stuff with better open

source alternatives.

Sophie 1593 days ago

> it's easier to have a single form component that uses metadata > to render

itself dynamically. This approach works better for very > customized

programatically generated Ajaxy forms because I can > drop into raw Seaside

whenever necessary to customize it.

I am really starting to need something like this. I'll either (muddle through)

building it, or beg or borrow it. Any chance you could share your code for this

e.g. as a fileOut?

Thanks - Sophie (p.s. sent email, but never know with spam filters ...)

Ramon Leon 1593 days ago

Check out my latest image.

Leon Smith 1519 days ago

I think you meant WAFormDialog rather than MAFormDialog right ?

Ramon Leon 1519 days ago

Oh, good catch, typo on my part, corrected.

Miguel Cobá] 1439 days ago

Until this week I finally began to learn Magritte. I read all the tutorials, all

the documentation I could find in the web and, in a post in the mailing list, a

link to your post. First it seemed like Magritte was the perfect tool to speed

up the development of a couple projects I have in mind. The examples from

the tutorials were amazing. You can build/validate forms with little effort.

All seemed perfect. But, when I began to do the real work of my project I find

myself trying to change the way Magritte do things by default. The layout of

Page 14: Using Magritte With Seaside

17/04/12 Using Magritte With Seaside

14/14onsmalltalk.com/using-magritte-with-seaside

myself trying to change the way Magritte do things by default. The layout of

fields, the css, the validations, etc. A feeling of being programing something

that was not the app, but the meta/descriptions/custom renderers began to

grow inside me. Often I was trying to solve problems related to Magritte

(customize it to adapt to my needs) instead of solving problems of my

project. Of course you save time by no writing forms by hand. But many

times, the time saved was lost trying to adapt Magritte. Furthermore, the

code began to have classes (like CAFancyCheckbox or MACssRenderer in

your example) that had nothing to do with my problem domain. Like another

layer that you have to understand before getting to the problem domain. So,

when I saw your comments I realize that I was not the only with this feeling.

I agree with you that, as Seaside allows you to quickly create exactly what

you need, in the long term the benefit of Magritte are not as evident and

useful as initially appears. I have Magritte in a very high concept, both as a

framework as and thesis work, but I think that Seaside is more than enough

to write a big project without the need of another layer hiding your problem

domain.

Cheers, Miguel Cobá]