Mailing List Archive

In-place preview editing
Hi,

I'm working on adding in-place preview editing to Bricolage for WHO.
However, being fairly new to Bricolage and Mason, I was hoping to get
some input on implementation. We want to get these changes committed
back into the project, so let me know if there's something that should
be done differently.

I've been playing around with the framework of getting this implemented
and what I've got so far is this:

- Modified /autohandler to load the in-place edit javascript and css
when we're in preview mode.
- Modified the various templates to store data that we need for the
field (I'm storing this in the class attribute).

So this gives me the basic interface to get the in-place editing
started. For the second item, I'm trying to add some way of making this
a simple task. Here is one of the things I'm not sure would be the best
approach to doing this. Would this be best done using a utility
template, creating a code ref in a <%shared> block, or <%method>? I
have currently got it set up as a template:

<%args>
$element
$just_classes => 0
</%args>
<%perl>
if ($burner->get_mode == PREVIEW_MODE) {
my $class = 'bricInlineEdit bricInlineEdit' . $element->get_id();

if ($just_classes) {
$m->out(" $class ");
}
else {
$m->out(qq| class="$class" |);
}
}
</%perl>

I'll probably need a global variable so we don't need to call
$burner->get_mode == PREVIEW_MODE (and whatever tests we might need) all
over the place. Would that be best placed in a <%shared> block in
/autohandler?

On the code side of things is where I'm really lost. I need to write
the code that the javascript will POST back to to save the field changes
given the element ID. I've been looking into how bulk edits are
saved and it looks like data is stored in sessions and saved using the
ContainerProf callback. Can anyone point me in the right direction for
this? I'm thinking we'll only allow in-place editing if you've already
checked out the story, so that should solve some of the permission
issues involved with being able to edit things. Are there any other
issues I need to be aware of for making such changes?

Thanks for any input!

Adrian

PS: I just realized that an element may have multiple fields so I need
to pass more than just the element ID back.
Re: In-place preview editing [ In reply to ]
On Jan 29, 2009, at 1:10 PM, Adrian Yee wrote:

> I'm working on adding in-place preview editing to Bricolage for WHO.

Welcome!

> However, being fairly new to Bricolage and Mason, I was hoping to get
> some input on implementation. We want to get these changes committed
> back into the project, so let me know if there's something that should
> be done differently.

Make sure that you're using the trunk checkout from SVN to do your
work. In fact, if you'd like, get a bitcard login and I'll get you a
commit bit and you can create a branch to work in.

https://www.bitcard.org/register

> I've been playing around with the framework of getting this
> implemented
> and what I've got so far is this:
>
> - Modified /autohandler to load the in-place edit javascript and css
> when we're in preview mode.

Well, a preview really just points to another Web server; Bricolage
doesn't really serve previews (it does out of the box, but that's just
so people can try Bricolage). So what you'd probably have to do here
is modify the code that controls the preview to inject the necessary
JS into the page being burned. And only if the output is text/html or
similar (xhtml).

Better would be to require that the template that formats a page for
preview insert the necessary JavaScript, like so:

<%preview>
<script type="text/javascript" src=http://<%
Bric::Config::VHOST_SERVER_NAME %>/media/js/preview.js"></script>
</%preview>

> - Modified the various templates to store data that we need for the
> field (I'm storing this in the class attribute).

What templates? An attribute of what class?

> So this gives me the basic interface to get the in-place editing
> started. For the second item, I'm trying to add some way of making
> this
> a simple task. Here is one of the things I'm not sure would be the
> best
> approach to doing this. Would this be best done using a utility
> template, creating a code ref in a <%shared> block, or <%method>?

Just to be clear, the templates that ship with Bricolage are
placeholders. WHO has its own templates that are completely
independent of Bricolage. So ideally, to support this functionality in
core bricolage, we need to provide an interface to template authors to
make adding support like this as simple as possible. So the JS code
and Perl code should go into libraries in Bricolage itself, with a
very simple interface of functions or a core object ($burner would be
good) that template authors can use without having to try very hard.

> I have currently got it set up as a template:
>
> <%args>
> $element
> $just_classes => 0
> </%args>
> <%perl>
> if ($burner->get_mode == PREVIEW_MODE) {
> my $class = 'bricInlineEdit bricInlineEdit' . $element->get_id();
>
> if ($just_classes) {
> $m->out(" $class ");
> }
> else {
> $m->out(qq| class="$class" |);
> }
> }
> </%perl>

This should probably be a method on Burner:

sub preview_class {
my ($self, $story, $element) = @_;
return '' unless $self->get_mode == PREVIEW_MODE && $story-
>get_checked_out;
return 'bricInlineEdit bricInlineEdit' . $element->get_id;
}

> I'll probably need a global variable so we don't need to call
> $burner->get_mode == PREVIEW_MODE (and whatever tests we might need)
> all
> over the place. Would that be best placed in a <%shared> block in
> /autohandler?

Keep code out of templates as much as possible. With what I have
above, template authors will be able to write:

for my $e ($element->get_elements) {
my $class = $burner->preview_class;
given ($e->get_key_name) {
when ('paragraph') { $m->print(qq{<p class="$class">}, $e-
>get_value, '</p>') }
when ('header') { $m->print(qq{<h3 class="$class">}, $e-
>get_value, '</p>') }
default { $burner->display_element($e); }
}
}

The upshot is that we make it as simple as possible for the template
author to use.

> On the code side of things is where I'm really lost. I need to write
> the code that the javascript will POST back to to save the field
> changes
> given the element ID. I've been looking into how bulk edits are
> saved and it looks like data is stored in sessions and saved using the
> ContainerProf callback. Can anyone point me in the right direction
> for
> this?

You've got it. You'll need to add a new method to that class that uses
the element ID to find the element to update (using
`_locate_subelement()`) and update it.

> I'm thinking we'll only allow in-place editing if you've already
> checked out the story, so that should solve some of the permission
> issues involved with being able to edit things.

Yes, I think that's right. You should test it with a non-checked-out
story, though, just for fun.

> Are there any other issues I need to be aware of for making such
> changes?
>
> Thanks for any input!
>
> Adrian
>
> PS: I just realized that an element may have multiple fields so I
> need to pass more than just the element ID back.


You need to pass the element ID and the ID of the field that you're
editing. Also, if you plan to add support for inserting a new field,
you'll need some way to handle that (maybe pass back the ID of the
field that comes before the field being added, with it being NULL if
the field being added is the first field).

HTH,

David
Re: In-place preview editing [ In reply to ]
Thanks for the input David.

>> - Modified /autohandler to load the in-place edit javascript and css
>> when we're in preview mode.
>
> Well, a preview really just points to another Web server; Bricolage
> doesn't really serve previews (it does out of the box, but that's just
> so people can try Bricolage). So what you'd probably have to do here is
> modify the code that controls the preview to inject the necessary JS
> into the page being burned. And only if the output is text/html or
> similar (xhtml).
>
> Better would be to require that the template that formats a page for
> preview insert the necessary JavaScript, like so:
>
> <%preview>
> <script type="text/javascript" src=http://<%
> Bric::Config::VHOST_SERVER_NAME %>/media/js/preview.js"></script>
> </%preview>

That's essentially what I'm doing. For my testing purposes, I just
edited the /autohandler template to load the in-place editor javascript
and css in a similar way (though I didn't know about the <%preview> block.

The separate preview server does pose a bit of a problem with browser's
same origin policy for XMLHttpRequests. If they do have a separate
preview server, they will need to set up rewrite rules to redirect the
request to the application server. Also the preview server will need to
be on the same domain. The other requirement is to modify Bricolage's
cookies so that it sends them to the preview server as well (ie.
.example.com).


>> - Modified the various templates to store data that we need for the
>> field (I'm storing this in the class attribute).
>
> What templates? An attribute of what class?

I'm referring to the html class attribute. For example, I have modified
the page.mc template:

if ($e->has_name('paragraph')) {
$m->out('<p', $burner->preview_class($story, $e), '>',
$e->get_value, '</p>');
}

I'm using the class attribute to store information about the element.
If you look at the attached patch, you'll see I'm passing it data like
the element's ID, the maximum length and widget type. I might need to
change what it passes depending on what other information I need to make
the actual change.


> Just to be clear, the templates that ship with Bricolage are
> placeholders. WHO has its own templates that are completely independent
> of Bricolage. So ideally, to support this functionality in core
> bricolage, we need to provide an interface to template authors to make
> adding support like this as simple as possible. So the JS code and Perl
> code should go into libraries in Bricolage itself, with a very simple
> interface of functions or a core object ($burner would be good) that
> template authors can use without having to try very hard.

Yup, that was what I was trying to do with the utility template. I have
changed it to be a burner method instead as you suggested.


>> On the code side of things is where I'm really lost. I need to write
>> the code that the javascript will POST back to to save the field changes
>> given the element ID. I've been looking into how bulk edits are
>> saved and it looks like data is stored in sessions and saved using the
>> ContainerProf callback. Can anyone point me in the right direction for
>> this?
>
> You've got it. You'll need to add a new method to that class that uses
> the element ID to find the element to update (using
> `_locate_subelement()`) and update it.

I'm still having a hard time figuring this part of it out. I've written
a bit of code that uses Bric::Biz::Element::Field to update a given
field, but that bypasses the whole permission system, which is obviously
not what I want. I've been trying to track down where permissions are
handled in bulk edits, but I haven't had any luck. So I have some
questions:

1) How does the session (get/set_state_data) work into the whole thing?
For example, for bulk edits, I see
widgets/container_prof/container_prof.mc gets included and it calls
set_state_data and get_state_data. The ContainerProf::bulk_edit
callback seems to do all the saving, so that does the mason code do
(other than load the form)?

2) How are permissions handled for editing elements for a story?

3) Where should I put my AJAXy handler and how should it be structured?
I've been playing around with just putting it in
widgets/story_prof/inline_edit.html (similar to
autocomplete_categories.html). Should I be using the callbacks, or just
put all the code in the html file? I don't imagine there being that
much code.


>> I'm thinking we'll only allow in-place editing if you've already
>> checked out the story, so that should solve some of the permission
>> issues involved with being able to edit things.
>
> Yes, I think that's right. You should test it with a non-checked-out
> story, though, just for fun.

Yup. The code should return an error to the javascript if the story
isn't already checked out.

Thanks for all the help!

Adrian
Re: In-place preview editing [ In reply to ]
On Feb 6, 2009, at 6:46 PM, Adrian Yee wrote:

> That's essentially what I'm doing. For my testing purposes, I just
> edited the /autohandler template to load the in-place editor
> javascript and css in a similar way (though I didn't know about the <
> %preview> block.

Okay.

> The separate preview server does pose a bit of a problem with
> browser's same origin policy for XMLHttpRequests. If they do have a
> separate preview server, they will need to set up rewrite rules to
> redirect the request to the application server. Also the preview
> server will need to be on the same domain. The other requirement is
> to modify Bricolage's cookies so that it sends them to the preview
> server as well (ie. .example.com).

Yeah, all of that is just a SMOP. Though the less configuration
required the better. It'd be much better if edit requests didn't go
through the preview server, but directly to the Bricolage server. The
less work for users and admins, the better.

>>> - Modified the various templates to store data that we need for the
>>> field (I'm storing this in the class attribute).
>> What templates? An attribute of what class?
>
> I'm referring to the html class attribute. For example, I have
> modified the page.mc template:
>
> if ($e->has_name('paragraph')) {
> $m->out('<p', $burner->preview_class($story, $e), '>', $e-
> >get_value, '</p>');
> }
>
> I'm using the class attribute to store information about the
> element. If you look at the attached patch, you'll see I'm passing
> it data like the element's ID, the maximum length and widget type.
> I might need to change what it passes depending on what other
> information I need to make the actual change.

Gotcha. Using HTML classes for this is a great hack.

> Yup, that was what I was trying to do with the utility template. I
> have changed it to be a burner method instead as you suggested.

+1

>>> On the code side of things is where I'm really lost. I need to
>>> write
>>> the code that the javascript will POST back to to save the field
>>> changes
>>> given the element ID. I've been looking into how bulk edits are
>>> saved and it looks like data is stored in sessions and saved using
>>> the
>>> ContainerProf callback. Can anyone point me in the right
>>> direction for
>>> this?
>> You've got it. You'll need to add a new method to that class that
>> uses the element ID to find the element to update (using
>> `_locate_subelement()`) and update it.
>
> I'm still having a hard time figuring this part of it out. I've
> written a bit of code that uses Bric::Biz::Element::Field to update
> a given field, but that bypasses the whole permission system, which
> is obviously not what I want. I've been trying to track down where
> permissions are handled in bulk edits, but I haven't had any luck.
> So I have some questions:

Well, this isn't a bulk edit, but the editing of a single field. Also,
I think that the permission checking is done in the story profile code
(Bric::App::Callback::Profile::Story). That would require multiple
callbacks, but once you have a story, you can just use chk_authz() to
verify permissions.

> 1) How does the session (get/set_state_data) work into the whole
> thing? For example, for bulk edits, I see widgets/container_prof/
> container_prof.mc gets included and it calls set_state_data and
> get_state_data. The ContainerProf::bulk_edit callback seems to do
> all the saving, so that does the mason code do (other than load the
> form)?

That's kind of a legacy: the callbacks used to be in Mason code. So
there's a mix. It's kind of hard to keep track of. But basically, when
you're editing a story, the callbacks put it into the session (in
create() and checkout()) and the various other callbacks and Mason
code make sure that they're always dealing with the correct story
object.

> 2) How are permissions handled for editing elements for a story?

Um…I'm not sure. I don't see any checked in ContainerProf, so we might
not be properly verifying permissions. In truth, however, I think you
can probably ignore permissions. For elements, we only check to make
sure users have READ permission to an element type before we add an
element of that type to a story. Once an element is in the story, a
user can edit it if she has EDIT permission to the story, regardless
of the permission on the element type on which it's based.

And none of this should apply to you, because as long as the user had
EDIT permission to the story, she can edit an individual field
anywhere in the story.

> 3) Where should I put my AJAXy handler and how should it be
> structured? I've been playing around with just putting it in
> widgets/story_prof/inline_edit.html (similar to
> autocomplete_categories.html). Should I be using the callbacks, or
> just put all the code in the html file? I don't imagine there being
> that much code.

Try to use the callbacks for processing and Mason only for
presentation. That's not always feasible given the legacy of the code,
but that's what we aim for.

HTH,

David
Re: In-place preview editing [ In reply to ]
Ahh, thanks, I think I'm getting more of a handle of how things are done
in Bricolage.

We've run into some new issues with the in-place preview editing. When
you update something in the preview, the edit story page (if you had it
open), now shows the old data. Currently, my implementation just edits
the field directly, so I'm not touching the session data, so until you
log out, the edit page shows the old data.

I have been thinking about switching my save code to update the session
data (rather than immediately saving the updated field values), but if
you don't already have the edit page open, then how do you actually save
the changes? Also, what you have on the save page will be different, so
what actually gets saved?

The other thing I can think of is to expect that if you make changes on
the preview, then your edit story becomes stale and if you attempt to
save the story, then you get an error message telling you this.

Any other possible solutions to this problem?

David E. Wheeler wrote:
>> The separate preview server does pose a bit of a problem with
>> browser's same origin policy for XMLHttpRequests. If they do have a
>> separate preview server, they will need to set up rewrite rules to
>> redirect the request to the application server. Also the preview
>> server will need to be on the same domain. The other requirement is
>> to modify Bricolage's cookies so that it sends them to the preview
>> server as well (ie. .example.com).
>
> Yeah, all of that is just a SMOP. Though the less configuration required
> the better. It'd be much better if edit requests didn't go through the
> preview server, but directly to the Bricolage server. The less work for
> users and admins, the better.

Yeah, I'm up for making things as simple as possible for everyone. I
might have to switch from using XMLHttpRequests to using an iframe to
submit the requests. It's a little clumsier, but it might allow us to
get around the same origin policy.

Adrian
Re: In-place preview editing [ In reply to ]
On Feb 11, 2009, at 12:43 PM, Adrian Yee wrote:

> Ahh, thanks, I think I'm getting more of a handle of how things are
> done in Bricolage.
>
> We've run into some new issues with the in-place preview editing.
> When you update something in the preview, the edit story page (if
> you had it open), now shows the old data. Currently, my
> implementation just edits the field directly, so I'm not touching
> the session data, so until you log out, the edit page shows the old
> data.

Yeah, you need to force that page to reload the elements. Perhaps you
can control that stuff by loading JavaScript in the top-level frame of
the preview window? That's served by Bricolage, not the preview
server, so there should be no cross-site problems. Plus, IIRC, the JS
code in the preview window, even though it's on another server, can
use JavsScript in the parent frame to do the submissions, thus letting
the Bricolage JS do the work. Yes?

> I have been thinking about switching my save code to update the
> session data (rather than immediately saving the updated field
> values), but if you don't already have the edit page open, then how
> do you actually save the changes? Also, what you have on the save
> page will be different, so what actually gets saved?

If the story is not in the session, you just save it, yes. Otherwise,
update the session. Why would what gets saved be any different?

> The other thing I can think of is to expect that if you make changes
> on the preview, then your edit story becomes stale and if you
> attempt to save the story, then you get an error message telling you
> this.
>
> Any other possible solutions to this problem?

Look at the code that's used to add new fields and elements to the
container profile: it issues a request for a partial HTML string from
Bricolage to update all of the elements, with the new one added in the
proper place. You're going to do something similar: send all changes
to the server and return a partial that should be loaded into the div
with the elements.

HTH,

David
Re: In-place preview editing [ In reply to ]
Hi Adrian,

I've been puzzling about something similar. Basically, what happens to
the edit screen if previewing a story causes changes to the story
itself? See here for background:

http://www.gossamer-threads.com/lists/bricolage/devel/35212

Obviously there are a lot of possible approaches. The big dilemma, near
as I can tell, is this:

1. For some users, forcing an update of the story profile is bad,
because unsaved changes would be lost.
2. For other users, forcing an update of the story profile is essential,
because changes have *already* occurred, and been saved, and the
inconsistency of the story profile page with the story itself triggers
an error message.

So the question is this: how do we reconcile those two perspectives?


Cheers,

Bret




On Wed, 2009-02-11 at 12:43 -0800, Adrian Yee wrote:
> Ahh, thanks, I think I'm getting more of a handle of how things are done
> in Bricolage.
>
> We've run into some new issues with the in-place preview editing. When
> you update something in the preview, the edit story page (if you had it
> open), now shows the old data. Currently, my implementation just edits
> the field directly, so I'm not touching the session data, so until you
> log out, the edit page shows the old data.
>
> I have been thinking about switching my save code to update the session
> data (rather than immediately saving the updated field values), but if
> you don't already have the edit page open, then how do you actually save
> the changes? Also, what you have on the save page will be different, so
> what actually gets saved?
>
> The other thing I can think of is to expect that if you make changes on
> the preview, then your edit story becomes stale and if you attempt to
> save the story, then you get an error message telling you this.
>
> Any other possible solutions to this problem?
>
> David E. Wheeler wrote:
> >> The separate preview server does pose a bit of a problem with
> >> browser's same origin policy for XMLHttpRequests. If they do have a
> >> separate preview server, they will need to set up rewrite rules to
> >> redirect the request to the application server. Also the preview
> >> server will need to be on the same domain. The other requirement is
> >> to modify Bricolage's cookies so that it sends them to the preview
> >> server as well (ie. .example.com).
> >
> > Yeah, all of that is just a SMOP. Though the less configuration required
> > the better. It'd be much better if edit requests didn't go through the
> > preview server, but directly to the Bricolage server. The less work for
> > users and admins, the better.
>
> Yeah, I'm up for making things as simple as possible for everyone. I
> might have to switch from using XMLHttpRequests to using an iframe to
> submit the requests. It's a little clumsier, but it might allow us to
> get around the same origin policy.
>
> Adrian
>
--
Bret Dawson
Producer
Pectopah Productions Inc.
(416) 895-7635
bret@pectopah.com
www.pectopah.com
Re: In-place preview editing [ In reply to ]
On Feb 11, 2009, at 1:50 PM, Bret Dawson wrote:

> 1. For some users, forcing an update of the story profile is bad,
> because unsaved changes would be lost.

We need to make sure that previews update the copy of the story stored
in the session before it previews the story. This will allow users to
see their changes in the preview before they have even saved those
changes.

> 2. For other users, forcing an update of the story profile is
> essential,
> because changes have *already* occurred, and been saved, and the
> inconsistency of the story profile page with the story itself triggers
> an error message.

Yes, the session copy of the story *must* be up-to-date before a
template changes the story. In fact, ideally the template should save
the story *but not change it* if the story is fetched from the
session. So we need to have a way to be able to tell whether or not a
story is currently being edited from within templates.

HTH,

David
Re: In-place preview editing [ In reply to ]
On Wed, 11 Feb 2009, David E. Wheeler wrote:
> On Feb 11, 2009, at 1:50 PM, Bret Dawson wrote:
>> 1. For some users, forcing an update of the story profile is bad,
>> because unsaved changes would be lost.
>
> We need to make sure that previews update the copy of the story stored in the
> session before it previews the story. This will allow users to see their
> changes in the preview before they have even saved those changes.

Wow, this is getting complicated..

I'm not sure if this matters:
If one User has a Story checked out,
when another User previews that Story
the checked-in version of the Story is previewed.
So if a template edits "the" Story during preview,
it presumably edits different versions of the Story
depending on its checked-out state and who is previewing it.
Re: In-place preview editing [ In reply to ]
On Wed, 11 Feb 2009, David E. Wheeler wrote:
> Plus, IIRC, the JS code in the preview window,
> even though it's on another server, can use JavsScript in the parent
> frame to do the submissions, thus letting the Bricolage JS do the work. Yes?

I don't think so.
I think you have to use an iframe like Adrian mentioned.
http://pipwerks.com/journal/2008/11/30/iframes-and-cross-domain-security-part-2/
Re: In-place preview editing [ In reply to ]
On Feb 12, 2009, at 2:11 AM, Scott Lanning wrote:

> Wow, this is getting complicated..
>
> I'm not sure if this matters:
> If one User has a Story checked out,
> when another User previews that Story
> the checked-in version of the Story is previewed.
> So if a template edits "the" Story during preview,
> it presumably edits different versions of the Story
> depending on its checked-out state and who is previewing it.

Only the user who has the story checked-out can make changes.

Best,

David
Re: In-place preview editing [ In reply to ]
On Feb 12, 2009, at 2:43 AM, Scott Lanning wrote:

> On Wed, 11 Feb 2009, David E. Wheeler wrote:
>> Plus, IIRC, the JS code in the preview window,
>> even though it's on another server, can use JavsScript in the parent
>> frame to do the submissions, thus letting the Bricolage JS do the
>> work. Yes?
>
> I don't think so.
> I think you have to use an iframe like Adrian mentioned.
> http://pipwerks.com/journal/2008/11/30/iframes-and-cross-domain-security-part-2/

That's what I meant. You know when you do a preview and you see the
"Preview again" link? That's served from Bricolage. JS there can do
whatever it wants with Bricolage. If the code in a child frame can
send stuff to that JS, we're golden. Can it?

Best,

David
Re: In-place preview editing [ In reply to ]
David E. Wheeler wrote:
> On Feb 12, 2009, at 2:43 AM, Scott Lanning wrote:
>
>> On Wed, 11 Feb 2009, David E. Wheeler wrote:
>>> Plus, IIRC, the JS code in the preview window,
>>> even though it's on another server, can use JavsScript in the parent
>>> frame to do the submissions, thus letting the Bricolage JS do the
>>> work. Yes?
>>
>> I don't think so.
>> I think you have to use an iframe like Adrian mentioned.
>> http://pipwerks.com/journal/2008/11/30/iframes-and-cross-domain-security-part-2/
>
> That's what I meant. You know when you do a preview and you see the
> "Preview again" link? That's served from Bricolage. JS there can do
> whatever it wants with Bricolage. If the code in a child frame can send
> stuff to that JS, we're golden. Can it?

I did a bit of research on this and the answer is no (sort of). There
are ways to hack around it like in the link Scott posted. However, I
believe the hacks use the frame's URL to communicate. The problem with
this is it really limits us to how much data we can send between the two
frames. Not a problem for the samples that they use, but we have
textareas of data to send and this could easily hit the limit (IE has a
limit of 2083 characters).

One possible not-so-nice solution would be this:
- Preview frame creates an iframe that links to a local file (if you can
create the iframe's source in javascript, then you won't need to have
that file on the preview server).
- Modify the form on that file to post the new element data and submit
the form.
- The form posts to the application server.
- The resulting page returns the result and using the techniques
described in the above url, we return that status back to the preview
server (since the iframe's content is now a result from the application
server, we can't communicate directly with it).
- The preview page would need to poll the iframe for the result.

Adrian
Re: In-place preview editing [ In reply to ]
On Feb 16, 2009, at 10:48 AM, Adrian Yee wrote:

> I did a bit of research on this and the answer is no (sort of).
> There are ways to hack around it like in the link Scott posted.
> However, I believe the hacks use the frame's URL to communicate.
> The problem with this is it really limits us to how much data we can
> send between the two frames. Not a problem for the samples that
> they use, but we have textareas of data to send and this could
> easily hit the limit (IE has a limit of 2083 characters).
>
> One possible not-so-nice solution would be this:
> - Preview frame creates an iframe that links to a local file (if you
> can create the iframe's source in javascript, then you won't need to
> have that file on the preview server).
> - Modify the form on that file to post the new element data and
> submit the form.
> - The form posts to the application server.
> - The resulting page returns the result and using the techniques
> described in the above url, we return that status back to the
> preview server (since the iframe's content is now a result from the
> application server, we can't communicate directly with it).
> - The preview page would need to poll the iframe for the result.

Hrm. But it'd just have to poll when it knew it was submitting a post,
right? That doesn't sound so bad.

Ultimately, we want this to be a simple for users to use as possible.
And as a secondary consideration, it should be as easy as possible for
Bricolage admins and template developers to use, too.

Best,

David
Re: In-place preview editing [ In reply to ]
On Mon, 16 Feb 2009 15:16:42 -0800
"David E. Wheeler" <david@kineticode.com> wrote:
> On Feb 16, 2009, at 10:48 AM, Adrian Yee wrote:
> > One possible not-so-nice solution would be this:
> > - Preview frame creates an iframe that links to a local file (if you
> > can create the iframe's source in javascript, then you won't need to
> > have that file on the preview server).
> > - Modify the form on that file to post the new element data and
> > submit the form.
> > - The form posts to the application server.
> > - The resulting page returns the result and using the techniques
> > described in the above url, we return that status back to the
> > preview server (since the iframe's content is now a result from the
> > application server, we can't communicate directly with it).
> > - The preview page would need to poll the iframe for the result.
>
> Hrm. But it'd just have to poll when it knew it was submitting a post,
> right? That doesn't sound so bad.

Yup, the idea is to start polling once the iframed form has been created and
posted. Once we get the response, then it stops polling.

> Ultimately, we want this to be a simple for users to use as possible.
> And as a secondary consideration, it should be as easy as possible for
> Bricolage admins and template developers to use, too.

I think there may be some UI quirks to deal with on the user side that I might
not be able to work around. A couple that I can think of:

- You have the edit story page open while you edit the preview. After you've
updated elements in the preview page, it now doesn't match the edit story page.
I might be able to work around this by using javascript to tell the edit page to
perform an update on an element, but I have to look into the whole permissions
thing for this as well. Even if you can, this is messy too, since the preview
control needs to poll the preview page for when to send refreshes back to the
opening window. ughh!
- You have have the story checked out, but you don't have the edit story page
open. After you edit, you don't have any way to save your changes. One
possible solution is to put the save button on the control frame on the preview
page. This will need some communication between the opener and the preview
page. Lots of room for breakage here though. :(

So the only thing the admin would need to do is be able to put the static iframe
content somewhere on the preview server. Template admins just need to put in
the <& $burner->preview_class() &> into their templates in the right places.
It's just a big pain and confusing for us developers!

Adrian
Re: In-place preview editing [ In reply to ]
On 17-Feb-09, at 7:01 AM, Adrian Yee wrote:

>> Ultimately, we want this to be a simple for users to use as possible.
>> And as a secondary consideration, it should be as easy as possible
>> for
>> Bricolage admins and template developers to use, too.
>
> I think there may be some UI quirks to deal with on the user side
> that I might
> not be able to work around.

I'm not sure if these comment will be helpful, but here goes:

I've been trying to get my head around the use cases for this "in-
place preview editing" for days now. I've been following the thread,
and it's confusing as hell, for all the reasons that have come up re:
permissions, the story edit screen state, etc.

And I keep asking myself, couldn't this be easier? For example:

1. Why would the user *need* to have _both_ the story edit UI and the
in-place preview open? If the user had the ability to edit previews,
wouldn't seem more likely that they'd simply click the preview link
from their workspace vs. clicking edit on the story, then the preview
link, etc.? Also, how would this work if the user clicked on a preview
link from a desk, or a search, when they don't have the story checked
out? Would they expect to be able to preview it in that scenario?

2. If they did *start* from the story edit UI and click the preview
link and then start editing, could the story edit UI be closed at that
point? Or, if not closed, maybe forced into a greyed-out / modal state
while the focus was on the preview window. Then, when focus returned
to the story edit UI, it could re-load all of story's data from the
updated / in-place edited version?

Also, I keep wondering about users who are just browsing their
organizations Web site, finding a typo, and wanting to update / edit
it. And -- from that use case -- I keep thinking of the "Bricolite"
tool that Greg Heo built (which I hope he'll post online soon!), which
allows bloggers access to a simple UI for editing "blog posts." The
whole process is accomplished through bric_soap, and I wonder why the
in-place edits could work the same way, e.g.:

1. The previewed story also contains the full bric_soap XML version of
the story (just commented out / not visible)
2. In place edits simply update the XML document
3. Finished edits are posted back to Bricolage with bric_soap --story
update

The nice thing about the way Bricolite works (because it's using
bric_soap) is that most / all of the permissions issues are already
addressed / built-in to bric_soap, so no need to re-check them. And,
going down that line of thinking -- and given that Greg's recently
worked on an XML-RPC extension to Bricolite -- wouldn't it be possible
to simply have the in-place edits be XML-RPC calls? E.g.:

1. Log-in to the organization site (in some way) to provide
credentials for Bricolage and an "Edit" button is overlaid on pages of
the site that are in Bricolage (by checking for the existence of a
certain meta tag or something, e.g. something with a Bricolage story
ID in it)
2. Clicking edit would use bric_soap to checkout the story to the user
and export the story XML for the in-place editor to use for updates
3. Clicking "Save & publish" or what-have-you would post the edited
XML back to Bricolage and publish the story

I think, to Adrian's point, that a "Save & publish" and maybe a "Save
& continue editing" button would need to be in the preview.

Sorry if I'm way off in wonderland here. Still early in the morning
and I've only had a half-cup of coffee. :-)

Phillip.

--
Phillip Smith // Simplifier of Technology // COMMUNITY BANDWIDTH
www.communitybandwidth.ca // www.phillipadsmith.com
Re: In-place preview editing [ In reply to ]
Hi Phillip,

> I've been trying to get my head around the use cases for this "in-
> place preview editing" for days now. I've been following the thread,
> and it's confusing as hell, for all the reasons that have come up re:
> permissions, the story edit screen state, etc.

The use case is when you have a well structured document that may be
formed from a lot of elements (some documents have 100+ elements). You
click preview and you notice a typo in a single field somewhere. Rather
then having to close preview, find the element, make the change, and
then re-preview, you simply click in the appropriate paragraph and make
your change.

If your document simply uses a single wysiwyg field for the content,
then this is really not that useful.

> 1. Why would the user *need* to have _both_ the story edit UI and the
> in-place preview open? If the user had the ability to edit previews,
> wouldn't seem more likely that they'd simply click the preview link
> from their workspace vs. clicking edit on the story, then the preview
> link, etc.? Also, how would this work if the user clicked on a preview
> link from a desk, or a search, when they don't have the story checked
> out? Would they expect to be able to preview it in that scenario?

The editable preview is for simple fixes only. It does not allow you to
add elements, move elements, add images, change images, or a host of
other things. It is limited to a simple text field fixups.

If the story is not checked out, then the story is not editable and the
preview would also not be editable.

> 2. If they did *start* from the story edit UI and click the preview
> link and then start editing, could the story edit UI be closed at that
> point? Or, if not closed, maybe forced into a greyed-out / modal state
> while the focus was on the preview window. Then, when focus returned
> to the story edit UI, it could re-load all of story's data from the
> updated / in-place edited version?

That's the struggle we are having now. =) The big problem comes with
javascript and trying to communicate from a remote server to the
bricolage server. Adrian has outlined it in much more detail.

> Also, I keep wondering about users who are just browsing their
> organizations Web site, finding a typo, and wanting to update / edit
> it. And -- from that use case -- I keep thinking of the "Bricolite"
> tool that Greg Heo built (which I hope he'll post online soon!), which
> allows bloggers access to a simple UI for editing "blog posts."

I think there are a few issues with this:

1. It depends on a single wysiwyg type block for content, and wouldn't
give you the wysiwyg edit feel if a story is put together from a lot of
elements (i.e. broken down to the paragraph level).

2. You run into the same issue with having to install something on the
preview server or another location, or have two separate authentications.

3. The separate login doesn't really address the use case we are trying
to solve. =)

Cheers,

Alex

--
Alex Krohn <alex@gossamer-threads.com>
Re: In-place preview editing [ In reply to ]
On Feb 17, 2009, at 1:01 AM, Adrian Yee wrote:

>> Hrm. But it'd just have to poll when it knew it was submitting a
>> post,
>> right? That doesn't sound so bad.
>
> Yup, the idea is to start polling once the iframed form has been
> created and
> posted. Once we get the response, then it stops polling.

Yeah, that seems fine. We might want to put a timeout on it, though.

>> Ultimately, we want this to be a simple for users to use as possible.
>> And as a secondary consideration, it should be as easy as possible
>> for
>> Bricolage admins and template developers to use, too.
>
> I think there may be some UI quirks to deal with on the user side
> that I might
> not be able to work around. A couple that I can think of:
>
> - You have the edit story page open while you edit the preview.
> After you've
> updated elements in the preview page, it now doesn't match the edit
> story page.
> I might be able to work around this by using javascript to tell the
> edit page to
> perform an update on an element, but I have to look into the whole
> permissions
> thing for this as well. Even if you can, this is messy too, since
> the preview
> control needs to poll the preview page for when to send refreshes
> back to the
> opening window. ughh!

I don't think you need to worry about permissions getting the edit
window to update its content. And if you can tie it to when the
preview window closes, that might be good enough -- or at least a good
place to start.

> - You have have the story checked out, but you don't have the edit
> story page
> open. After you edit, you don't have any way to save your changes.
> One
> possible solution is to put the save button on the control frame on
> the preview
> page. This will need some communication between the opener and the
> preview
> page. Lots of room for breakage here though. :(

I say that if you don't have the window open, the changes are just
saved. I think that will be the closest to DWIM for most users,
especially if the control when you're editing a field in the preview
window has a "save" button which has to be clicked when the edit is
complete.

> So the only thing the admin would need to do is be able to put the
> static iframe
> content somewhere on the preview server.

I think I missed this. What is it?

> Template admins just need to put in
> the <& $burner->preview_class() &> into their templates in the right
> places.
> It's just a big pain and confusing for us developers!

Yeah, but that's where the confusion should be, IMHO.

Best,

David
Re: In-place preview editing [ In reply to ]
David E. Wheeler wrote:
> On Feb 17, 2009, at 1:01 AM, Adrian Yee wrote:
>
>>> Hrm. But it'd just have to poll when it knew it was submitting a post,
>>> right? That doesn't sound so bad.
>>
>> Yup, the idea is to start polling once the iframed form has been
>> created and
>> posted. Once we get the response, then it stops polling.
>
> Yeah, that seems fine. We might want to put a timeout on it, though.

Good idea.

>> - You have the edit story page open while you edit the preview. After
>> you've
>> updated elements in the preview page, it now doesn't match the edit
>> story page.
>> I might be able to work around this by using javascript to tell the
>> edit page to
>> perform an update on an element, but I have to look into the whole
>> permissions
>> thing for this as well. Even if you can, this is messy too, since the
>> preview
>> control needs to poll the preview page for when to send refreshes back
>> to the
>> opening window. ughh!
>
> I don't think you need to worry about permissions getting the edit
> window to update its content. And if you can tie it to when the preview
> window closes, that might be good enough -- or at least a good place to
> start.

I'm not sure what the 'normal' flow is for a Bricolage story editor, but
at least when I'm playing around with it, I'll often keep both story
edit and preview windows open while I create a new story. I'll make my
changes in the edit window, then switch over to the preview and click on
Repreview.

The media upload popup already does something like this (makes the edit
window update its own element), so I think it shouldn't be a problem.

>> - You have have the story checked out, but you don't have the edit
>> story page
>> open. After you edit, you don't have any way to save your changes. One
>> possible solution is to put the save button on the control frame on
>> the preview
>> page. This will need some communication between the opener and the
>> preview
>> page. Lots of room for breakage here though. :(
>
> I say that if you don't have the window open, the changes are just
> saved. I think that will be the closest to DWIM for most users,
> especially if the control when you're editing a field in the preview
> window has a "save" button which has to be clicked when the edit is
> complete.

I don't like that as that produces a bit of inconsistency with how the
preview editing works. If you somehow accidentally close the edit
window, then suddenly the preview edit changes are saved immediately.

>> So the only thing the admin would need to do is be able to put the
>> static iframe
>> content somewhere on the preview server.
>
> I think I missed this. What is it?

I briefly mentioned it in a previous e-mail. The problem is that we
need to create the content of the iframe so that we can then modify or
create a form on that page for us to submit to the application server.
I'm not 100% sure if we can dynamically generate it without loading a
static page first.

Adrian
Re: In-place preview editing [ In reply to ]
On Feb 18, 2009, at 4:31 PM, Adrian Yee wrote:

> I'm not sure what the 'normal' flow is for a Bricolage story editor,
> but at least when I'm playing around with it, I'll often keep both
> story edit and preview windows open while I create a new story.
> I'll make my changes in the edit window, then switch over to the
> preview and click on Repreview.
>
> The media upload popup already does something like this (makes the
> edit window update its own element), so I think it shouldn't be a
> problem.

Right, exactly.

> I don't like that as that produces a bit of inconsistency with how
> the preview editing works. If you somehow accidentally close the
> edit window, then suddenly the preview edit changes are saved
> immediately.

Yeah…I guess it can go ahead and save the whole thing. What the hell.

>>> So the only thing the admin would need to do is be able to put the
>>> static iframe
>>> content somewhere on the preview server.
>> I think I missed this. What is it?
>
> I briefly mentioned it in a previous e-mail. The problem is that we
> need to create the content of the iframe so that we can then modify
> or create a form on that page for us to submit to the application
> server. I'm not 100% sure if we can dynamically generate it without
> loading a static page first.

I don't see why not. I've created all sorts of stuff dynamically in
JavaScript. :-)

Best,

David
Re: In-place preview editing [ In reply to ]
>>>> So the only thing the admin would need to do is be able to put the
>>>> static iframe
>>>> content somewhere on the preview server.
>>> I think I missed this. What is it?
>>
>> I briefly mentioned it in a previous e-mail. The problem is that we
>> need to create the content of the iframe so that we can then modify or
>> create a form on that page for us to submit to the application server.
>> I'm not 100% sure if we can dynamically generate it without loading a
>> static page first.
>
> I don't see why not. I've created all sorts of stuff dynamically in
> JavaScript. :-)

Yup, did some searching and it is possible. Yay, shouldn't need any
extra files now!

Adrian
Re: In-place preview editing [ In reply to ]
Hi ho,

Nothing super-substantial here, but my responses are inline:

On 17-Feb-09, at 6:48 PM, Alex Krohn wrote:

> Hi Phillip,
>
>> I've been trying to get my head around the use cases for this "in-
>> place preview editing" for days now. I've been following the thread,
>> and it's confusing as hell, for all the reasons that have come up re:
>> permissions, the story edit screen state, etc.
>
> The use case is when you have a well structured document that may be
> formed from a lot of elements (some documents have 100+ elements). You
> click preview and you notice a typo in a single field somewhere.
> Rather
> then having to close preview, find the element, make the change, and
> then re-preview, you simply click in the appropriate paragraph and
> make
> your change.


That makes sense.


> If your document simply uses a single wysiwyg field for the content,
> then this is really not that useful.


I could still see it as something useful in that scenario if you
weren't actually *in* Bricolage at the moment, and were able to spot a
typo and edit it directly on the site without logging in to
Bricolage... but that's probably a different use case entirely.


>> 1. Why would the user *need* to have _both_ the story edit UI and the
>> in-place preview open? If the user had the ability to edit previews,
>> wouldn't seem more likely that they'd simply click the preview link
>> from their workspace vs. clicking edit on the story, then the preview
>> link, etc.? Also, how would this work if the user clicked on a
>> preview
>> link from a desk, or a search, when they don't have the story checked
>> out? Would they expect to be able to preview it in that scenario?
>
> The editable preview is for simple fixes only. It does not allow you
> to
> add elements, move elements, add images, change images, or a host of
> other things. It is limited to a simple text field fixups.
>
> If the story is not checked out, then the story is not editable and
> the
> preview would also not be editable.


Though, if the underlying goodies are there, wouldn't it make sense
that any user with edit permissions for that story should be able to
edit it from any preview? Is there any real significant difference
from edit a checked out story vs. checking out and editing a story
from a preview pane? Just curious, as it seems like a useful use case.




>> 2. If they did *start* from the story edit UI and click the preview
>> link and then start editing, could the story edit UI be closed at
>> that
>> point? Or, if not closed, maybe forced into a greyed-out / modal
>> state
>> while the focus was on the preview window. Then, when focus returned
>> to the story edit UI, it could re-load all of story's data from the
>> updated / in-place edited version?
>
> That's the struggle we are having now. =) The big problem comes with
> javascript and trying to communicate from a remote server to the
> bricolage server. Adrian has outlined it in much more detail.


Yep, I'm following that part of the thread. But I guess I'm wondering
why the story edit UI needs to receive the information back from the
preview UI, i.e., if the story edit UI is locked from edits while
looking at the preview, could it not just reload when focus returns to
the story edit UI (whether it needs to or not?). No need to answer
that... just talking out loud.


>> Also, I keep wondering about users who are just browsing their
>> organizations Web site, finding a typo, and wanting to update / edit
>> it. And -- from that use case -- I keep thinking of the "Bricolite"
>> tool that Greg Heo built (which I hope he'll post online soon!),
>> which
>> allows bloggers access to a simple UI for editing "blog posts."
>
> I think there are a few issues with this:
>
> 1. It depends on a single wysiwyg type block for content, and wouldn't
> give you the wysiwyg edit feel if a story is put together from a lot
> of
> elements (i.e. broken down to the paragraph level).


Bricolite is just loading up the data in the XML document returned by
bric_soap and providing an edit UI for what's there (in this case,
only one content block). So that's what I'm noodling here... if you
worked with the XML document vs. the page's element data directly,
wouldn't that open up a bunch of different edit options?


> 2. You run into the same issue with having to install something on the
> preview server or another location, or have two separate
> authentications.


That is true.


> 3. The separate login doesn't really address the use case we are
> trying
> to solve. =)



:-) Cool. Thanks for the response. Excited to see what y'all come up
with. Sorry to stir the pot! ;-)

Phillip.

--
Phillip Smith // Simplifier of Technology // COMMUNITY BANDWIDTH
www.communitybandwidth.ca // www.phillipadsmith.com
Re: In-place preview editing [ In reply to ]
Sorry to have gone awol from this thread over the last couple weeks.
We had a site roll out and I was busy.

I'll admit, I'm more than skeptical about how this will work 1)
technically, and 2) from a usability standpoint.

The whole point of Bricolage is to separate layout from content. This
is essentially destroying that paradigm. It's adding a new editing
interface on top of what's there, and I think, complexity. Not saying
the current interface is anything to write home about. But as I said
before, thoughtfulness about this is of utmost importance.

On Feb 17, 2009, at 3:48 PM, Alex Krohn wrote:

> If the story is not checked out, then the story is not editable and
> the
> preview would also not be editable.

So is there now going to be a "Check Out" button on the top frame of
the preview? Because most people don't have things checked out when
they are going through that preview list. And if you have them check
things out, you may as well just send them to the regular interface
IMHO.

Sorry if I missed the solution to that.

-Matt
RE: In-place preview editing [ In reply to ]
I admit not reading all the devel emails lately, so sorry if this has
been covered, but I think in place editing is different than in-place
navigation to stories one wants to edit.

In place editing would be substantially more complex -- in fact, the
templates would have to explicitly interact with the in-place editing UI
in my opinion to identify the proper editing component for the content
the user wishes to edit. When combined with permissions, versions, etc.
it's going to be a huge undertaking.

Since the 2.x interface has been ajaxified, in theory, some components
of the existing editing UI could be overlaid on top of the content on
the preview page to allow for editing in place.

However, for starters, I think simply being able to pull up a story or
story element's standard Bricolage editing screen by navigating to that
story on the preview server would yield a substantial benefit. Links to
the bricolage editing screen could appear on top of content from that
story -- this would require some simple form of template tagging, but
would not be too difficult to retrofit existing templates.
Re: In-place preview editing [ In reply to ]
On Feb 25, 2009, at 10:05 AM, Beaudet, David wrote:

> Since the 2.x interface has been ajaxified, in theory, some components
> of the existing editing UI could be overlaid on top of the content on
> the preview page to allow for editing in place.

This is something we were storyboarding out yesterday as a matter of
fact.

What I would like to see in the near future is an edit tab containing
the content area. That is the default tab. It'll also have the
title. Then there would be a Details tab with the information,
categories, output channels, contributors, and key words.

We also talked about having a File tab dropdown with things like Check
in And . . . Revert to . . . - things like that would pop up a
lightbox window with further options.

And the final piece would be a preview tab, so you could preview
without moving screens.

Along with other things like ajax autosaving. So a lot of what we
talked about is aspirational, but I think that it is a good direction
to look in.

> However, for starters, I think simply being able to pull up a story or
> story element's standard Bricolage editing screen by navigating to
> that
> story on the preview server would yield a substantial benefit.

I would agree with this.

> Links to
> the bricolage editing screen could appear on top of content from that
> story -- this would require some simple form of template tagging, but
> would not be too difficult to retrofit existing templates.

Maybe then just add a checkout button to the top frame if you have
access?

1 2 3  View All