> I think that the best solution is to add a new return value, e.g.
> {meta, Val}, to controller functions. ErlyWeb will accumulate those
> values in a list and pass it to the 'phased' Fun as an extra
> parameter. So, you could write
> {phased, {ewc, A},
> fun(ExpandedEwc, MetaVals, Rendered) ->
> {ewc, html_container, [A, MetaVals, Rendered]}
> end}.
> This would simplify setting the Title, Header, etc from the
> controllers without using Bryan's clever ErlTL tricks (which may be
> less-than-intuitive for some people :) ), add too much magic to the
> framework, or even changing it much. It would also work trivially even
> when subcomponents are rendered in parallel because this is
> effectively a side-effect-free accumulator.
That sounds good, and it avoids breaking backwards compatibility as
well. I do agree about changes to yaws_arg being a bad idea (although
it is currently possible for programs to change it before passing it
to children, that would be to be deliberate).
The only problem I see is that if my controller function returns:
[{add_property,{title,"The Title!"}},
{data,"foo"}]
Then what does my view function look like? These could both make sense:
<%@ fun([_,Data]) %> <!-- pass it through -->
<%@ fun([Data]) %> <!-- pretend it didn't exist -->
I wouldn't mind passing it through, but that does seem a bit strange
for children to be getting data intended for parents. Pretending it
didn't exist seems even stranger.
>
>>
>> I really like the component system, so I'd definitely like to get
>> your feedback on my ideas since it's already going in a good
>> direction.
>>
>> I wouldn't expect the siblings to be guaranteed to receive it (since
>> clearly you can't guarantee that they all do, since some may have
>> already been evaluated, or may be being evaluated at the same time),
>> but I wouldn't expect them to be guaranteed to *not* receive it.
>>
>> Since the yaws_arg is being re-vamped anyway, maybe this should be
>> carried around on the yaws_arg. A simple plist is probably fine for
>> it. Then as the yaws_arg is returned changed it can be passed through
>> changed. Then make all subcomponents pass the yaws_arg implicitly: so
>> instead of {ewc,controller,func,[A,Foo]} calling func(A,Foo), make
>> {ewc,controller,func,[Foo]]} call fun(A,Foo). That way you're not
>> passing a stale yaws_arg accidentally. This is of course a backwards-
>> breaking change, but not a difficult one to fix, since all of the
>> erlyweb code that I've seen and written passes it to the sub-
>> components anyway (even if it's not necessarily used).
>>
>> Otherwise, you end up all of the components doing something like
>> this:
>>
>> show(A,Foo)
>> NewA=yaws_arg:add_meta(A,[{title,get_the_title()}]),
>>
>> {return_with_meta,[{ewc,func,[NewA,Foo]}],
>> NewA}.
>>
>> (once again, with better names than return_with_meta and add_meta)
>> The worry here is that the subcomponents have to be called with NewA
>> instead of A, which seems ripe for forgetting to me (especially if
>> the yaws_arg some some validation before it passes it on; you could
>> pass invalid data to sub-components this way).
>>
>> I haven't looked at the contents of the yaws_arg, but if it's tagged
>> with a type, then you could just do this:
>>
>> show(A,Foo)
>> [_New_yaws_arg=yaws_arg:add_property(A,[{title,get_the_title()}]),
>> {ewc,func,[Foo]}].
>>
>> Since erlyweb already knows to check the returned list for {ewc} and
>> whatnot, it could just check for a new yaws_arg and start using that
>> one. The problem there is that it forces {ewc}s to be processed
>> serially (since what do you do when you get two conflicting
>> yaws_args?), which my erlyweb does not (and given your blog post on a
>> potential {concurrent,[{ewc,...}]}, I suspect this won't be a
>> guarantee forever). Another idea is to just add another return value
>> from controller functions:
>>
>> show(A,Foo)
>> [{add_property,{title,get_the_title()}},
>> {add_property,{time_to_live,two_weeks()}}
>> {ewc,controller,func,[Foo]},
>> {ewc,controller,fun2,[yaws_arg:get_property(cookies)]].
>>
>> (this was has my implicit-passing of yaws_args, but it's not
>> necessary; not doing so does preclude children retrieving properties
>> from parents, but if they need that they should pass it as an
>> argument anyway). That doesn't carry the assumption that they are
>> processed serially. It prevents parents from getting to children's
>> properties without using {phased,Ewcs,...}, but that's probably not a
>> problem, and isn't very avoidable. (I think all of these options do,
>> if they want to do post-processing of any kind).
>>
>> Personally, I like the last option, but it looks like it would
>> require quite a few changes to the way that the erlyweb:ewc/N
>> functions work
>>
>> Any other ideas? How does that last one look?
>
>
>
>
>>
>>
>>
>>
>>>>> Btw, just curious, what parts of ErlyWeb are you rewriting?
>>>> [...]
>>>> Mostly large swaths of erlydb and erlydb_mnesia (in ways that
>>>> make it
>>>> work better with mnesia, but that make it incompatible with other
>>>> DBMSs, which of course the current incarnation avoids). I may
>>>> end up
>>>> having to revert this if mnesia can't handle millions of objects,
>>>> with which it seems to be having trouble once they start to become
>>>> larger objects than simple tuples. I've hacked in a few return and
>>>> 'EXIT' handlers from controller functions for special
>>>> circumstances,
>>>> like when I want to return a 400- or 500-level HTTP response along
>>>> with other information. I might try to hack in some WebDAV handling
>>>> stuff, as I'm considering writing a desktop client for my app in
>>>> the
>>>> future and that seems the easiest way to get the data to and
>>>> from the
>>>> desktop client. I haven't decided what that's going to look like
>>>> yet.
>>>> It looks like I may be hacking in a return value to return extended
>>>> information to parent controller functions, like <title> tags.
>>>> but I
>>>> want to decide how it should work, first. It sounds like it's just
>>>> not a concern to the two biggest users of erlyweb
>>>
>>> If you want to contribute this feature (or any other feature that
>>> you
>>> think will be useful to other ErlyWeb users) I'll be happy to accept
>>> your code.
>>>
>>> Yariv
>>>
>>>>
>>>>
>>>>>
>>>>> Yariv
>>>>>
>>>>> On Nov 16, 2007 10:19 AM, David King <[EMAIL PROTECTED]> wrote:
>>>>>>
>>>>>> erlyweb uses a component system for rendering pages. It makes
>>>>>> most of
>>>>>> my controller functions return lists like this:
>>>>>>
>>>>>> [{data,post:title(Post)},
>>>>>> {ewc,post,contents,[A,Post]},
>>>>>> {ewc,comment,comments,[A,post:comments(Post)]}]
>>>>>>
>>>>>> The view function then looks like:
>>>>>>
>>>>>> <%@ show([Title,Contents,Comments]) %>
>>>>>> <h1><% Title %></h1>
>>>>>> <div class="post_contents"><% Contents %></div>
>>>>>> <ul class="comments><% Comments %></ul>
>>>>>>
>>>>>> I really like this, because it allows me to separate the view-
>>>>>> logic
>>>>>> for things like contents and comments out from each other, which
>>>>>> makes changing the behaviour of these quite simple, localised,
>>>>>> and
>>>>>> re-
>>>>>> useable. (In fact, as I re-write portions of erlyweb for my
>>>>>> purposes,
>>>>>> the component system is something that I haven't touched at all
>>>>>> because it works quite well.) However, it has an inherent
>>>>>> limitation:
>>>>>> none of those functions can return data to be rendered outside of
>>>>>> their components. In my case, I'd like to be able to set <title>
>>>>>> tags, which means that the top-level controller function (by top-
>>>>>> level, I mean the one referenced in the URL; like in /post/
>>>>>> show/12,
>>>>>> the top-level controller function would be show/2) needs to
>>>>>> somehow
>>>>>> return information to be rendered outside its little sandbox.
>>>>>>
>>>>>> I see that Vimagi doesn't set <title> tags (neither <http://
>>>>>> vimagi.com/p/0PXmMRe6hGV> nor <http://vimagi.com/users/
>>>>>> feeling3_4>
>>>>>> set one, at least, and those are where I'd expect to see
>>>>>> them), but
>>>>>> BeerRiot does (<http://beerriot.com/beer/view/1751>; BTW I do
>>>>>> love
>>>>>> the idea of having a controller called "beer_controller").
>>>>>>
>>>>>> It isn't limited to <title>s (for instance, I may want to
>>>>>> alert the
>>>>>> browser that an RSS equivalent of this page exists, or what the
>>>>>> caching TTL is for this page in the HTTP headers). Conceptually,
>>>>>> how
>>>>>> would one go about returning this extra information, while still
>>>>>> using the component system (I now have a lot of code that uses it
>>>>>> that I'd like to not re-write :) )?
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>>
>>>>
>>>
>>>
>>
>>>
>>
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"erlyweb" group.
To post to this group, send email to erlyweb@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/erlyweb?hl=en
-~----------~----~----~----~------~----~------~--~---