dhruba Posted August 25, 2013 Share Posted August 25, 2013 What is the best way to edit a page using API. Why we need to call $page->setOutputFormatting(false) before saving the page. Need some clarification. Link to comment Share on other sites More sharing options...
kongondo Posted August 25, 2013 Share Posted August 25, 2013 By default, output will be formatted according filters you may have defined with the field. If you are modifying the values of a page's custom fields, you will need to call $page->setOutputFormatting(false) before doing so. This turns off output formatting, which ensures that saved values don't already have runtime formatters applied to them. ProcessWire will throw an error if you attempt to save formatted fields. http://processwire.com/api/variables/page/ 6 Link to comment Share on other sites More sharing options...
MatthewSchenker Posted August 25, 2013 Share Posted August 25, 2013 Greetings, What makes ProcessWire so excellent is the ability to do all kinds of work at the API level, so that you can essentially create a custom admin for your projects. Editing a page is of course a crucial part of any custom admin. NOTES: Of course, you must cutomize this to your project. Also, in my code I am editing the page directly inside the page itself. In other words, you display a page as usual, but inside it you have your edit code, as well as code to save the page after editing. The other option would be to link to another page just for editing. Editing does get rather involved. Below is a technique I've used. I'll break editing down to several steps, then later I'll put it all together as one. Here goes... Step 1: Isolate Who Has Editing Rights You don't want anyone who can view the page editing it! I use code like this to limit editing to people with either an "editor" or "superuser" role. We open it here, and close it later in Step 6: <?php if ($user->isSuperuser() OR $user->hasRole("editor")) { Step 2: Set the $page Variables (Except Title) to Hold Edited Values Take inputs received from a submitted form and use those values to replace current $page values. For this example, I am only using two fields to keep it simple. And they are text fields. We hold off on setting the title, since that needs special handling: <?php if ($input->post->title) { $page->set("first_name", $sanitizer->text($input->post->first_name)); $page->set("last_name", $sanitizer->text($input->post->last_name)); } Step 3: Edit Title Field, but Only if the Title is Unique, Then Save the Page You need something like this so you don't get an error if the title you apply to the edited page collides with the title of an existing page. The code below confirms that the title is unique and allows you to set the title, and only then save the page: $thistitle = $page->title; $matchedtitle = $input->post->title; $checktitles = $pages->find("parent=/[path]/[to]/[parent]/, title=$matchedtitle|$thistitle"); $titlecount = count($checktitles); if($titlecount < 2) { $page->of(false); $page->set("title", $sanitizer->text($input->post->title)); $page->set("name", $sanitizer->text($input->post->title)); $page->save(); Step 4: Refresh URL Think about it... If while editing this page we changed the title, the URL you are on is no longer valid. Here's a simple bit of Javascript to handle this. The code below also closes out the conditional set in Step 3: $refresh=$page->url; ?> <script type="text/javascript"> window.location = '<?php echo $refresh ?>'; </script> <?php } Step 5: Handle the Scenario When the Page Title Collides In Step 3, we edited the page title because it passed the "unique" test. But what if it fails that test? We would move to this section of code, where a message lets the user know there is a problem. A bit of Javascript helps make the warning fade in so it is more noticeable: else { ?> <div class="admin_error_box"> <p>Sorry, there is already a page using this title: <?php echo $input->post->title?>!</p> <p>Please enter a different title in the form.</p> </div> <script> $(function() { $('.admin_error_box').hide().fadeIn(3000); }); </script> <?php } Step 6: The Edit Form We need a form to capture the submission of edits. It would look the same as your page-creation form, but would have to be pre-populated with the current values of the page, which will also change upon submission of the form. The last bit of code closes out the check on user roles set in Step 1: <div class="page_create_form_box"> <p class="form_heading">EDIT THIS PAGE USING THE FORM BELOW</p> <form action="<?php echo $page->url ?>" method="post"> <ul> <li><label class="label_class" for="title">Page Title:</label> <input type="text" class="input_class" name="title" value="<?php echo $page->title ?>"></li> <li><label class="label_class" for="first_name">First Name:</label> <input type="text" class="input_class" name="first_name" value="<?php echo $page->first_name ?>"></li> <li><label class="label_class" for="last_name">Last Name:</label> <input type="text" class="input_class" name="last_name" value="<?php echo $page->last_name ?>"></li> </ul> <button class="admin_submit" type="submit" name="submit">SAVE EDITED PAGE</button> </form> <?php } ?> Step 7: Putting it all Together Now let's put all of this code into one continuous routine. <?php if ($user->isSuperuser() OR $user->hasRole("editor")) { ?> <?php if ($input->post->title) { $page->set("first_name", $sanitizer->text($input->post->first_name)); $page->set("last_name", $sanitizer->text($input->post->last_name)); } $thistitle = $page->title; $matchedtitle = $input->post->title; $checktitles = $pages->find("parent=/[path]/[to]/[parent]/, title=$matchedtitle|$thistitle"); $titlecount = count($checktitles); if($titlecount < 2) { $page->of(false); $page->set("title", $sanitizer->text($input->post->title)); $page->set("name", $sanitizer->text($input->post->title)); $page->save(); $refresh=$page->url; ?> <script type="text/javascript"> window.location = '<?php echo $refresh ?>'; </script> <?php } else { ?> <div class="admin_error_box"> <p>Sorry, there is already a page using this title: <?php echo $input->post->title?>!</p> <p>Please enter a different title in the form.</p> </div> <script> $(function() { $('.admin_error_box').hide().fadeIn(3000); }); </script> <?php } ?> <div class="page_create_form_box"> <p class="form_heading">EDIT THIS PAGE USING THE FORM BELOW</p> <form action="<?php echo $page->url ?>" method="post"> <ul> <li><label class="label_class" for="title">Page Title:</label> <input type="text" class="input_class" name="title" value="<?php echo $page->title ?>"></li> <li><label class="label_class" for="first_name">First Name:</label> <input type="text" class="input_class" name="first_name" value="<?php echo $page->first_name ?>"></li> <li><label class="label_class" for="last_name">Last Name:</label> <input type="text" class="input_class" name="last_name" value="<?php echo $page->last_name ?>"></li> </ul> <button class="admin_submit" type="submit" name="submit">SAVE EDITED PAGE</button> </form> <?php } ?> My apologies for any problems with the formatting of the code above (please use your editor to assure proper tabs). Notes: - If you include checkboxes or other field types in your page, the editing is a bit more involved. - If you have image fields, you would have separate actions connected with those. For more information on handling image fields in custom forms, take a look at this: http://processwire.com/talk/topic/3105-create-pages-with-file-upload-field-via-api/ That should get you started! Follow up if you have more questions! Thanks, Matthew 16 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now