Plots2: Add a new /preview route to open editor preview in new tab

Created on 13 Oct 2020  路  17Comments  路  Source: publiclab/plots2

Create a POST route at /editor/preview which simply renders a simulated "note" or "wiki page" using the Markdown in the "body" and "title" POST variables. Nothing is saved in the db, and we repoint all editor Preview buttons at this. (not sure about comment previews though, probably not those). We also make a Preview button for the rich editor pointed at this. All open in a new tab, and should use the [->] "open in new tab" icon from FontAwesome

Add "Preview" button next to the Publish button [ON WHICH EDITORS?] that opens a preview of your content in a new tab

feature

Most helpful comment

The editor_controller has actions defined related to rendering of 2 types of editor:

  1. Rich view editor
  2. legacy editor
    Hence the name editor_controller makes sense, right?

On the other hand notes_controller has 1 action in which we are interested that is show, which renders the actual POST made using editors (actual POST means rendering HTML).
Node is a general nomenclature used in plots2 which may mean any POST (wiki, notes, question, etc).
Now we have to again do the same job as done in show action but this time without saving anything to DB 馃槃

All 17 comments

For this, i'm thinking we could make a notes controller method for preview and then in the templates, we could do a @ node.title || params[:title] substitution for both title and body --

https://github.com/publiclab/plots2/blob/3664a280d660f6f059fbadfcd38f059129f7645f/app/views/notes/show.html.erb#L23

https://github.com/publiclab/plots2/blob/3664a280d660f6f059fbadfcd38f059129f7645f/app/views/notes/show.html.erb#L64

...but there are lots of references to @node on the template, so another way we could try would be to manually assemble a @node with a revision and author (current author) but not save any of it...? so it's just an instance variable and never entered in the database? That would mean no template changes needed, except perhaps for an alert message that it is just a preview?

we might also need to pass in the main_image URL as a parameter; it will have been uploaded and saved, so that should be OK...

Okay @jywarren that makes sense 馃憤
We have to add another button in /post editor page that will open a new tab and call this route, right?

Hi @sagarpreet-chadha I'd like to try this out...please assign it to me.

Hey @RuthNjeri , sure go ahead! I was just going to start on this myself :)
You may start with a different route /preview and pass the form details as body params and render the preview.
Let me know if you need any help 馃槃
Meanwhile I will ask @ebarry or @jywarren on where exactly we have to show this preview button, we can take that separately. Thanks 馃挴

This will be pretty interesting feature, we will also make sure that we write proper tests for this 馃槃
Let me know if you get stuck somewhere and maybe open the PR sooner in WIP state so we can track status, or you may open once you feel comfortable. No worries 馃槃

@sagarpreet-chadha thanks! I'll definitely reach out throughout!

Hi, @sagarpreet-chadha I'm working on understanding the task, I have a couple of questions..

The preview tab is meant for this editor page, right?
Screenshot 2020-10-15 at 18 00 49

And from this form, I'll pass the params to the preview route when the params have values? That is the title, image, location, markdown, and tags.

I don't understand how this relates to the notes controller.

Hey @RuthNjeri ,
Correct we will have a Preview button here, on clicking we will open a new tab and send all the information entered in the form (including image URL) in a POST request /preview.

Now corresponding to this route we will implement a controller function in Notes controller, action name can be preview.
This action will render a template/view (something.html.erb), right?

For this template/view, we can use the plots2/app/views/notes/show.html.erb template itself so that we do not have to duplicate the code. In order to use this template, we need to build a @node ruby param inside the controller function preview. However we will not save this @node variable inside DB.

The only change we will need to do inside plots2/app/views/notes/show.html.erb will be to show a banner that this is just a preview and not actual post made by you.

So I will break the tasks as well:

  • [ ] Make a route POST /preview and corresponding controller function previewPost in Notes controller.

  • [ ] This /preview route will have the same body params as that of /post route.

  • [ ] Inside previewPost we will make @node variable (similar to /post controller function but not saving this data in DB!)

  • [ ] Render the plots2/app/views/notes/show.html.erb and add a banner by passing some flag, which if true will show a banner: "This is a preview of your post, click PUBLISH to make this live!"

  • [ ] Add a button in /post or Rich wiki editor which will open this new preview in new tab.

  • [ ] Write tests 馃帀

I hope this helps 馃槃

@sagarpreet-chadha thanks, that helps a lot, I'm curious why the preview action should be defined in the NotesController...how does that relate to the EditorController?

Also, what's a node in this case?

The editor_controller has actions defined related to rendering of 2 types of editor:

  1. Rich view editor
  2. legacy editor
    Hence the name editor_controller makes sense, right?

On the other hand notes_controller has 1 action in which we are interested that is show, which renders the actual POST made using editors (actual POST means rendering HTML).
Node is a general nomenclature used in plots2 which may mean any POST (wiki, notes, question, etc).
Now we have to again do the same job as done in show action but this time without saving anything to DB 馃槃

Thanks, I'll use this info and start out with the first task and create a PR for it...

Hi @sagarpreet-chadha 馃憢馃従

I'm working on creating a manual node.. I am thinking of defining one in the node model file, similar to the new_note but without saving any details, since it creates the revision and author.

But I am not sure why revision is needed, because the body in the show view is defined as
<%= raw auto_link(insert_extras(@node.latest.render_body), :sanitize => false) %> but with the node manually defined, it might not be possible to do this since latest makes a query call to a saved revision.
So maybe it could be <%= raw auto_link(insert_extras(@node.latest.render_body || params[:body]), :sanitize => false) %>
as @jywarren mentioned..

So far what I think should happen for the manual definition is this...

    author = User.find(current_user.uid)
    @node = Node.new(uid:     author.uid,
                    title:   params[:title],
                    comment: 2,
                    type:    'note')
    @node.status = 4 if author.first_time_poster

Let me know if this makes sense so far..

Yes @RuthNjeri , you are going in the right direction 馃憤

Can you check this PR: https://github.com/publiclab/plots2/pull/8604, I have added a lot of TODO's (9-10 todo's 馃檲 ) and you will get idea of how I am thinking of mocking the model functions like has_power_tag and others.
I want to use '/show' view file only for making 'previews' because it will be easy to maintain and in this way we will have to do changes in one file only in future if we addd any new feature.
Feel free to work on this PR or fork your own branch from it 馃挴
Let me know if it makes sense or not 馃槃

Thanks @Sagarpreet I'll look at the PR and add my contributions to it.. in my case, I had just defined the preview action with some minor changes on the show template, you've done a much better job breaking down what is required. I'll first try and understand the PR then begin asking/adding onto it..

Hi all! this is awesome. Just to answer @RuthNjeri's Q about revisions, the body of all posts (nodes) is stored in a Revision record, so we have to mock that too. Unfortunately for us in this case, i believe the saving of both revision and node is interconnected, and in our case, we don't want to save either.

https://github.com/publiclab/plots2/blob/737f6fa9fc85774526689f0e90356f96bd6cc1a2/app/models/node.rb#L686-L690

See how normally, we check if a node is valid, then we begin creating its first revision, and we save the node... but we try to ensure that if the revision fails, it's in a "transaction" which then rolls back the node saving too -- this is a database feature for ensuring either both succeed or both fail. That way we're never left with a situation where a node exists with no revision!

In our case, i think we have to duplicate some of this code instead of relying on the transaction code, because w never want to save.

One of the tests might be a check to ensure the total count of nodes and revisions doesn't change! Just to be sure we aren't saving any records. That test could look like this:

https://github.com/publiclab/plots2/blob/737f6fa9fc85774526689f0e90356f96bd6cc1a2/test/functional/notes_controller_test.rb#L777-L779

Anyways, great work! @Sagarpreet I think we can make the preview system and tests first, and then later add the buttons, but yes, it would go on the /post page first, and maybe later the /wiki/new route? Let's be sure though that it opens in a new window!

Thanks for the clarification @jywarren, it's beginning to make much more sense now..

Was this page helpful?
0 / 5 - 0 ratings

Related issues

milaaraujo picture milaaraujo  路  3Comments

first-timers[bot] picture first-timers[bot]  路  3Comments

grvsachdeva picture grvsachdeva  路  3Comments

bronwen9 picture bronwen9  路  3Comments

keshavsethi picture keshavsethi  路  3Comments