include multiple attachments with different types in the same transformation

Farah El Agha asked on November 28, 2017 09:04

hello guys, I am using a custom attachment field to attach Images into my transformation, the below code explains it all, the problem is that I tried to add another attachment field for Files but it didnt work, what is the right format that I should be using in order to include more than one attachment field and display each in a separate div in the transformation?

< script >

protected override void OnInit(EventArgs e) {

CMS.DataEngine.DataClassInfo dci = CMS.DataEngine.DataClassInfoProvider.GetDataClassInfo(Eval("ClassName").ToString(), true);

if (dci != null)
{

  CMS.FormEngine.FormInfo fi = new CMS.FormEngine.FormInfo(dci.ClassFormDefinition);
  // field name we added in the page type
  CMS.FormEngine.FormFieldInfo ffi = fi.GetFormField("Images");  
  Guid AttachmentGroupGUID = ffi.Guid;
  ucDocAttachments.Path = Eval < string > ("NodeAliasPath");
  ucDocAttachments.AttachmentGroupGUID = AttachmentGroupGUID;
  ucDocAttachments.TransformationName = "CMS.Root.Attachment";
  ucDocAttachments.ReloadData(true);
}

}

< /script >

<%@ Register Src="~/CMSModules/Content/Controls/Attachments/DocumentAttachments/DocumentAttachments.ascx" TagName="DocumentAttachments" TagPrefix="cms" %>

< div class="innerSelectedElectionContainer col-xs-12" >

  < div class="col-xs-12 selectedElectionInfo " >
    < div class="col-xs-12 selectedElectionTitle ">
     <%# Eval("Title") %>
    < /div>

     <div class="col-xs-12 selectedElectionText selectedElectionInfo" >
    <%# Eval("Text") %>
    </div>
     </div>
    <div class="selectedElectionInfo " style="display: flex; flex-wrap: wrap;"> 



      <a class="imageItem" target="_blank" href="<%# GetAbsoluteUrl(GetAttachmentUrl(Eval("AttachmentName"), Eval("NodeAliasPath")), EvalInteger("AttachmentSiteID")) %>">

      <cms:DocumentAttachments ID="ucDocAttachments" runat="server" /></a>


    </div>

Correct Answer

Mariia Hrytsai answered on November 28, 2017 14:59

Do you use Basic repeater or Repeater? If Basic repeater is used what is DataSource?

Here is my test transformation (the same as yours) with test page type: And it is okay to use two controls. <%@ Register Src="~/CMSModules/Content/Controls/Attachments/DocumentAttachments/DocumentAttachments.ascx" TagName="DocumentAttachments" TagPrefix="cms" %>

<script runat="server">

protected override void OnInit(EventArgs e) {
  CMS.DataEngine.DataClassInfo dci = CMS.DataEngine.DataClassInfoProvider.GetDataClassInfo(Eval("ClassName").ToString(), true);
  if (dci != null)
  {

    CMS.FormEngine.FormInfo fi = new CMS.FormEngine.FormInfo(dci.ClassFormDefinition);
    // field name we added in the page type
    CMS.FormEngine.FormFieldInfo ffi = fi.GetFormField("Attachments");  
    CMS.FormEngine.FormFieldInfo ffi1 = fi.GetFormField("Images");  
    Guid AttachmentGroupGUID = ffi.Guid;
    Guid AttachmentGroupGUID1 = ffi1.Guid;
    ucDocAttachments.Path = Eval<string>("NodeAliasPath");
    ucDocImages.Path = Eval<string>("NodeAliasPath");
    ucDocAttachments.AttachmentGroupGUID = AttachmentGroupGUID;
    ucDocImages.AttachmentGroupGUID = AttachmentGroupGUID1;
    ucDocAttachments.TransformationName = "CMS.Root.Attachment";
    ucDocImages.TransformationName = "CMS.Root.AttachmentList";
    ucDocAttachments.ReloadData(true);
    ucDocImages.ReloadData(true);
  }
}

</script>


<div class="innerSelectedElectionContainer col-xs-12" >
  <div class="col-xs-12 selectedElectionInfo " >
    <div class="col-xs-12 selectedElectionTitle ">
     <%# Eval("FAQQuestion") %>
    </div>
    <div class="col-xs-12 selectedElectionText selectedElectionInfo" >
      <%# Eval("FAQAnswer") %>
    </div>
   </div>
  <div class="selectedElectionInfo " style="display: flex; flex-wrap: wrap;"> 
      <a class="imageItem" target="_blank" href="<%# GetAbsoluteUrl(GetAttachmentUrl(Eval("AttachmentName"), Eval("NodeAliasPath")), EvalInteger("AttachmentSiteID")) %>">
      <cms:DocumentAttachments ID="ucDocAttachments" runat="server" /></a>
  </div>
  <div class="selectedElectionInfo " style="display: flex; flex-wrap: wrap;"> 
    <cms:DocumentAttachments ID="ucDocImages" runat="server" />
  </div>
</div>   

This works well with Repeater web part. Did you set Columns property of web part? If yes, make sure that NodeAliasPath is there.

2 votesVote for this answer Unmark Correct answer

Recent Answers


Mariia Hrytsai answered on November 28, 2017 11:00

I guess this page might give you an idea how to implement this: https://docs.kentico.com/k10/managing-website-content/configuring-the-environment-for-content-editors/creating-grouped-page-attachments.

So to display attachments from another field you can add another control <cms:DocumentAttachments ID="ucDocImagesField" runat="server" /></a> and make appropriate assignment of AttachmentGroupGUID, Transformation etc., as in code above.

0 votesVote for this answer Mark as a Correct answer

Farah El Agha answered on November 28, 2017 11:12

I already tried that but faced a lot of errors, can you please show me what would be the form of Init function if i want to implement 2 controls?

0 votesVote for this answer Mark as a Correct answer

Mariia Hrytsai answered on November 28, 2017 11:17

I suppose that there should be something like this:

  CMS.FormEngine.FormFieldInfo ffi2 = fi.GetFormField("AnotherImagesField");  
  Guid AttachmentGroupGUID2 = ffi2.Guid;
  ucDocImagesField.Path = Eval<string> ("NodeAliasPath");
  ucDocImagesField.AttachmentGroupGUID = AttachmentGroupGUID2;
  ucDocImagesField.TransformationName = "CMS.Root.Attachment";
  ucDocImagesField.ReloadData(true);

  and in ascx file add another control
  <cms:DocumentAttachments ID="ucDocImagesField" runat="server" />
0 votesVote for this answer Mark as a Correct answer

Farah El Agha answered on November 28, 2017 11:25

Previously I tried this code:

 protected override void OnInit(EventArgs e)

{

CMS.DataEngine.DataClassInfo dci = CMS.DataEngine.DataClassInfoProvider.GetDataClassInfo(Eval("ClassName").ToString(), true);
if (dci != null)
{
  CMS.FormEngine.FormInfo fi = new CMS.FormEngine.FormInfo(dci.ClassFormDefinition);
  // field name we added in the page type
  CMS.FormEngine.FormFieldInfo ffi = fi.GetFormField("Images");  
       CMS.FormEngine.FormFieldInfo ffi1= fi.GetFormField("Reports");
  Guid AttachmentGroupGUID = ffi.Guid;
        Guid AttachmentGroupGUID1= ffi1.Guid;
  ucDocAttachments.Path = Eval<string>("NodeAliasPath");
        ucDocFileAttachs.Path = Eval<string>("NodeAliasPath");
  ucDocAttachments.AttachmentGroupGUID = AttachmentGroupGUID;
        ucDocFileAttachs.AttachmentGroupGUID = AttachmentGroupGUID1;
  ucDocAttachments.TransformationName = "CMS.Root.Attachment";
        ucDocFileAttachs.TransformationName = "CMS.Root.AttachmentList";
  ucDocAttachments.ReloadData(true);
        ucDocFileAttachs.ReloadData(true);
}

}

where in AttachmentList transformation I have this:

< div> <a target="_blank" href="<%# GetAbsoluteUrl(GetAttachmentUrl(Eval("AttachmentName"), Eval("NodeAliasPath")), Eval < int>("AttachmentSiteID")) %>" download > <%# Eval("AttachmentName",true) %> < /a> < /div>

but it returns this error: [Error loading the control 'Repeater', check event log for more details]

0 votesVote for this answer Mark as a Correct answer

Mariia Hrytsai answered on November 28, 2017 11:34

Could you please check event log and send me the error you are getting?

0 votesVote for this answer Mark as a Correct answer

Farah El Agha answered on November 28, 2017 11:47

Event ID: 4489

Event type: Error

Event time: 11/28/2017 12:50:17 PM

Source: Control

Event code: LOAD

User ID: 65

User name: public

Description: Message: Object reference not set to an instance of an object.

Exception type: System.NullReferenceException

Stack trace:

at ASP.cmsvirtualfiles_transformations__vg_81685704_be55_473f_8a2f_a53f2e59180d_custom_elections_selectedelection_ascx.OnInit(EventArgs e) in http://server/Lade/CMSVirtualFiles/Transformations/=vg=81685704-be55-473f-8a2f-a53f2e59180d/custom.Elections/selectedElection.ascx:line 15 at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Control.AddedControl(Control control, Int32 index) at System.Web.UI.ControlCollection.Add(Control child) at System.Web.UI.WebControls.Repeater.CreateItem(Int32 itemIndex, ListItemType itemType, Boolean dataBind, Object dataItem) at System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource) at CMS.DocumentEngine.Web.UI.BasicRepeater.CreateControlHierarchy(Boolean useDataSource) at System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e) at System.Web.UI.WebControls.Repeater.DataBind() at CMS.DocumentEngine.Web.UI.BasicRepeater.DataBind() at CMS.DocumentEngine.Web.UI.CMSRepeater.DataBind() at CMS.DocumentEngine.Web.UI.CMSRepeater.ReloadDataInternal(Boolean forceReload) at CMS.DocumentEngine.Web.UI.CMSRepeater.<>c__DisplayClass3.b__2() at CMS.Base.Web.UI.ControlsExtensions.CallHandled(Control ctrl, Action func)

0 votesVote for this answer Mark as a Correct answer

Mariia Hrytsai answered on November 28, 2017 11:57 (last edited on November 28, 2017 11:57)

Does you .ascx file contain repeater, and repeater transformation contains control <cms:DocumentAttachments ID="ucDocImagesField" runat="server" />?

If yes, you should use ItemDataBound event of repeater and there you should initialize attachments control.

0 votesVote for this answer Mark as a Correct answer

Farah El Agha answered on November 28, 2017 12:05

the .ascx contains a basic repeater and the transformation is already shared as it is, can you please explain more what should be included in the ItemDataBound event? or how to initialize the attachments control? also one more question, the Images attachment worked really well, why am I facing this problem with the second attachment field if I am applying almost the same code for both.

0 votesVote for this answer Mark as a Correct answer

Mariia Hrytsai answered on November 28, 2017 12:47

It is quite difficult to judge about the issue not seeing it, but what I can see as a problem, that if your repeater has attachment control in transformation, it might be incorrectly init it in OnInit event. Is it your OnInit Script is in transformation? Do you use some custom web part with ascx and code behind? Do you display your attachments on Election details page? Can you send screenshot of you transformation? As by event log details the issue is in line 15 of your transformation.

0 votesVote for this answer Mark as a Correct answer

Farah El Agha answered on November 28, 2017 13:40

A transformation screenshot

Event Logs

0 votesVote for this answer Mark as a Correct answer

Mariia Hrytsai answered on November 28, 2017 14:34

You put the CMS.Root.AttachmentLinks** transformation for second control. Please make sure that such transformation exists. Maybe there should be CMS.Root.AttachmentList

And also check attachment fields names. I tried to use you transformation and it works well with correct transfromation names and Repeater webpart.

0 votesVote for this answer Mark as a Correct answer

Farah El Agha answered on November 28, 2017 14:49

yes the transformation exists, I created it, but also when I use CMS.Root.Attachment I face the same error, also I double checked the names, and everything looks fine, one more question please, is it okay to use the same control "DocumentAttachments" for both attachment fields? or should I use separate controls?

0 votesVote for this answer Mark as a Correct answer

Farah El Agha answered on November 29, 2017 07:22 (last edited on November 29, 2017 07:22)

well it turned out that the Basic Repeater that I was using was firing all these errors, I replaced it with a repeater and it worked fine, thank you for your help :)

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.