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

[Feature] Post Preview Links (v2) #5097

Closed
ErisDS opened this Issue Apr 2, 2015 · 12 comments

Comments

Projects
None yet
6 participants
@ErisDS
Member

ErisDS commented Apr 2, 2015

This is a rework from the original spec/discussion in #4595


To start with, the problem we want to solve. There are two slightly different use cases here:

  1. Users commonly want to view a version of their post that has their theme and all of their embeds enabled so that they can see what the finished product is going to look like.
  2. Users commonly want to share a post with a few trusted people to get feedback before publishing.

Following on from the discussions that were had in #4595, lets implement post previews for our users with two different modes: private (default) and public (can be enabled/disabled). By default, the preview will be available to anyone who would normally be able to see the draft post according to the existing permissions system. If desired, the preview link can be converted to being public, and disabled when needed.

As these urls are going to be sharable, they should be short and pretty. Ideally something like
http://my-ghost-blog.com/p/c7djz - with the /p/ to make this easily identifiable as a preview URL and then a small number of random characters (as short as possible). We can achieve this by using something like the hashids package to create a hash from the post id, using the dbhash as the salt.

This URL should only work whilst the post is a draft, once published this URL should 301 to the proper URL. The preview route should add the private cache control header rule that we use for the admin and API, so that this page is never, ever cached as well. If the URL is in private mode, and the user doesn't have permission to see the post, the URL should respond with a 404 rather than a 403, I think.

In order to make it possible to switch between private and public mode, we'll need to add a new preview field to the posts table which defaults to private. This field would be used when handling the /p/ route to determine whether to require the user have permission to see the draft - I believe it should be possible to do this by passing in the logged in user as the context to the API when in private mode, and passing the internal context when in public mode.

The UI for getting the preview URL & the switch between private/public are still in the works. There will be a need to inject code into the preview using the ghost_head/foot mechanism so that we can clearly mark the view as a preview and perhaps include other UI elements. Therefore I think it makes sense to implement the private preview URL first, and then layer on the sharing functionality as a second piece.

@sebgie

This comment has been minimized.

Show comment
Hide comment
@sebgie

sebgie Apr 3, 2015

Contributor

Looks very good 👍!

a preview URL and then a small number of random characters (as short as possible)

I would not promote a short link because the link is public, but the post is not published. Having a differentiation between private and public preview was intended to help prevent user error. Short links could still be easy to guess. The link is going to be copied/pasted anyway.

Github Gist uses 20 chars which looks quite reasonable to me?

Contributor

sebgie commented Apr 3, 2015

Looks very good 👍!

a preview URL and then a small number of random characters (as short as possible)

I would not promote a short link because the link is public, but the post is not published. Having a differentiation between private and public preview was intended to help prevent user error. Short links could still be easy to guess. The link is going to be copied/pasted anyway.

Github Gist uses 20 chars which looks quite reasonable to me?

@novaugust

This comment has been minimized.

Show comment
Hide comment
@novaugust

novaugust Apr 3, 2015

Member

Github Gist uses 20 chars which looks quite reasonable to me?

By the time we're doing 20 chars, why not just expose the UUID? :)

Member

novaugust commented Apr 3, 2015

Github Gist uses 20 chars which looks quite reasonable to me?

By the time we're doing 20 chars, why not just expose the UUID? :)

@ErisDS

This comment has been minimized.

Show comment
Hide comment
@ErisDS

ErisDS Apr 3, 2015

Member

The 4/5 char concept was based on things like bit.ly and cl.ly - the URL is only public if it is converted to public by the user, and they can then disable this again.

I think this goes back to the original discussion - this is a feature for 90% of users, the users who need more security when sharing will need a different form of sharing (with specific people or email addresses etc) which is an extension of this feature that would sit well in an app.

Member

ErisDS commented Apr 3, 2015

The 4/5 char concept was based on things like bit.ly and cl.ly - the URL is only public if it is converted to public by the user, and they can then disable this again.

I think this goes back to the original discussion - this is a feature for 90% of users, the users who need more security when sharing will need a different form of sharing (with specific people or email addresses etc) which is an extension of this feature that would sit well in an app.

@JohnONolan

This comment has been minimized.

Show comment
Hide comment
@JohnONolan

JohnONolan Apr 6, 2015

Member

This can start life here:

image

Pretty sure that icon is already in core somewhere

Member

JohnONolan commented Apr 6, 2015

This can start life here:

image

Pretty sure that icon is already in core somewhere

@JohnONolan

This comment has been minimized.

Show comment
Hide comment
@JohnONolan

JohnONolan Apr 6, 2015

Member

This will probably need some further discussion, because this is painfully complex - but here's what I'm thinking so far:

I click on the "preview" link ^ above and a new window opens with a preview of my post. Whatever URL this preview appears on is accessible by anyone with >= Editor permissions.

Just before {{content}} a preview toolbar is injected:

image

Create a preview link

Clicking on "get preview link" generates a new short URL which is accessible to anyone who has the link. This can be copied/pasted or disabled. If disabled, we revert to screenshot 1 above. If the "get preview link" is clicked again - a new short URL is created and the old one is invalid. (NB: @ErisDS I don't think preview links need to be 301'd to final posts - they should always be ephemeral)

image

View preview link

If I view this preview-link as anybody except the author of the post, the preview toolbar shows a simple notification:

image

Notes

To avoid style-clashes with the theme:

  • This is deliberately simple black / not a giant multi-coloured CTA
  • This will probably need to be implemented as an iframe injection, to avoid inheriting any styles
  • iFrames aren't responsive so will need something like this
  • Other embed options welcome (I don't know any, myself)
Member

JohnONolan commented Apr 6, 2015

This will probably need some further discussion, because this is painfully complex - but here's what I'm thinking so far:

I click on the "preview" link ^ above and a new window opens with a preview of my post. Whatever URL this preview appears on is accessible by anyone with >= Editor permissions.

Just before {{content}} a preview toolbar is injected:

image

Create a preview link

Clicking on "get preview link" generates a new short URL which is accessible to anyone who has the link. This can be copied/pasted or disabled. If disabled, we revert to screenshot 1 above. If the "get preview link" is clicked again - a new short URL is created and the old one is invalid. (NB: @ErisDS I don't think preview links need to be 301'd to final posts - they should always be ephemeral)

image

View preview link

If I view this preview-link as anybody except the author of the post, the preview toolbar shows a simple notification:

image

Notes

To avoid style-clashes with the theme:

  • This is deliberately simple black / not a giant multi-coloured CTA
  • This will probably need to be implemented as an iframe injection, to avoid inheriting any styles
  • iFrames aren't responsive so will need something like this
  • Other embed options welcome (I don't know any, myself)
@ErisDS

This comment has been minimized.

Show comment
Hide comment
@ErisDS

ErisDS Apr 6, 2015

Member

Would it be possible to move the preview bar to the top of the page? I realise there is likely good reason for its current location, however from a technical perspective putting the toolbar just above {{content}} results in some complication 😞

Injecting at the top or bottom is relatively straightforward due to us always knowing where that is within the DOM. Injecting it right above {{content}} limits us to using the content helper to do the injection. I think it would result in a much cleaner implementation if we do the injection at render time - that is, we can render the theme template, get that back as a string and perform either String or DOM manipulation on it before serving it up. This method would keep us from having to do odd things to make this work with the theme API.

Using the content helper is absolutely a possibility here, just not preferable, IMO.

Member

ErisDS commented Apr 6, 2015

Would it be possible to move the preview bar to the top of the page? I realise there is likely good reason for its current location, however from a technical perspective putting the toolbar just above {{content}} results in some complication 😞

Injecting at the top or bottom is relatively straightforward due to us always knowing where that is within the DOM. Injecting it right above {{content}} limits us to using the content helper to do the injection. I think it would result in a much cleaner implementation if we do the injection at render time - that is, we can render the theme template, get that back as a string and perform either String or DOM manipulation on it before serving it up. This method would keep us from having to do odd things to make this work with the theme API.

Using the content helper is absolutely a possibility here, just not preferable, IMO.

@JohnONolan

This comment has been minimized.

Show comment
Hide comment
@JohnONolan

JohnONolan Apr 6, 2015

Member

can do, yeah - exact same concept just a 100% width bar across the top of the screen

Member

JohnONolan commented Apr 6, 2015

can do, yeah - exact same concept just a 100% width bar across the top of the screen

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 27, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Probably should go behind labs?
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)
@novaugust

This comment has been minimized.

Show comment
Hide comment
@novaugust

novaugust Apr 28, 2015

Member

So, my POC became somewhat more serious in an effort to break out the implementation of this into three seperate phases

Implementation Phases

  • Preview for all posts (via uuid)
  • Preview toggleable per-post
  • Preview via an obfuscated hash, removing uuid from api

As with all new features, we also need to think about

  • labs settings
  • a style comb-over

The problem with hashids

Preview for all posts is implemented in #5158. We initially set out with the hope of also implementing hashids via the hashids library, but ran into some problems with that. The issue happened on the client: how could we construct the post's preview url without knowing the salt used on the server?

  • pass the salt through to the client :(
  • create a new "preview_url_for" sort of endpoint on the api :(
  • change the serialized versions of drafts to include the preview url we couldn't see a safe way to share the hashing salt across :(
  • ??

So, that needs some consideration.

Member

novaugust commented Apr 28, 2015

So, my POC became somewhat more serious in an effort to break out the implementation of this into three seperate phases

Implementation Phases

  • Preview for all posts (via uuid)
  • Preview toggleable per-post
  • Preview via an obfuscated hash, removing uuid from api

As with all new features, we also need to think about

  • labs settings
  • a style comb-over

The problem with hashids

Preview for all posts is implemented in #5158. We initially set out with the hope of also implementing hashids via the hashids library, but ran into some problems with that. The issue happened on the client: how could we construct the post's preview url without knowing the salt used on the server?

  • pass the salt through to the client :(
  • create a new "preview_url_for" sort of endpoint on the api :(
  • change the serialized versions of drafts to include the preview url we couldn't see a safe way to share the hashing salt across :(
  • ??

So, that needs some consideration.

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 28, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Probably should go behind labs?
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 28, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Probably should go behind labs?
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 28, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Probably should go behind labs?
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 28, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 28, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- prev/next post helpers only activate on published posts
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- prev/next post helpers only activate on published posts
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- prev/next post helpers only activate on published posts
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- prev/next post helpers only activate on published posts
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- prev/next post helpers only activate on published posts
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)

novaugust added a commit to novaugust/Ghost that referenced this issue Apr 30, 2015

Add post preview via uuid (/p/:uuid)
Refs TryGhost#5097

- All drafts will show a preview link (this needs real css)
- Published posts will redirect
- prev/next post helpers only activate on published posts
- Powered by ~10 pints between the two of us (@ErisDS, @novaugust)
@probus

This comment has been minimized.

Show comment
Hide comment
@probus

probus Jun 6, 2015

There should be a way to customize templates for preview to exclude scripts you don't want to run.

I have a small javascript in the post template that creates a comment topic for the post on a related discourse forum and fetches any comments back for displaying. Now it gets run when previewing unfinished posts and generates a public topic for comments before the post is published. There might be also other scripts (analytics etc.) that you don't want to run in preview.

probus commented Jun 6, 2015

There should be a way to customize templates for preview to exclude scripts you don't want to run.

I have a small javascript in the post template that creates a comment topic for the post on a related discourse forum and fetches any comments back for displaying. Now it gets run when previewing unfinished posts and generates a public topic for comments before the post is published. There might be also other scripts (analytics etc.) that you don't want to run in preview.

@srajkovic

This comment has been minimized.

Show comment
Hide comment
@srajkovic

srajkovic Jun 22, 2015

It looks like a PR for at least the /p/:uuid got merged into master?

So if I wanted to test out this functionality, how would I go about getting the UUID for a post? I'd be happy to test it out and give feedback!

srajkovic commented Jun 22, 2015

It looks like a PR for at least the /p/:uuid got merged into master?

So if I wanted to test out this functionality, how would I go about getting the UUID for a post? I'd be happy to test it out and give feedback!

@ErisDS

This comment has been minimized.

Show comment
Hide comment

@ErisDS ErisDS referenced this issue Jun 30, 2015

Closed

Ghost 0.7 Overview #5503

13 of 31 tasks complete
@ErisDS

This comment has been minimized.

Show comment
Hide comment
@ErisDS

ErisDS Jan 16, 2017

Member

Closing this for now, we can reopen when we decide to prioritise improving the preview feature.

Member

ErisDS commented Jan 16, 2017

Closing this for now, we can reopen when we decide to prioritise improving the preview feature.

@ErisDS ErisDS closed this Jan 16, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment