Coder Social home page Coder Social logo

stevemcarthur / docpad-plugin-posteditor Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 0.0 2.09 MB

Docpad plugin that allows the saving and updating of posts/articles by a user. It provides the basis for an admin/CMS interface.

License: Other

CoffeeScript 93.13% HTML 6.87%
docpad-plugin docpad editor cms-interface cms

docpad-plugin-posteditor's Introduction

Post Editor Plugin for DocPad

Build Status NPM version NPM downloads

Docpad plugin that allows the saving and updating of posts/articles. It provides the basis for an admin/CMS interface.

Screen shot

It manages the saving and updating of posts and loading of existing posts for an editor interface. It does not provide the editor interface. It is editor interface agnostic. It assumes you have provided an editor on the client side with client code to request existing articles via the plugin's configured load url and save articles via the configured save url. The editor can be a simple textarea element or a full-blown text editor like CKeditor. The choice is yours.

The plugin will also save old versions of an article to a "versions" folder - thus maintaining a history of each post edited.

The plugin also (optionally) manually triggers the regeneration of a saved article and the home page. This is especially useful if you want to stop Docpad from regenerating the whole website on each save. It is also particularly relevant if you are storing articles and documents outside of the Docpad root/repo.

The plugin is designed to work with an existing authentication/login system - although it will work without any authentication as well. In truth, it is built to work in tandem with my other plugin, docpad-plugin-authentication. User name and user id is added to the metadata of the document saved.

Default configuration

    config:
        #custom metadata fields outside of the standard title,layout and tags.
        #Prevents the arbitrary addition of extra (unexpected) metadata fields.
        #A validation of user input.
        customFields: []
        #Location for version files. This also needs to be outside of the
        #docpad src folder so that version files are not generated or copied to the
        #out folder
        dataPath: null

        defaultLayout: 'post'
        postCollection: 'posts'
        defaultSavePath: 'posts'

        #retain previous version of post that is edited and move it
        #to a 'version' folder
        saveVersions: true
        loadURL: '/load/:docId'
        saveURL: '/save'
        #URL to manually trigger regeneration of post
        generateURL: '/generate'
        #whether to send rendered HTML to the client or raw markdown
        #wysiwyg editors will want the rendered HTML and then this edited content
        #will have to be converted back to markdown for saving back to the server
        sendRenderedContent: true
        #manually trigger post regeneration rather than let docpad do it automatically.
        #usefull when there is a custom regeneration path - ie when documents are stored
        #outside of the docpad application root/repo. In such a case docpad will regenerate
        #ALL documents regardless if standalone=true or referencesOthers=false.
        handleRegeneration: true
        #if handleRegeneration=true then force the home page to be generated after each post update
        generateHomePage: true

        sanitize: require('bleach').sanitize

        #remember to include the space character but not the tab (\t) or newline (\n)
        titleReg: /[^A-Za-z0-9_.\-~\?! ]/g

Example JS for loading an article/post

    function getPost(docId,slug) {
        var id = docId ? docId : slug;
        $.get('/load/' + id)
            .done(function (data) {
                $('#post-title').val(data.title);
                $('#slug').text(data.slug);
                $('#feature-img').attr('src', data.img);
                $('#docId').text(data.docId);
                var tags = $('#tags');
                for (var i = 0; i < data.tags.length; i++) {
                    tags.append('<li><a class="icon-cancel-circle"></a>' + data.tags[i] + "</li>");
                }

                CKEDITOR.instances.editor1.setData(data.content, {
                    callback: function () {
                        var btn = $('.cke_voice_label:contains("save")').parent();
                        btn.addClass('save-btn');
                    }
                });

            });
    }

Example JS for saving an article/post

    function postData() {
        var txt = downshow(CKEDITOR.instances.editor1.getData());
        var title = $('#post-title').val();
        var slug = $('#slug').text();
        var docId = parseInt($('#docId').text());
        var inputs = $('#tags li');
        var tags = [];
        inputs.each(function () {
            tags.push($(this).text());
        });

        //check we actually have something written
        //and that we have a title
        if (txt.length < 10) {
            alert("Write something first!");
        } else if (title.length < 2) {
            $('#title-callout').fadeIn();
            var titleCallout = function () {
                $('#title-callout').fadeOut();
                $(this).unbind('click', titleCallout);
            };
            $('#post-title').click(titleCallout);


        } else {
            $('#edit-loader').show();

            var obj = {
                content: txt,
                title: title,
                slug: slug,
                tags: tags,
                docId: docId
            };

            $.post('/save', obj)
                .done(function () {
                    $('#edit-msg').show();
                    $('#edit-loader').fadeOut(1000, function () {
                        $('#edit-msg').fadeOut(1000);
                    });
                })
                .fail(function (xhr, err, msg) {
                    $('#edit-loader').fadeOut(500);
                    $('#edit-msg').fadeOut(500);
                    alert(msg);
                });
        }

    }

Regeneration of saved posts

The plugin works by saving edited or new articles/posts directly to the file system. It then uses Docpad's inbuilt system for regenerating a page when the corresponding source file is modified. To give finer control over the regeneration process the plugin will manually trigger the regeneration of the document just updated. This works best when Docpad is run with the docpad server command rather than docpad run, otherwise the regeneration process will run twice. If you want docpad to handle all regeneration on its own (as normal), then set the config option handleRegeneration: false.

Converting HTML to Markdown

The plugin expects Markdown to be sent to the server. Typically, however, the general user will not know Markdown. Fair enough. So typically 'wiswyg' editors (like CKeditor) will work with HTML. So, to facilitate this, the plugin will send the rendered content (ie HTML) to the client. To send the content back to the server we need to convert the HTML back to Markdown. To do this I use the Downshow js library.

License

Licensed under the incredibly permissive MIT license

Copyright © 2016+ Steve McArthur [email protected] (http://www.stevemcarthur.co.uk)

docpad-plugin-posteditor's People

Contributors

stevemcarthur avatar

Stargazers

 avatar

Watchers

 avatar  avatar

docpad-plugin-posteditor's Issues

Author not being posted to the client

The loadDocuments helper does not send back an "author" property. This can lead to the author property of a document being removed when it is edited and sent back to the server.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.