This project is using Apostrophe-Workflow . Therefore , I created my own custom module for comment system with permissions false (Follow this comment system but adjust the piece myself for non-logged user submission). It was successful and submitted to database with non-logged user viewer. However , when I logged in and see pieces items submitted from non-logged user , it's empty/isn't there. And apostrophe-workflow asking me to commit without non-logged user submitted . To be clear , in Live Mode , I can see submitted comments. But in Draft Mode , nothing. And it prompts me to commit the changes (Which means to commit/delete non-logged user comments). Here is my piece and piece-widgets .
In 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()
});
});
});
}
}
In my /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);
});
});
}
}
})
In /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 Comment Form & Add a Title
2.On Pieces-Pages , Select Comment Widget & Browse Individually
3.Select my comment piece that created the title and DONE !
This code does not work . It somehow successful update but both live and draft are not updated . Here is my code using your solution :
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()
// });
});
})
Well , I think Tom Boutell was right . Draft and Live mode is a different docs. However , I can't access my public comments data unless I do excludeTypes
as below code. Now I understands , If you want to submit your form or comments or likes pieces WHILE using your Apostrophe-Workflow . In live mode , you can access the data if you set this on your app.js file :
// 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.