提交具有权限 "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 有文档大小限制,无论每次打开文档时加载数百条评论都不是一个好的性能策略。您应该考虑为评论使用单独的片段类型并加入它们。
重要说明:如果您也使用工作流来实现本地化,那么您可能希望将这样的更新查询限制为仅 en
和 en-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.
此项目正在使用 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 有文档大小限制,无论每次打开文档时加载数百条评论都不是一个好的性能策略。您应该考虑为评论使用单独的片段类型并加入它们。
重要说明:如果您也使用工作流来实现本地化,那么您可能希望将这样的更新查询限制为仅 en
和 en-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
orproperties
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 tosubmit/commit
everytime you submit the form. You don't want that.