Possible to use Contour to save document (i.e. update existing document)
Hi list,
I am trying to use Contour as a kind of board (for buying/selling/exchange things). For that purpose I would like that people can update their post. For instance if the price has changed.
Can I use the "Save as Umbraco document" workflow for this? I can´t get any xpath to do the job since it creates a new document as the child of my xpath expression.
How do I make it overwrite/update a given node instead?
I am trying to make one that is inspired by Tim's "Contour Workflow - Save to Page Specified in Form Field". He has published the source code of PublishFormAsPage.cs. I'd like to call it UpdateFormAsPage.
Now what I am trying is to understand is how I can get to the Id of the current document. The edit form has pre-filled default values e.g. [#bodyText] but after submitting instead of the form creating a new node, I want to update the current document.
Document d = new Document(Node.GetCurrent().Id);
gives the error
Compiler Error Message: CS0104: 'Property' is an ambiguous reference between 'umbraco.cms.businesslogic.property.Property' and 'umbraco.NodeFactory.Property'
I used to get by with XSLT only, but now I am taking steps into C#, which is unfamiliar to me. Could anyone point me in the right direction?
I found a solution to this problem. I had included umbraco.Nodefactory but this seemed to cause problems with umbraco.cms.businesslogic when calling properties. By not adding "using umbraco.Nodefactor" and directly getting the id of the current node it all works.
int root = umbraco.NodeFactory.Node.GetCurrent().Id; Document d = new Document(root);
A few more adjustments and I'll have a working UpdateFormAsPage.cs custom workflow.
Lately I've been working on yet another project that relies on Contour and customisation of field types, workflows, and conditional form fields. Which part of my code would you like to see? What functionality are you after?
I am making a member profile area with a listing of member owned/managed pages.
So need to create new nodes from the form (this is straight fwd) adding these to the member profile page... And then later they will edit this node, and was hoping to simply have contour form on an alt template of the node being edited (populating the form with page fields).
Was interested in making a 'preview changes' state in there also, but not 100% about this most likely outputing values from contour entry and then on edit send back to form or on confirm send the status to approved and publish the node with changes.
Yes I did and I have a pretty good working model, but it's not particularly portable at present.
I'm happy to help you with a run down on the workflow and pieces to the puzzle, but have a deadline at present so can let you know in the next few days.
Below is the Workflow I formulated... it was a while back now so will try to explain briefly;
This workflow creates a doc of type to a given root location or updates the page identified by ID given in the value of RecordField "Node".
Essentially having a 2 way connection between Umbraco Node and Umbraco form Record.
Use the form in edit mode to update the node (saves the record fields to the node if it exists already) or not edit mode (blank form) to create a new doc/node of type to the root location.
After the form was submitted we fwd to a preview page (altTemplate) to display the record from the Umbraco forms db.
By attaching an approval action for the record to a PUBLISH button click, the workflow runs and saves/updates the node into the public website.
With a BACK button on the preview page, this allowed any number of edits before the node was saved or updated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic.property;
using umbraco.cms.businesslogic.propertytype;
using Umbraco.Forms.Core;
using Umbraco.Forms.Core.Enums;
using Umbraco.Forms.Data;
using Umbraco.Forms.Data.Storage;
using System.Web;
using Advertising;
namespace RDL.Contour.WorkFlows
{
public class AddOrUpdateFormAsPage : WorkflowType
{
public AddOrUpdateFormAsPage()
{
this.Id = new Guid("6c064290-16a8-4fc7-b86a-464d878cb81e");
this.Name = "Save as umbraco doc - Add or Update page from form";
this.Description = "Saves the form as an umbraco node with a specific type, or updates the node with matching Record Guid.";
}
[Umbraco.Forms.Core.Attributes.Setting("Document Type", description = "Map document type", control = "Umbraco.Forms.Core.FieldSetting.DocumentMapper")]
public string Fields { get; set; }
[Umbraco.Forms.Core.Attributes.Setting("Publish", description = "Publish document instantly", control = "Umbraco.Forms.Core.FieldSetting.Checkbox")]
public string Publish { get; set; }
[Umbraco.Forms.Core.Attributes.Setting("Field containing node id", description = "The field in the form that contains the node id of the page to save under", control = "Umbraco.Forms.Core.FieldSetting.FieldPicker")]
public string RootNode { get; set; }
public override WorkflowExecutionStatus Execute(Record record, RecordEventArgs e)
{
Dictionary<string, string> mappings = new Dictionary<string, string>();
int dtId = 0;
int root = -1;
if (record.RecordFields.ContainsKey(new Guid(RootNode)))
{
int.TryParse(record.RecordFields[new Guid(RootNode)].ValuesAsString(), out root);
}
if (root == 0)
root = -1;
string nameMapping = "NodeName";
string[] array = Fields.Trim().Split('|');
//Log.Add(LogTypes.Custom, 0, String.Join("|",Fields.Trim().Split('|')));
foreach (string s in array)
{
string[] a = s.Trim().Split(',');
if (a.Count() == 1 && s.Trim().Length >= 4)
{
if (dtId == 0)
int.TryParse(s.Trim(), out dtId);
}
else if (a.Count() == 3)
{
string mapping = "";
if (!string.IsNullOrEmpty(a[2]))
mapping = record.RecordFields[new Guid(a[2])].ValuesAsString();
else if (!string.IsNullOrEmpty(a[1]))
mapping = Umbraco.Forms.Core.Services.WorkflowService.parseAttribute(e.Context, record, a[1]);
// MAP EMPTY STRINGS BUT NOT THOSE WITHOUT ALLOCATED FIELDS
//if(!string.IsNullOrEmpty(mapping))
//{
if (a[0] == "__nodeName")
nameMapping = mapping;
else if (!string.IsNullOrEmpty(a[1]) || !string.IsNullOrEmpty(a[2])) // MUST HAVE ALLOCATED FIELD / VALUE
{
mappings.Add(a[0], mapping);
//Log.Add(LogTypes.Custom, 0, "mapping: " + a[0] + " - " + mapping);
}
//}
}
}
DocumentType dt = new DocumentType(dtId);
if (dt != null)
{
RecordField nodeField = record.GetRecordField("Node");
string nodeStr = nodeField.ValuesAsString();
// Set Doc to either currently set or create new
Document d = !String.IsNullOrEmpty(nodeStr) && nodeStr.Trim()!="" ? new Document(Convert.ToInt32(nodeStr)) : Document.MakeNew(nameMapping, dt, new umbraco.BusinessLogic.User(0), root) ;
foreach (Property p in d.getProperties)
{
try
{
if (mappings.ContainsKey(p.PropertyType.Alias))
{
//Log.Add(LogTypes.Custom, 0, "Running: " + p.PropertyType.Alias);
// Trim whitespace from checkboxlist
if (p.PropertyType.Alias == "relatedCats" || p.PropertyType.Alias == "tags")
{
mappings[p.PropertyType.Alias] = mappings[p.PropertyType.Alias].Replace(", ",",");
}
// Cleanup all past images + copy new into live dir
if ((p.PropertyType.Alias == "adSwf" || p.PropertyType.Alias == "adImage")
&& System.IO.Path.GetFileName(p.Value.ToString()) != System.IO.Path.GetFileName(mappings[p.PropertyType.Alias]))
{
Log.Add(LogTypes.Custom, 0, "File Cleanup: " + p.Value.ToString() + " - " + mappings[p.PropertyType.Alias]);
if (!String.IsNullOrEmpty(p.Value.ToString()) && System.IO.File.Exists(HttpContext.Current.Server.MapPath(p.Value.ToString())))
{
System.IO.File.Delete(HttpContext.Current.Server.MapPath(p.Value.ToString()));
Log.Add(LogTypes.Custom, 0, "File Deleted: " + p.Value.ToString());
p.Value = String.Empty;
}
if (!String.IsNullOrEmpty(mappings[p.PropertyType.Alias]))
{
string dir = "/media/_uploads/_live/";
string newFileName = dir + System.IO.Path.GetFileName(mappings[p.PropertyType.Alias]);
if (!System.IO.Directory.Exists(HttpContext.Current.Server.MapPath(dir)))
System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(dir));
System.IO.File.Copy(HttpContext.Current.Server.MapPath(mappings[p.PropertyType.Alias]), HttpContext.Current.Server.MapPath(newFileName));
Log.Add(LogTypes.Custom, 0, "File Copied: " + newFileName);
mappings[p.PropertyType.Alias] = newFileName;
}
}
p.Value = mappings[p.PropertyType.Alias];
// Let's see what we've got...
//Log.Add(LogTypes.Debug, 0, p.PropertyType +" - "+ p.PropertyType.Alias+": "+p.Value+" - New: "+mappings[p.PropertyType.Alias]);
}
}
catch (Exception ex)
{
LogHelper.Debug(ex.ToString());
}
}
d.Text = nameMapping;
d.Save();
d.Move(root);
if (Publish == true.ToString())
{
d.Publish(new umbraco.BusinessLogic.User(0));
umbraco.library.UpdateDocumentCache(d.Id);
}
umbraco.library.RefreshContent();
// Update the field in Contour
nodeField.Values.Clear();
nodeField.Values.Add(d.Id);
RecordStorage rs = new RecordStorage();
rs.UpdateRecord(record, e.Form);
rs.UpdateRecordXml(record, e.Form);
rs.Dispose();
}
return WorkflowExecutionStatus.Completed;
}
public override List<Exception> ValidateSettings()
{
return new List<Exception>();
}
}
}
Possible to use Contour to save document (i.e. update existing document)
Hi list,
I am trying to use Contour as a kind of board (for buying/selling/exchange things). For that purpose I would like that people can update their post. For instance if the price has changed.
Can I use the "Save as Umbraco document" workflow for this? I can´t get any xpath to do the job since it creates a new document as the child of my xpath expression.
How do I make it overwrite/update a given node instead?
Regards,
Martin
Comment author was deleted
Updating an existing document isn't possible with the default workflows, but you could make a custom one...
Hi Tim,
Thanks for your reply. Sounds like a good approach which I will give a try.
Regards,
Martin
I am trying to make one that is inspired by Tim's "Contour Workflow - Save to Page Specified in Form Field". He has published the source code of PublishFormAsPage.cs. I'd like to call it UpdateFormAsPage.
Now what I am trying is to understand is how I can get to the Id of the current document. The edit form has pre-filled default values e.g. [#bodyText] but after submitting instead of the form creating a new node, I want to update the current document.
gives the error
Compiler Error Message: CS0104: 'Property' is an ambiguous reference between 'umbraco.cms.businesslogic.property.Property' and 'umbraco.NodeFactory.Property'
I used to get by with XSLT only, but now I am taking steps into C#, which is unfamiliar to me. Could anyone point me in the right direction?
Regards,
León
I found a solution to this problem. I had included umbraco.Nodefactory but this seemed to cause problems with umbraco.cms.businesslogic when calling properties. By not adding "using umbraco.Nodefactor" and directly getting the id of the current node it all works.
A few more adjustments and I'll have a working UpdateFormAsPage.cs custom workflow.
@León - how did you get on with this?
Am looking to do the exact same thing, would you consider sharing your workings?
Thanks so much ;)
Hi Josh,
Lately I've been working on yet another project that relies on Contour and customisation of field types, workflows, and conditional form fields. Which part of my code would you like to see? What functionality are you after?
Cheers,
León
Hi Leon, Awesome thanks....
I am making a member profile area with a listing of member owned/managed pages.
So need to create new nodes from the form (this is straight fwd) adding these to the member profile page...
And then later they will edit this node, and was hoping to simply have contour form on an alt template of the node being edited (populating the form with page fields).
Was interested in making a 'preview changes' state in there also, but not 100% about this most likely outputing values from contour entry and then on edit send back to form or on confirm send the status to approved and publish the node with changes.
Your thoughts?
Thanks
Josh
Hi, Josh!
Did you ever figure this out? I'm trying to do the same thing as you describe...
Thanks,
Christopher
Hi Christopher
Yes I did and I have a pretty good working model, but it's not particularly portable at present.
I'm happy to help you with a run down on the workflow and pieces to the puzzle, but have a deadline at present so can let you know in the next few days.
Cheers
Josh
Great, thanks! :-)
Hi Guys,
I am in your exact situation where I need to edit existing nodes/pages through umbraco forms.
Can you please share your workings please, so I can see how I can change it for my situation?
Thank you, appreciate.
Kind Regards.
Hi Simon
Below is the Workflow I formulated... it was a while back now so will try to explain briefly;
This workflow creates a doc of type to a given root location or updates the page identified by ID given in the value of RecordField "Node".
Essentially having a 2 way connection between Umbraco Node and Umbraco form Record.
Use the form in edit mode to update the node (saves the record fields to the node if it exists already) or not edit mode (blank form) to create a new doc/node of type to the root location.
After the form was submitted we fwd to a preview page (altTemplate) to display the record from the Umbraco forms db.
By attaching an approval action for the record to a PUBLISH button click, the workflow runs and saves/updates the node into the public website.
With a BACK button on the preview page, this allowed any number of edits before the node was saved or updated.
is working on a reply...