Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A new entry preview for the backend #218

Closed
yellowled opened this issue Sep 19, 2014 · 35 comments
Closed

A new entry preview for the backend #218

yellowled opened this issue Sep 19, 2014 · 35 comments

Comments

@yellowled
Copy link
Member

This might even be “far future”. It is by no means critical or blocking for any release.

The current implementation of previewing an entry in the backend (using an iframe) is clumsy, prone to error and likely to make developing backend and frontend themes only harder in the future. See 5ee2f4b and comments for an example. It has also historically always been hard for frontend theme authors to get the preview_iframe.tpl quite right. We've had occurrences where a mysterious empty spacer div appeared in the backend preview etc.

We should come up with an easier solution for an entry preview for the new backend, maybe just using a frontend preview?

This definitely needs discussion, which should be held in the forums. I'm just putting this here for future reference (yes, that means “so we don't forget about it”).

@yellowled yellowled added this to the Future milestone Sep 19, 2014
@yellowled yellowled modified the milestones: x.0.0, Future Jan 22, 2015
@garvinhicking garvinhicking modified the milestones: 2.x.0, x.0.0 Jan 22, 2015
@garvinhicking garvinhicking self-assigned this Jan 22, 2015
@garvinhicking
Copy link
Member

I was having a go at this today and was thinking: This should be easy enough, just instead of creating a preview, create a new window.open() popup with the normal frontend and show the entry data as such.

But this proves as really really painful; the saving of entries is done with iframes, not only previewing, to make sure that a save does not block editing an entry and can be performed in the background. Also, if you preview, the entry may not be saved in the database, but we need to transport the data.

I tried to go the short-route and make the preview iframe create a window.open() request to the blog's frontend, and wanted to fetch the sesison data to display the blog entry. But such window.open() requests in the iframe return are blocked by the browser. So a lot of users would no longer see a preview of the entry, unless told to unblock it in their browser (which, let's face it, a lot of users willnot understand). Plus, modern browsers don't allow to "focus" a popped up window that lives as a new tab, at least "preview_window.focus()" doesn't seem to work.

This here is my simple diff:

https://gist.github.com/garvinhicking/5aa581920139f4847d59

but I believe this will lead to nothing useful in rea-life :-(

@garvinhicking garvinhicking removed their assignment Jan 29, 2015
@yellowled
Copy link
Member Author

I would really like to see a “true frontend preview” here. However, since I'm not a PHP coder, I can't say whether this is technically possible in s9y.

Could we have a “ghost article” in the database which can never be published and is only used to create a frontend preview of the article the user is currently editing? That “ghost article” would only be visible to logged in users, and the preview would simply open this ghost article in a new tab.

(I imagine this is more complicated in a multi-user context, though.)

@garvinhicking
Copy link
Member

Not possible because multiple editors could create multiple entries that await preview, yes

@garvinhicking
Copy link
Member

(Plus, the challenge really is "open in a new tab". Browsers block this, very effectively)

@yellowled
Copy link
Member Author

Bummer. Multiple “ghost entries” that only exist temporarily would be a performance issue, I assume?

(But we can do that for published entries.)

@garvinhicking
Copy link
Member

I think this is a dead-end route; we cannot save the data in the database, it must be drawn from temporary data inside the user's session data, else it would really pollute the database.

Ideally, the "click" on the preview button should not execute a POST to the page itself, but open the preview window directly. But that would change a LOT of the "save entry" functionality, this would mean a near-total rewrite of the whole entry saving procedure; too complicated for me to perform, I think this will break more than it fixes.

If there only was a way to properly open the popup without the browser interfering, within the iframe. :(

@yellowled
Copy link
Member Author

That's why my original idea was to avoid iframe for the preview altogether. Using iframe usually leads to a world of pain.

@onli
Copy link
Member

onli commented Jan 29, 2015

For me the iframe sucks not because it is an iframe and on the same page like the editor. I don't really care for the new popup. The current iframe-preview sucks because we simulate the frontend partly in the preview template.

The right way to do it is to let the frontend render the entry, then take that entry, and show it somehow - that could be perfectly fine in an iframe then.
So, the idea to just make a POST to the frontend with temporary data sounds good to me.

So, can we combine the new approach and the iframe one? Point the iframe to the frontend and use session data to render the entry there (while blocking sidebars, comment section and footer).
That way, we'd have a real frontend preview without changing the entry save flow and could still get rid of the preview_iframe.tpl.

@garvinhicking
Copy link
Member

There's no way to embed the frontend inside an iframe; which is why the preview_iframe was created in first place.

This would mean that every existing frontend template would not work in a "new" iframed preview, and we would basically be building the same thing that already exists (preview_iframe.tpl IS the blog's theme content without footer and sidebars :-))

@onli
Copy link
Member

onli commented Jan 29, 2015

There's no way to embed the frontend inside an iframe;

Why? Is there an iframe access protection I don't know?

On a click on preview, we call the core. He sets the content of entry-form into SESSION variables and creates an iframe like that: <iframe src=/archives/preview-NOTITLE> (adapted to the actual entry path). In the frontend, we make sure he still routes to serendipity_printEntry. In printEntry however we fill the smarty variables with the content of the SESSION variables instead of hitting the database for them.

preview_iframe.tpl IS the blog's theme content without footer and sidebars :-)

That is not what I see in https://github.com/s9y/Serendipity/blob/a2130e3d89e9423f629c0cc6b4186c178ee7e9d7/templates/2k11/preview_iframe.tpl

I see that it has its own head, even modified to point to admin files. And I see custom js doing stuff.

That current tpl-approach could be salvaged if we separate the entry head out of the entries.tpl and in general do nothing else there than calling frontend templates. But I don't see that being easier than just calling the frontend directly.

@garvinhicking
Copy link
Member

Templates simply don't have an option to omit header / sidebars from the output, that'S what I mean with "no way to embed the frontend". We can of course always embed it FULLY, but that won't fit inside an iframe in most cases.

The preview_iframe usually was meant to recreate the frontend template with the whole structure that is required for the usual CSS to render the blog entry only, without headers, sidebars and footers.

In 2k11 and some other themes it got munged to print additional output in admin layout, that's where the lines began to blur.

We can't really seperate entries.tpl, we always need the index.tpl part of an entry too, but then all the header etc. will be emitted.

@ophian
Copy link
Member

ophian commented Apr 1, 2015

I lost track of this, but I just fell over this with 2.0.1:
choose another template like next,
saving an entry gives you the 2k11 preview file with the appended templates/next/style.css in serendipity.css and this all for the "Your Entry has been saved" with link message.
This is clumsy!
https://github.com/s9y/Serendipity/blob/2.0/templates/2k11/preview_iframe.tpl

@garvinhicking
Copy link
Member

What's your proposal?

@garvinhicking
Copy link
Member

(Note that the iframe at this point does not know if it shows a preview or "just" the saving message)

@yellowled
Copy link
Member Author

This is clumsy!

This is why I referenced this issue from #302. See comment by @donchambers there – it is actually not only clumsy but kind of an issue because those messages might not get styled properly because they are part of the preview.

I don't know if that's possible with a feasible amount of effort, but ideally, the messages for the preview should not be part of the preview so that they get styled by the backend stylesheet, if that makes any sense at all.

@ophian
Copy link
Member

ophian commented Apr 1, 2015

What's your proposal?

Avoid the iframe at all on entry save.
We have a (green) success message on top which could get build with an entry frontend link by id, couldn't we?
I fell over this since my theme had a totally dark background set for html. Having an iframe here for saving issues just makes no sense at all (at least if you don't have trackback messages).
The preview is working just fine, since it take the correct themes preview tpl file and its styles.

@garvinhicking
Copy link
Member

Have you read this entry and checked my comments on why the iframe is actually a benefit for saving entries, because it decouples the action of saving from the originating HTTP request in case errors occur and the entry would otherwise be lost?

@garvinhicking
Copy link
Member

Ah I see this thread doesn't hold these comments, probably I made them on the forum or somewhere else.

The save process sends pingbacks etc. and can easily stall or timeout. Which is why the iframe takes care of the saving so when an error occurs, the usual backend with the current entry would still be there, and feedback is sent directly. XML-RPC methods and trackbacks can take up anything from 1 to 60 seconds, and users might think something failed when they don't get any output. So we definitely need a method of decoupling the process, and I honestly don't think how this can easily be done without breaking a lot more things (see above).

@donchambers
Copy link
Member

While I am probably unable to contribute to the solution from a technical perspective, I would be more than happy to test the hell out of any proposed solution!

@ophian
Copy link
Member

ophian commented Apr 1, 2015

Ok, thats a point.
But it still does not tell me why it takes 2k11 with the other themes styles. It should best use 2k11 iframe_preview.tpl with some really simple css for html, body, #page, #content, some link stylings and so on... on $mode == 'save', without all that other stuff it would need for mode 'preview' then.

@garvinhicking
Copy link
Member

Yeah but preview_iframe.tpl is used for both the preview and saving. It would mean we'd need a "preview_iframe.tpl" and "save_iframe.tpl" for the future maybe. save_iframe.tpl would use the backend CSS and preview_iframe.tpl the frontend CSS.

However it would mean also rewriting parts of the iframe creation because the way it is now the file is rendered and prepared the same for both.

I'd be happy to give feedback on possible implementations and together with @donchambers test them

@donchambers
Copy link
Member

It should not use 2k11's preview_iframe.tpl at all if a theme provides one of its own. And it shouldn't presume any particular theme has specific ID names such as #page, #content, etc.

@ophian
Copy link
Member

ophian commented Apr 1, 2015

Yeah but preview_iframe.tpl is used for both the preview and saving. It would mean we'd need a "preview_iframe.tpl" and "save_iframe.tpl" for the future maybe. save_iframe.tpl would use the backend CSS and preview_iframe.tpl the frontend CSS.

No. To get an idea of what I mean (watch out for {if $mode != 'save'} cases):

<head>
    <meta charset="{$head_charset}">
    <title>{$CONST.SERENDIPITY_ADMIN_SUITE}</title>
    <meta name="generator" content="Serendipity v.{$serendipityVersion}">
    <meta name="viewport" content="width=device-width, initial-scale=1">
{if $mode != 'save'}
{if $template_option.webfonts == 'droid'}
    <link  rel="stylesheet" href="//fonts.googleapis.com/css?family=Droid+Sans:400,700">
{elseif $template_option.webfonts == 'ptsans'}
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=PT+Sans:400,400italic,700,700italic">
{elseif $template_option.webfonts == 'osans'}
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic">
{elseif $template_option.webfonts == 'cabin'}
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Cabin:400,400italic,700,700italic">
{elseif $template_option.webfonts == 'ubuntu'}
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ubuntu:400,400italic,700,700italic">
{elseif $template_option.webfonts == 'dserif'}
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Droid+Serif:400,400italic,700,700italic">
{/if}
    <link rel="stylesheet" href="{$serendipityHTTPPath}{$serendipityRewritePrefix}serendipity.css">
    <script src="{serendipity_getFile file="admin/js/modernizr-2.8.3.min.js"}"></script>
{/if}
{serendipity_hookPlugin hook="backend_header" hookAll="true"}
{if $mode != 'save'}
    <script src="{serendipity_getFile file='admin/js/plugins.js'}"></script>
    <script src="{serendipity_getFile file='admin/serendipity_editor.js'}"></script>
{else}
    <link rel="stylesheet" href="{serendipity_getFile file='admin/simple_preview.css'}">
{/if}
....

and so on This could get very small on output for the "save" mode. And it is very simple to implement!

@ophian
Copy link
Member

ophian commented Apr 1, 2015

It should not use 2k11's preview_iframe.tpl at all if a theme provides one of its own.

Generally yes, and could be easily implemented by adding the https://github.com/s9y/Serendipity/blob/master/include/functions_config.inc.php#L837 to both preview file cases, but not in this case IMHO, since that would mean to rewrite every themes preview file to fit the needs. It is much more easy to just make the default theme (2k11) fit the "save" mode case, like shown above.

@garvinhicking
Copy link
Member

Cool! Feel free to submit the patch, we can then check it out!

On 01.04.2015, at 16:00, Ian notifications@github.com wrote:

It should not use 2k11's preview_iframe.tpl at all if a theme provides one of its own.

Generally yes, and could be easily implemented by adding the https://github.com/s9y/Serendipity/blob/master/include/functions_config.inc.php#L837 to both preview file cases, but not in this case IMHO, since that would mean to rewrite every themes preview file to fit the needs. It is much more easy to just make the default theme fit the "save" mode case, like shown above.


Reply to this email directly or view it on GitHub.

@ophian
Copy link
Member

ophian commented Apr 2, 2015

Garvin, would this page need any of the js tweaks we use? To say, what else does mode "save" create than some error/success messages and some external links to the entry and the trackbacks?

@onli
Copy link
Member

onli commented Apr 2, 2015

The one thing we/you have to look out for is the js used to set the id of the entry. Otherwise, the save mode does not use any JS I think.

@onli
Copy link
Member

onli commented Apr 2, 2015

Oh, it uses the JS for the cache of course, the entry cache is invalidated in that box I think when saving the entry.

@ophian
Copy link
Member

ophian commented Apr 2, 2015

Isn't the xml-rpc stuff and the id created before? I am only talking about modifying the tpl and I already tested the example above with a normal page (no trackbacks), which worked well without any js.
The serendipity.eraseEntryEditorCache() thing is bad placed though. Does that mean we would need to load jquery and editor.js because of this? I'd be happy to avoid this...

@onli
Copy link
Member

onli commented Apr 2, 2015

I'm not sure anymore whether it is still like this, or it only was like this. But when writing a new entry, you don't have an id in the entry editor form. As soon as the entry is generated, the id is generated, and I vaguely remember there existed the approach to break out of the save iframe to set the new entry id in the entry editor form, so edits after the save will edit the entry, not create a new one. That would affect the tpl.

Does that mean we would need to load jquery and editor.js because of this? I'd be happy to avoid this...

Yes. I don't think it is possible to avoid this, as I don't see other opportunities to execute the JS on entry save.

@ophian
Copy link
Member

ophian commented Apr 2, 2015

Hmm bad... I definitely need more info to not break something.

And there also is this for upcoming 2.0.2 a8b0aeb I am not sure - except for the cache buster, why Garvn did not easily use $serendipity['smarty_preview'] = true; (see link in other post) for mode save too.

Too much to be thought of to commit a lightweight patch...

@garvinhicking
Copy link
Member

It would be required to check all backend_save and backend_publish hooks in all event plugins of core and spartacus to see what is used there. Basically removing js funcs there would mean a BC break and be documented. Honestly I don't think dropping js would be good; too much work to check compatibility and possibly break stuff, and why? The js is cached so it wouldnt really impact the iframe there I think...

On 02.04.2015, at 11:04, Ian notifications@github.com wrote:

Isn't the xml-rpc stuff and the id created before? I am only talking about modifying the tpl and I already tested the example above with a normal page (no trackbacks), which worked well without any js.
The serendipity.eraseEntryEditorCache() thing is bad placed though. Does that mean we would need to load jquery and editor.js because of this? I'd be happy to avoid this...


Reply to this email directly or view it on GitHub.

@onli
Copy link
Member

onli commented Jan 15, 2016

Still something we want to pursue? I was kind of happy with the current state the last year.

@yellowled
Copy link
Member Author

As much as I would like a different way to implement the preview, it seems technically next to impossible as far as I understand the discussion. :-/

@onli
Copy link
Member

onli commented Jan 15, 2016

Then I'll close here for now

@onli onli closed this as completed Jan 15, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants