提交具有权限 "False" 的作品未更新为草稿模式。仅在实时模式下可用

Submit Piece with Permissions "False" not updated to Draft Mode. Only Available in Live Mode

此项目正在使用 Apostrophe-Workflow。因此,我为评论系统创建了自己的自定义模块,权限为 false(遵循此 comment system 但自己调整部分以供 non-logged 用户提交)。它成功并使用 non-logged 用户查看器提交到数据库。但是,当我登录并看到 non-logged 用户提交的条目时,empty/isn 不存在。 apostrophe-workflow 要求我在 non-logged 用户没有提交的情况下 提交 。明确地说,在 实时模式 中,我可以看到提交的评论。但在 草稿模式 中,什么都没有。它提示我提交更改(这意味着 commit/delete non-logged 用户评论)。这是我的作品 piece-widgets .

这里是 实时模式 (non-logged 用户成功提交评论 - Public) :

但是在草稿模式中查看时,您看不到public评论并且它在没有public评论的情况下要求提交(当点击提交时, 按钮不会消失) :

modules/comments/index.js中:

module.exports = {
    extend : 'apostrophe-pieces',
    name : 'comments',
    label : 'Comment Form',
    alias : 'commentForm',
    pluralLabel : 'All Comments',
    addFields : [
    {
        name: 'comments',
        label: 'Comments',
        type: 'array',
        sortify : true,
        schema: [
        {
            name: 'date',
            label: 'Date',
            type: 'date'
        },
        {
            name: 'readerName',
            label: 'Reader\'s Name',
            type: 'string',
            required: true
        }, {
            name: 'comment',
            label: 'Comment',
            type: 'string',
            textarea: true,
            required: true
        }]
    }],
    arrangeFields : [{
            name: 'comment',
            label: 'Comment',
            fields: ['comments']
        },
        {
            name: 'config',
            label: 'Comment Configuration',
            fields: ['title', 'slug', 'published', 'tags'],
            last: true
        }
    ],
    permissionsFields: false,
    construct: function (self, options) {

        self.addTask('update', 'Update Cursor for comment with data permissions false', function (apos, argv, callback) {
            var year = new Date().getFullYear();
            var month = (new Date().getMonth() < 12) ? "0" + new Date().getMonth() : new Date().getMonth();
            var day = (new Date().getDay() < 10) ? "0" + new Date().getDay() : new Date().getDay();
            var date = [
                [year],
                [month],
                [day]
            ];
            date.join('-');
            console.log("Array to string" , date.join('-'));

            const req = apos.tasks.getAnonReq();

            const idPiece = self.generate(1);

            self.apos.docs.getManager('comments').find(req)
                .criteria({
                    _id: idPiece
                })
                .sort({
                    updatedAt: 1
                })
                .log(true)
                .toArray(function (err, docs) {
                    if (err) {
                        return callback(null);
                    }
                    // fetch comment req.body
                    // generate new commentId

                    var comment = {
                        _id: self.apos.utils.generateId(),
                        date: date,
                        readerName: 'Reader Amin',
                        comment: 'Some comment'
                    };

                    // Hack method - Make it published when sucessful update
                    docs.published = true;

                    docs.forEach(doc => {
                        doc.comments.push(comment);
                        console.log("Success");
                        return self.apos.modules['comments']
                            .update(req, doc, {
                                permissions: false
                            }, function () {
                                console.log("Doc Update :", doc);
                                // Testing begins
                                self.apos.docs.getManager('comments').find(req)
                                    .criteria({
                                        _id: idPiece
                                    })
                                    .projection({
                                        title: 1,
                                        slug: 1,
                                        comments: 1,
                                        permissions: 1
                                    })
                                    .toArray((err, doc) => {
                                        if (err) {
                                            return setImmediate(callback);
                                        }
                                        doc.forEach(element => {
                                            console.log("element : ", element);
                                            return callback(null , element);
                                        })
                                    });
                                // End testing
                            });

                        // Then should update the module here using .update()
                    });
                });

        });

        self.addTask('list', 'List all comments with sorting', function (apos, argv, callback) {
            const req = apos.tasks.getAnonReq();
            return self.apos.modules['comments'].find(req)
                .sort({
                    updatedAt: 1
                })
                .projection({
                    title: 1,
                    type: 1,
                    slug: 1,
                    comments: 1,
                    permissions: 1
                })
                .toArray().then((doc) => {
                    // When anything output in array , you can do forEach
                    doc.forEach(element => {
                        // console.log("All comments", doc);
                        console.log("All comments", element);
                        return callback();
                    });
                });
        });

        // Create a post route /modules/comment-form/submit
        self.route('post' , 'submit' , function(req , res){
            // Get by pieces id
            self.apos.docs.getManager('comments').find(req)
            .criteria({
                _id: req.body.pieceId
            })
            .sort({
                createdAt : 1
            })
            .log(true)
            .toArray(function(err , docs){
                // fetch comment req.body
                // generate new commentId

                var comment = {
                    _id : self.apos.utils.generateId(),
                    date : req.body.date ,
                    readerName: req.body.readerName,
                    comment : req.body.comment,
                };

                // get docs . It will output as array.
                // therefore , it's easier to use forEach
                // Hack method - Make it published when sucessful update
                docs.published = true;

                docs.forEach(doc => {
                    doc.comments.push(comment);
                    self.apos.modules['comments']
                        .update(req, doc, {permissions : false}, function () {
                            console.log("Doc Update :" , doc);
                            return res.json({
                                status: 'okay'
                            });
                        });

                    // Then should update the module here using .update()
                });
            });
        });

    }
}

在我的 /modules/comments-widgets/public/js/always.js 中:

apos.define('comments-widgets' , {
    extend  :'apostrophe-widgets',
    construct : function(self , options){
        self.play = function($widget , data, options){
            // get form
            $widget.find("[data-button-submit]").on('click' , function(){
                var year = new Date().getFullYear();
                var month = (new Date().getMonth() < 12) ? "0" + new Date().getMonth() : new Date().getMonth();
                var day = (new Date().getDay() < 10) ? "0" + new Date().getDay() : new Date().getDay();
                var date = [
                    [year],
                    [month],
                    [day]
                ];
                date.join('-');
                var data = {
                    pieceId: $widget.find("form").attr("id"),
                    date :date.join('-'),
                    readerName: $widget.find("input[name='readerName']").val(),
                    comment: $widget.find("textarea[name='comment']").val()
                }

                var value = $widget.find("textarea[name='comment']").val();
                console.log("Comment Value" , value);
                $.ajax({
                    url : '/modules/comments/submit',
                    method : 'POST',
                    data : data,
                    success: function (result, status, xhr) {
                        console.log("Success POST" , result);
                    },
                    error: function (xhr, status, error){
                        console.log("Failed to POST");
                    }
                }).done(function(msg){
                    apos.change($widget);
                });

            });

        }
    }
})

/modules/comments-widgets/views/widget.html中:

{% for piece in data.widget._pieces %}
<form class="comment-widget" id="{{ piece._id }}" data-apos-pieces-submit-form>
<h4 class="Mont-Bold leave-comment">Leave a comment</h4>
    <input type="text" name="readerName" placeholder="Reader's Name">
    {# Must use fieldset with data.name on schema.name object #}
    <textarea name="comment" id="textarea-comment" cols="10" placeholder="Write a comment"></textarea>
<button class="submit" data-button-submit>Submit</button>
<div class="thank-you" data-apos-pieces-submit-thank-you>
    <h1>Done</h1>
</div>
</form>
<div class="comment-container">
    {% for piece in piece.comments %}
    <div class="comment-piece">
        <h4 class="reader-comment Mont-Heavy">{{ piece.readerName }} <span class="Mont-Regular" style="color : #0F58FF; font-size :14px ; letter-spacing : 0.20px; line-height : 19px;">- {{ piece.date | date("Do MMM YYYY") }}</span></h4>
        <p class="comment-paragraph Mont-Regular">{{ piece.comment }}</p>
    </div>
    {% endfor %}
</div>
{% endfor %}

逐步介绍如何在页面上创建添加评论

1.Create/Add评论表单并添加标题

2.On Pieces-Pages , Select 评论小部件和单独浏览

3.Select 我的评论文章创建了标题并完成了!


已更新

此代码无效。它以某种方式成功更新,但实时和草稿都没有更新。这是我使用您的解决方案的代码:

self.route('post', 'submit', function (req, res) {
      // Get by pieces id

        // get docs . It will output as array.
        // therefore , it's easier to use forEach
        // Hack method - Make it published when sucessful update

        self.apos.docs.getManager('comments').find(req)
            .criteria({
                _id: req.body.pieceId
            })
            .sort({
                createdAt: 1
            })
            .log(true)
            .toArray(function (err, docs) {
                // fetch comment req.body
                // generate new commentId

                var comment = {
                    _id: self.apos.utils.generateId(),
                    date: req.body.date,
                    readerName: req.body.readerName,
                    comment: req.body.comment,
                };

                // get docs . It will output as array.
                // therefore , it's easier to use forEach
                // Hack method - Make it published when sucessful update
                docs.published = true;

                self.apos.docs.db.update({
                    workflowGuid: self.apos.launder.id(req.query.workflowGuid)
                }, {
                    $push: {
                        comments: comment
                    }
                }, {
                    multi: true
                }, function (err, lol) {
                    if (err) {
                        return res.json({
                            status: 'error'
                        })
                    }
                    console.log(lol);
                    return res.json({
                        status: 'ok'
                    })
                });

                // docs.forEach(doc => {
                //     doc.comments.push(comment);
                //     self.apos.modules['comments']
                //         .update(req, doc, {
                //             permissions: false
                //         }, function () {
                //             console.log("Doc Update :", doc);
                //             return res.json({
                //                 status: 'okay'
                //             });
                //         });

                //     // Then should update the module here using .update()
                // });
            });
    })

如果您直接在实时语言环境中操作文档,则不会将其推回草稿语言环境。在撇号工作流中,内容从草稿流向实时,而不是相反。

一般来说,如果您要将评论作为数组 属性 附加到文档,那么您应该直接使用 mongodb 并利用 $push 运算符,而不是而不是通过 Apostrophe 的模型层。如果两个人试图在大约同一时间提交评论,这可以避免竞争条件。

并且如果您希望评论同时存在于草稿和实时语言环境中,那么您应该使用 doc.workflowLocale 将其标识为 MongoDB,而不是使用 doc._id,然后制作确保将 { multi: true } 传递给 apos.docs.db.update,如下所示:

apos.docs.db.update({
  workflowGuid: self.apos.launder.id(req.query.workflowGuid)
}, {
  $push: {
    comments: comment
  }
}, {
  multi: true
}, function(err) {
  // respond to the browser here
});

但是,数组属性不是实现注释的好方法。 MongoDB 有文档大小限制,无论每次打开文档时加载数百条评论都不是一个好的性能策略。您应该考虑为评论使用单独的片段类型并加入它们。

重要说明:如果您也使用工作流来实现本地化,那么您可能希望将这样的更新查询限制为仅 enen-draft,并非所有语言环境。或者不是,但请注意,如果您不这样做,它将影响许多语言。

好吧,我认为 Tom Boutell 是对的。草稿和实时模式是不同的文档。但是,我无法访问我的 public 评论数据,除非我按照下面的代码执行 excludeTypes。现在我明白了,如果您想在使用 Apostrophe-Workflow 时提交表单或评论或点赞。在实时模式下,如果您在 app.js 文件中设置此项,则可以访问数据:

    // WORKFLOW
    'apostrophe-workflow': {
      excludeTypes: ['comments' , 'likes' , 'contact-form'],
      alias: 'workflow'
    },

Then I can access all LIVE when trying to submit any form in LIVE mode ! So when using Apostrophe-Workflow , makes sure that you set any types or properties to exclude it for accessing data in LIVE MODE . If you submit your form in draft mode , you only get those data in draft mode , never in LIVE mode. And it will prompt you to submit/commit everytime you submit the form. You don't want that.