Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I like the idea of enabling any user of my website to suggest edits to a page. Much like the edit system on Stack Exchange but different in that anyone should be able to edit, not just registered users. All edits would go through an approval process.

How could I implement that?

share|improve this question
1  
I don't know how to do it, but I think this might be really problematic. I think you will get a lot of spam. –  moose Mar 13 '13 at 18:39
3  
Are you positive that you require a WordPress installation for your website? The functionality you desire sounds a lot like a MediaWiki installation. You should weight the pros and cons of both installations. MediaWiki is a good alternative. –  Marc Dingena Mar 15 '13 at 9:59
    
I was bouncing around with this idea a while back. The closest to a solution available was this plugin: wordpress.org/support/plugin/post-forking It is however in very early stages. The plugin is restricted to registered users. –  Christine Cooper May 5 '13 at 0:10

3 Answers 3

up vote 9 down vote accepted
+50

Diff the post content, title and author

As had to do something related some month ago, here's the easiest and most future proof way (that I could fine) to check if there's a change made to the content or title or if the author changed:

// Update Title
'' !== wp_text_diff(
    $el['post_title'],
    $GLOBALS['post']->post_title
)
    AND $GLOBALS['post']->post_title = $el['post_title'];
// Update Content
'' !== wp_text_diff(
    $el['post_content'],
    $GLOBALS['post']->post_content
)
    AND $GLOBALS['post']->post_content = $el['post_content'];
// Update author
$GLOBALS['post']->post_author !== $el['post_author']
    AND $GLOBALS['post']->post_author = $el['post_author'];

To explain my scenario briefly: I was fetching posts from a remote location via a remote API. Then I returned the global $post, during a single post loop, containing either the original data or the new data. This way I moved around setting all the other post values that I didn't need to check for changes.

Proposing the edit

The main fact one has to keep in mind when searching a place where a copy-edit of the post content could be (temporarily) saved is that the content is a db entry of longtext. So the place where one wants to save the suggested edit should meet that requirement. Comments do that.

Then there's the nice fact that they offer an API to place them nicely in a loop, so it integrates smoothly, is highly customizable and can quickly be setup. Last but not least most themes already come with comments integrated so it's easy to piggyback on the system and hook into nearly any available theme.

I'd suggest to just (either) extend or alter the comment form. Use either the following or add additional fields with a callback hooked to comment_form_default_fields.

<?php
// Add it for logged in users and guests:
add_action( 'comment_form_logged_in_after', 'wpse_proposed_edit_textarea' );
add_action( 'comment_form_after_fields', 'wpse_proposed_edit_textarea' );
function wpse_proposed_edit_textarea()
{
    ?>
    <p class="comment-form-title">
        <label for="wpse_propsed_edit">
            <?php _e( 'Propose Edit', 'your_textdomain' ); ?>
        </label>
        <textarea name="wpse_propsed_edit" id="wpse_propsed_edit">
            <?php the_content(); ?>
        </textarea>
    </p>
    <input type="hidden" name="comment_approved" id="comment_approved" value="0" />
    <?php
}

So I've added a hidden field for comment_approved with an value of 0 to set it in the queue. Not sure if this will work or if this (core) value is actually comment meta data and needs to get added by using add_comment_meta() during saving. If not, you could use something along the following lines of code

add_filter( 'pre_comment_approved' , 'wpse_pre_suggest_edit', 100, 2 );
function wpse_pre_suggest_edit( $approved , $commentdata )
{
    // You might need to inspect $commentdata 
    // to determine approval, disapproval, or spam status
    if ( ! empty( $commentdata['wpse_propsed_edit'] ) )
    {
        # Now add a filter to the comment post action, so we save a meta entry
        add_action( 'comment_post', 'wpse_set_proposed_edit' );
        return 0;
    }

    return 1;
}

// This function makes it easier for us to identify the comments by their meta value
function wpse_set_proposed_edit( $comment_id );
{
    // Only run once
    remove_filter( current_filter(), __FUNCTION__ );

    add_comment_meta( $comment_id, 'proposed_edit', true, true );
}

Displaying the comments on the admin side

Here I'd go with a simple class extension and a custom admin page:

function wpse_add_proposed_edits_admin_page()
{
    add_menu_page(
        'Proposed Edits',
        'Suggested Edits',
        'activate_plugins',
        'proposed_edits',
        'wpse_proposed_edits_page_cb'
    );
}
add_action( 'admin_menu', 'wpse_add_proposed_edits_admin_page' );

function wpse_proposed_edits_page_cb()
{
    $proposed_edits_table = new WP_Proposed_Edits_Table();
    $proposed_edits_table->prepare_items(); 
    $proposed_edits_table->display(); 
}

class WP_Proposed_Edits_Table extends WP_List_Table
{
    // Override List table default logic in here
}

More info can be found on WPEngineer.

Approving edits

You could then add custom actions and process the proposed edits using the first code I showed to check if there was a change and then simply update the post. The comment itself holds a value with a key of comment_post_ID, so identifying the edited posts ID is straight forward.

Final note

I'd like to see the final plugin as well. Please link it here :)

share|improve this answer
1  
I give the bounty to this question for the idea to use comment meta to store the suggested edit and wp_text_diff() for the actual comparison. Upvotes for the other answers. –  toscho May 8 '13 at 19:26

My idea is something simple.

  • You can make an Edit Suggestion link at bottom of posts that has a custom defined template, in that use a textbox (maybe with an editor) that's linked to a custom taxonomy with the default value of post content.

  • Any changes to content will be compared to original post content after submitting (as Draft) and Entering CAPTCHA code with Diff algorithms like PHP inline-diff package or Text-Diff PEAR Package or alternatively using a PHP function according to this for not too-long texts with combination of CSS.

  • Then by saving values in 3 custom Meta Boxes (in that taxonomy back-end add/edit page) that show

    1. Original Content
    2. Edited Version
    3. User nickname and His Email

    and saving Post ID maybe with a update_option() function for later use.

  • After reading edited version and acceptance by admin, that post will be replaced the original one as you coded in functions.php.

share|improve this answer
    
Some notes: (A) "as you coded in functions.php" - don't agree with this one. This is plugin material. (B) "linked to a custom taxonomy with the default value of post content" - A taxonomy term/taxon has only one possible value where content would fit in any case: The description. And then you'd need a place to store the post ID. Where would this be? As there's no place for this due to the limits of WPs tax system, you could only save the term ID. Then this is a (limited) one way system only: Post > Term data. –  kaiser May 9 '13 at 15:05

Well this is rather complicated, a proper answer would take considerable time to write. So this isn't a real answer just some thoughts..

Using WordPress build in wp_update_post via ajax would give you the needed revision history but not the capability needed to approve edits.

Creating drafts from edits is not possible by default but has been discussed here, Is there any way to draft a revision of a published page or post? What workarounds have you used?

You can try and use Front-end Editor but you will have no control over edits being published, so try and mash it with with another plugin like Revisionary which does allow for permissions based edits, I have no idea if they will work together.

If they don't you will have to hack a plugin based on the 2 above plugins or write something from scratch.

My scratch approach would be to have a button that goes to another page that outputs the post content/data using JSON, which is easier to work with when using Ajax and WYSIWYG editors. The save button would post as a draft instead of publish and that way you would have control over the edits (see above WPSE discussion on how to accomplish this, it's rather daunting).

There are additional complications when doing this such as sanitization, encoding, spam, media handling, custom fields, timestamps, memory, etc. The good news is that wordpress already has a revision system you can plug into and a decent ability to handle multiple editors.

ps. This is a good idea for a plugin.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.