Style Differently Edited Posts

Is there any way to add class to edited posts in order to style them differently?
If there is a way to do that without adding a class, this option would be much better.

EDITED – IGNORE THE ABOVE QUESTION – SEE BELOW

Read More

Is there a way to add a check box (meta box) in the area that a user writes an article/post so when this is checked a class will be added on the specific post (in loop and in single post page)? If something like this way is impossible, is there a way to get this done with a custom field? If both are possible I would prefer the first way.

Related posts

Leave a Reply

3 comments

  1. This is very similar to @mrwweb’s answer, but a little bit more fleshed out. We’re also not going to overload taxonomies in order to get our post class, but do what you wanted initially: use a custom meta box.

    There is a built in template tag called post_class. Like almost every other function in WordPress you can control its output via a filter.

    Step one: add the meta box.

    This is done via add_meta_box. If you’re wondering what the arguments are, you can head on over to the codex — the docs are very good. The thing to be concerned about is the third argument which specifies a callback function — the callback is what renders the HTML. To add the meta box we’ll hook into add_meta_boxes_post and call add_meta_box.

    Here’s the whole deal:

    <?php
    add_action('add_meta_boxes_post', 'wpse52122_meta_box');
    /*
     * Adds a meta box on the post editing screen.
     *
     * @uses add_meta_box
     */
    function wpse52122_meta_box()
    {
        add_meta_box(
            'wpse52122-box',
            __('Add Custom Style', 'wpse52122'),
            'wpse52122_meta_box_cb',
            'post',
            'side',
            'low'
        );
    }
    
    
    /*
     * Callback function for the meta box added above. This is what renders the 
     * boxes HTML.
     *
     * @uses get_post_meta
     */
    function wpse52122_meta_box_cb($post)
    {
        $meta = get_post_meta($post->ID, '_wpse52122_style', true);
        wp_nonce_field('wpse52122_nonce', 'wpse52122_nonce', false);
        echo '<p>';
        echo '<label for="wpse52122_style">' . __('Edited?', 'wpse52122') . '</label> ';
        echo '<input type="checkbox" name="wpse52122_style" id="wpse52122_style" ' .
             checked($meta, 'on', false) . ' />';
        echo '</p>';
    }
    

    Now we need to actually save that stuff when the post is saved. You hook into save_post to do that:

    <?php
    add_action('save_post', 'wpse52122_save_post');
    /*
     * Hooked in `save_post` this is the function that will take care of saving the
     * checkbox rendered above
     *
     * @uses update_post_meta
     * @uses wp_verify_nonce
     * @uses current_user_can
     */
    function wpse52122_save_post($post_id)
    {
        // no auto save
        if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) 
            return;
    
        // can the current user edit this post?
        if(!current_user_can('edit_post', $post_id))
            return;
    
        // Do we have our nonce?
        if(!isset($_POST['wpse52122_nonce']) ||
            !wp_verify_nonce($_POST['wpse52122_nonce'], 'wpse52122_nonce')) return;
    
        // if the the box is set, save meta key with 'on' as the value.
        $val = isset($_POST['wpse52122_style']) && $_POST['wpse52122_style'] ?
                    'on' : 'off';
        update_post_meta($post_id, '_wpse52122_style', esc_attr($val));
    }
    

    Finally, hook into post_class to add your ‘edited’ class. Your hooked function will get three arguments, we’re concerned with the first and last: the array of post classes and the post id respectively.

    <?php
    add_filter('post_class', 'wpse52122_post_class', 10, 3);
    /*
     * Hooked into `post_class` this function adds the class 'edited' to the
     * post_class array if the meta value `_wpse52122_style` is set to 'on'
     *
     * @uses get_post_meta
     * @return array The Post classes
     */
    function wpse52122_post_class($classes, $class, $post_id)
    {
        if('on' == get_post_meta($post_id, '_wpse52122_style', true))
        {
            $classes[] = 'edited';
        }
        return $classes;
    }
    

    Done! All that seems like quite a bit of work, however. So why not just hook into post_class and compare the post_created_gmt and post_modified_gmt?

    <?php
    add_filter('post_class', 'wpse52122_post_class_alt', 11, 3);
    /*
     * Filter the post_class and add the class edited if the post_date_gmt & 
     * post_modified_gmt don't match up.
     *
     * @uses get_post
     * @return array The post classes
     */
    function wpse52122_post_class_alt($classes, $class, $post_id)
    {
        $post = get_post($post_id);
        if(!$post) return $classes;
        $created = strtotime($post->post_date_gmt);
        $mod = strtotime($post->post_modified_gmt);
        if($mod > $created)
        {
            $classes[] = 'edited-alt';
        }
        return $classes;
    }
    

    Here is all of that as a plugin.

  2. Basically what you want to do is write either a function, or a small plugin (not so challenging if you know php).

    To have you code fired at the right time, you can hook into an action or filter that will happen when a post is updated.

    If you are not sure what that means, you should read up on wordpress.org on how to write plugins, and see the Action and Filter API’s. The main difference between actions and filters is that a filter lets you change some data. In your case that is interesting, because the filter wp_insert_post_data allows you access to all of the post content and metadata before it is stored in the database.

    This means you could use the content to compare to the content that is already stored to see if this is a substantial edit, or just a small one. Of course you could implement a feature where the user can choose, or top it all and do both, like a checkbox that will turn on if the editor content differs by more than 15 characters from the stored post, but will not change state anymore once the user has checked/unchecked it manually.

    However I would keep it simple for a first version and just do a comparison in php and add the right class automatically. That is considerably simpler to implement and probably more desirable than needing the user to decide on this consciously.

    So, technically it comes down to this:

    1. Create a hook on the wp_insert_post_data filter.
    2. Compare the new content to that already in the database
    3. If changed substantially, add some identifier to the post in the database
    4. In your theme, call post_class to check the database and add the desired class
    5. In your theme css, define a new look for these edited posts

    Regarding 3, note that wp doesn’t keep classes in the database, they are generated at runtime when pages are generated. You want to keep some durable info linked to the post though, so you need to add something. I think you have the choice between a custom meta field or the existing status field. The latter might have some complications in the sense that if you change articles status from published to edited say, you might have to check what all the consequences of that are. Potentially wordpress code or plugins count on posts being “published” to do certain things.

    Now, I don’t know what your php skill is. If you need more explanation let me know and I can elaborate those five points in a bit more detail. Otherwise, codex.wordpress.org has all the explanation you need.

    Ps: Don’t forget that programming is 75% error handling. For example wp_insert_post_data will also fire when a new post is created and obviously checking the database for a previous version will not give you a sensible result to compare with. Things like that should be obvious, but I think for a lot of people they aren’t. In essence, think scenarios. Try to conceive all possible input your code could get and try to consciously do the best thing you can in every situation.

  3. A custom meta box with a checkbox field would probably work best, but the easiest solution I can think of is this:

    1. Create an “Edited” category.
    2. Make sure you are using post_class() on the wrapper element of each article/post/page.*
    3. Add a CSS rule that looks for .category-edited class on the post wrapper (or .category-{ID}, which is safer if the “edited” slug ever changes).

    The post_class() function (read about it on the Codex) is a template tag used in theme files. It’s put on the wrapping element for each post in a loop. It can be on any HTML element, but common ones are div, article (HTML5 only), and li. Using the class looks like this:

    <article <?php post_class(); ?>>
        <!-- stuff like the_title() and the_content() goes here. -->
    </article>
    

    Post_class() then generates something like “class=’post post-23 category-events'”.