Displaying DocumentsAndFiles in Product Detail Widget Template
Hello,
I have a series of products that can be purchased as printed and shipped brochures. But, each of these brochures is also available as a free PDF download. I have added the PDF to the products as a "Documents and Other Files", but the widget template doesn't display the file at all.
When I go into Design > Widget Templates, and I click to edit the template for "Product Details". In the "Insert..." bar on the right, under "Other Data" there are two possible fields:
When I click to add "DocumentsAndFiles" it puts in this code:
<sitefinity:TextField runat="server" DisplayMode="Read" Value='<%# Eval("DocumentsAndFiles")%>' />Which obviously doesn't help as it just does a .toString() apparently, and the page prints out:
System.Collections.Generic.List`1[Telerik.Sitefinity.Ecommerce.Catalog.Model.ProductFile]How can I at least grab the first list item and snag it's content URL, so that I can fill in something like this for the template:
<a href='<%# (System.Collections.Generic.List)Eval("DocumentsAndFiles")[0].DocumentUrl %>'>FREE PDF - Download Now</a>Thanks,
Brandon
OK, so I have more info on this topic, but may need a fresh set of eyes to help really identify it...
The required tag for adding the files to the page (I got from the default template for Product Details):
1.<div class="sfProductDocumentsAndFiles"> 2. <sf:ProductDocumentsAndFilesControl id="productDocumentsAndFilesControl" ProductItem='<%# Page.GetDataItem() %>' runat="server" />3.</div>So I added the above code to my template, and it puts on the rendered container DIV for the DocumentsAndFiles, but it is empty, like this:
1.<div class="sfProductDocumentsAndFiles"> 2. <div id="ctl00_BodyContent_C004_productsFrontendDetail_ctl00_ctl00_SingleItemContainer_ctrl0_productDocumentsAndFilesControl"></div>3.</div>I then compared my template file to the default one, making sure all the control directives at the top matched. They do. I noticed that my "sfProductDocumentsAndFiles" DIV though was not under the same parent DIV as the default, so I moved it to be inside the "sfproductInfoWrp" DIV just like the default template does. ...strangely, at this point, I saw the download link (with PDF icon) and it worked...the first time I viewed the page...after that coming back to the page, it hasn't shown up again...
Here's the code I'm using in the template that I *want* to use:
001.<%@ Control Language="C#" %>002.<%@ Import Namespace="System.ComponentModel" %>003.<%@ Import Namespace="Telerik.Sitefinity.Ecommerce.Catalog.Model" %>004.<%@ Register Assembly="Telerik.Sitefinity.Ecommerce" Namespace="Telerik.Sitefinity.Modules.Ecommerce.Orders.Web.UI"005. TagPrefix="sfOrders" %>006.<%@ Register Assembly="Telerik.Sitefinity.Ecommerce" Namespace="Telerik.Sitefinity.Modules.Ecommerce.Catalog.Web.UI.Fields"007. TagPrefix="sfCatalog" %>008.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.ContentUI" Assembly="Telerik.Sitefinity" %>009.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>010.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit"011. Assembly="Telerik.Sitefinity" %>012.<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>013.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Modules.Ecommerce.Catalog.Web.UI"014. Assembly="Telerik.Sitefinity.Ecommerce" %>015.<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields"016. TagPrefix="sfFields" %>017.<%@ Register Assembly="InGen.Sitefinity.ProductReviews" Namespace="InGen.Sitefinity.ProductReviews" TagPrefix="ipr" %>018.<sf:ResourceLinks id="resourcesLinks" runat="server">019. <sf:ResourceFile JavaScriptLibrary="JQueryFancyBox" />020.</sf:ResourceLinks>021.<sf:ResourceLinks id="resourcesLinks2" runat="server" UseEmbeddedThemes="true" Theme="Default">022. <sf:ResourceFile Name="Telerik.Sitefinity.Resources.Themes.Basic.Styles.fancybox.css"023. Static="true" />024.</sf:ResourceLinks>025.<div id="widgetStatus" runat="server" visible="false" class="sfErrorSummary sfTopMsg">026. <asp:Label ID="widgetStatusMessage" runat="server" />027.</div>028.<div class="sfproductDetailsWrp">029.<sf:ConditionalTemplateContainer ID="conditionalTemplate" runat="server">030. <templates>031. <sf:ConditionalTemplate Left="IsActive" Operator="Equal" Right="false" runat="server">032. <asp:Literal ID="Literal1" runat="server" Text="<%$Resources:OrdersResources, ProductNotAvailable %>" />033. </sf:ConditionalTemplate>034. 035. <sf:ConditionalTemplate Left="IsActive" Operator="Equal" Right="true" runat="server">036. <telerik:RadListView ID="SingleItemContainer" ItemPlaceholderID="ItemContainer" AllowPaging="False" runat="server" EnableEmbeddedSkins="false" EnableEmbeddedBaseStylesheet="false">037. <LayoutTemplate>038. <div class="sfproductDetails sfClearfix">039. <asp:PlaceHolder ID="ItemContainer" runat="server" />040. </div>041. </LayoutTemplate>042. <ItemTemplate>043. <div class="sfproductInfoWrp">044. 045. <span class="promo-callout">046. <%# (Eval("SpecialPromoNew") == null || (bool)Eval("SpecialPromoNew") == false) ? "" : "<span class='new'>New</span>" %>047. <%# (Eval("SpecialPromoUpdated") == null || (bool)Eval("SpecialPromoUpdated") == false) ? "" : "<span class='updated'>Updated</span>" %>048. <%# (Eval("SpecialPromoReduced") == null || (bool)Eval("SpecialPromoReduced") == false) ? "" : "<span class='reduced'>Reduced Price</span>" %>049. <%# (Eval("SpecialPromoLimited") == null || (bool)Eval("SpecialPromoLimited") == false) ? "" : "<span class='limited'>Limited Quantity</span>" %>050. </span>051. 052. <h1 class="sfproductTitle">053. <%# Eval("Title") %>054. </h1>055. <div class="product-modified-date">056. <sitefinity:TextField runat="server" DisplayMode="Read" Value='<%# Eval("LastModified")%>' />057. </div>058. <div class="sfproductDescription">059. <%# Eval("Description") %>060. </div>061. <div class="sfproductSpecs clearfix">062. <%# Eval("Specifications") == null ? "" : "<br/>" + Eval("Specifications") %> 063. </div>064. <div class="sfProductDocumentsAndFiles"> 065. <a href='#'>FREE PDF - Download Now</a>066. <sf:ProductDocumentsAndFilesControl id="productDocumentsAndFilesControl" ProductItem='<%# Page.GetDataItem() %>' runat="server" />067. </div>068. </div>069. <div class="product-detail-left">070. 071. 072. 073. <div class="rule"> </div> 074. 075. <div class="sfproductOptions clearfix">076. <sf:ProductOptionsControl id="productOptionsControl" ProductItem='<%# Page.GetDataItem() %>' runat="server" />077. </div>078. 079. <div class="sfproductPrice">080. <sfCatalog:DisplayPriceField runat="server" ObjectType="Product" ObjectId='<%# Eval("Id") %>' />081. </div>082. 083. 084. <div class='sfproductAddtoCart <%# (Eval("CalltoOrder") == null || (bool)Eval("CallToOrder") == false) ? "" : "hide" %>'>085. <sfOrders:AddToCartWidget ID="addToCartWidget" ProductId='<%# Eval("Id") %>' runat="server" />086. </div>087. 088. <div class='sfproductCallToOrder <%# (Eval("CalltoOrder") == null || (bool)Eval("CallToOrder") == false) ? "hide" : "" %>'>089. <div class="prmCust hide">For Premium Customization:</div>090. Contact <b>Vince Stone</b> at <b>800-638-9797 Ext. 2610</b> <br/>091. or <a href="mailto:vinston@atlasworldgroup.com">vinston@atlasworldgroup.com</a> 092. </div>093. 094. <div class="sfproductImgsWrp">095. <div class="sfproductMainImgWrp">096. <%-- This is so that we can have the rel="fancybox" without resorting to an Attributes.Add() call --%>097. <%-- <a href='<%# HttpUtility.HtmlAttributeEncode(Eval("PrimaryImageUrl") as string) %>' rel="fancybox"> --%>098. <img src='<%# HttpUtility.HtmlAttributeEncode(Eval("PrimaryImageUrl") as string) %>' alt='<%# HttpUtility.HtmlAttributeEncode(Eval("ThumbnailAlternativeText") as string) %>' />099. <%-- </a> --%>100. </div>101. 102. 103. <asp:PlaceHolder ID="socialContainer" runat="server"></asp:PlaceHolder>104. </div>105. 106. 107. <div class="sfProductTagsWrp">108. <h3>Tags</h3>109. <sitefinity:FlatTaxonField ID="FlatFieldControl" DisplayMode="Read" runat="server" WebServiceUrl="~/Sitefinity/Services/Taxonomies/FlatTaxon.svc" AllowMultipleSelection="true" TaxonomyId="CB0F3A19-A211-48a7-88EC-77495C0F5374" TaxonomyMetafieldName="Tags" Expanded="false" ExpandText="ClickToAddTags" BindOnServer="true" HideWhenNoTaxaFound="true" />110. </div> 111. 112. </div>113. <div class="product-detail-right">114. <div class="product-detail-favorites">115. 116. 117. <fav:FavoriteButtonView118. ImageUrl="~/resources/favorite.png"119. FavoritedImageUrl="~/resources/delete.png"120. ID="FavoriteButton1"121. ContentType="Products"122. ItemId='<%# Eval("Id") %>'123. ShowFavoritesCount="true" 124. LayoutTemplatePath="~/resources/Favorites/FavoriteButtonLayout.ascx" 125. runat="server" />126. 127. 128. </div>129. <div class="product-detail-reviews">130. <ipr:ProductReviewList ID="ProdReviewList" ProductId='<%# Eval("Id") %>' ReviewTextRows='5' ReviewTextCols='50' runat="server" />131. </div>132. </div>133. 134. </ItemTemplate>135. </telerik:RadListView>136. </sf:ConditionalTemplate>137. </templates>138.</sf:ConditionalTemplateContainer>139.</div>For the record...Everything else on the page displays just fine. No errors, or anything like that.
And for reference, here is the code from the default Product Detail template:
01.<%@ Control Language="C#" %>02.<%@ Import Namespace="System.ComponentModel" %>03.<%@ Import Namespace="Telerik.Sitefinity.Ecommerce.Catalog.Model" %>04.<%@ Register Assembly="Telerik.Sitefinity.Ecommerce" Namespace="Telerik.Sitefinity.Modules.Ecommerce.Orders.Web.UI"05. TagPrefix="sfOrders" %>06.<%@ Register Assembly="Telerik.Sitefinity.Ecommerce" Namespace="Telerik.Sitefinity.Modules.Ecommerce.Catalog.Web.UI.Fields"07. TagPrefix="sfCatalog" %>08.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.ContentUI" Assembly="Telerik.Sitefinity" %>09.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>10.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit"11. Assembly="Telerik.Sitefinity" %>12.<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>13.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Modules.Ecommerce.Catalog.Web.UI"14. Assembly="Telerik.Sitefinity.Ecommerce" %>15.<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields"16. TagPrefix="sfFields" %>17.<sf:ResourceLinks id="resourcesLinks" runat="server">18. <sf:ResourceFile JavaScriptLibrary="JQueryFancyBox" />19.</sf:ResourceLinks>20.<sf:ResourceLinks id="resourcesLinks2" runat="server" UseEmbeddedThemes="true" Theme="Default">21. <sf:ResourceFile Name="Telerik.Sitefinity.Resources.Themes.Basic.Styles.fancybox.css"22. Static="true" />23.</sf:ResourceLinks>24.<div id="widgetStatus" runat="server" visible="false" class="sfErrorSummary sfTopMsg">25. <asp:Label ID="widgetStatusMessage" runat="server" />26.</div>27.<div class="sfproductDetailsWrp">28.<sf:ConditionalTemplateContainer ID="conditionalTemplate" runat="server">29. <templates>30. <sf:ConditionalTemplate Left="IsActive" Operator="Equal" Right="false" runat="server">31. <asp:Literal ID="Literal1" runat="server" Text="<%$Resources:OrdersResources, ProductNotAvailable %>" />32. </sf:ConditionalTemplate>33. 34. <sf:ConditionalTemplate Left="IsActive" Operator="Equal" Right="true" runat="server">35. <telerik:RadListView ID="SingleItemContainer" ItemPlaceholderID="ItemContainer" AllowPaging="False" runat="server" EnableEmbeddedSkins="false" EnableEmbeddedBaseStylesheet="false">36. <LayoutTemplate>37. <div class="sfproductDetails sfClearfix">38. <asp:PlaceHolder ID="ItemContainer" runat="server" />39. </div>40. </LayoutTemplate>41. <ItemTemplate>42. <div class="sfproductImgsWrp">43. <div class="sfproductMainImgWrp">44. <%-- This is so that we can have the rel="fancybox" without resorting to an Attributes.Add() call --%>45. <a href='<%# HttpUtility.HtmlAttributeEncode(Eval("PrimaryImageUrl") as string) %>' rel="fancybox">46. <img src='<%# HttpUtility.HtmlAttributeEncode(Eval("Thumbnail.Url") as string) %>' alt='<%# HttpUtility.HtmlAttributeEncode(Eval("ThumbnailAlternativeText") as string) %>' />47. </a>48. </div>49. 50. <div class="sfproductImgsListWrp">51. <ul class="sfproductImgsList">52. <asp:Repeater ID="Repeater1" runat="server" DataSource='<%# new BindingList<ProductImage>(((IEnumerable<ProductImage>)Eval("Images")).Skip(1).ToList()) %>'>53. <ItemTemplate>54. <li class="sfproductImgWrp">55. <a href='<%# DataBinder.Eval(Container.DataItem, "Url") %>' rel="fancybox" class="sfproductImgLnk">56. <asp:Image ID="Image1" CssClass="sfproductImg" runat="server" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "ThumbnailUrl") %>' Width='<%# (int)DataBinder.Eval(Container.DataItem, "ThumbnailWidth") %>' Height='<%# (int)DataBinder.Eval(Container.DataItem, "ThumbnailHeight") %>' />57. </a>58. </li>59. </ItemTemplate>60. </asp:Repeater>61. </ul>62. </div>63. <asp:PlaceHolder ID="socialContainer" runat="server"></asp:PlaceHolder>64. </div>65. 66. 67. <div class="sfproductInfoWrp">68. <h1 class="sfproductTitle">69. <%# Eval("Title") %>70. </h1>71. <div class="sfproductPrice">72. <sfCatalog:DisplayPriceField runat="server" ObjectType="Product" ObjectId='<%# Eval("Id") %>' />73. </div>74. 75. <sf:ProductDynamicFields id="productDynamicFieldsControl" ProductItem='<%# Page.GetDataItem() %>' runat="server" />76. 77. <div class="sfproductDescription">78. <%# Eval("Description") %>79. </div>80. 81. <div class="sfproductOptions">82. <sf:ProductOptionsControl id="productOptionsControl" ProductItem='<%# Page.GetDataItem() %>' runat="server" />83. </div>84. 85. <div class="sfProductDocumentsAndFiles">86. <sf:ProductDocumentsAndFilesControl id="productDocumentsAndFilesControl" ProductItem='<%# Page.GetDataItem() %>' runat="server" />87. </div>88. 89. <sfOrders:AddToCartWidget ID="addToCartWidget" ProductId='<%# Eval("Id") %>' runat="server" />90. </div>91. </ItemTemplate>92. </telerik:RadListView>93. </sf:ConditionalTemplate>94. </templates>95.</sf:ConditionalTemplateContainer>96.</div>I'm on Sitefinity 5.2, by the way.
Hey Brandon,
The price has to be displayed/called prior to the documents and files in order for files to show up.
So lines 64/67 have to come after lines 79/81 - or in code:
<div class="sfproductPrice"> <sfCatalog:DisplayPriceField runat="server" ObjectType="Product" ObjectId='<%# Eval("Id") %>' /></div><div class="sfProductDocumentsAndFiles"> <sf:ProductDocumentsAndFilesControl id="productDocumentsAndFilesControl" ProductItem='<%# Page.GetDataItem() %>' runat="server" /></div>this ensures it works.
Or if you feel like playing around further, tweak the code so the ObjectType & ObjectId are set prior to referring to a ProjectItem.
Jochem
Jochem, thank you so much! Reordering the widget template items did the trick. Interesting...