Error executing template "/Designs/Hewitt/Paragraph/StandardParagraph.cshtml"
System.NotSupportedException: Unsupported item layout: .
   at CompiledRazorTemplates.Dynamic.RazorEngine_e061baa2e43e4ff88d26a4fd7ae3cd7f.<>c__DisplayClass96_0.b__0(TextWriter __razor_helper_writer) in c:\Domains\Sites\hewittrad.com\Files\Templates\Designs\Hewitt\Paragraph\StandardParagraph.cshtml:line 2377
   at CompiledRazorTemplates.Dynamic.RazorEngine_e061baa2e43e4ff88d26a4fd7ae3cd7f.<>c__DisplayClass95_0.b__0(TextWriter __razor_helper_writer) in c:\Domains\Sites\hewittrad.com\Files\Templates\Designs\Hewitt\Paragraph\StandardParagraph.cshtml:line 2321
   at CompiledRazorTemplates.Dynamic.RazorEngine_e061baa2e43e4ff88d26a4fd7ae3cd7f.<>c__DisplayClass105_0.b__0(TextWriter __razor_helper_writer) in c:\Domains\Sites\hewittrad.com\Files\Templates\Designs\Hewitt\Paragraph\StandardParagraph.cshtml:line 2501
   at CompiledRazorTemplates.Dynamic.RazorEngine_e061baa2e43e4ff88d26a4fd7ae3cd7f.b__104_0(TextWriter __razor_helper_writer) in c:\Domains\Sites\hewittrad.com\Files\Templates\Designs\Hewitt\Paragraph\StandardParagraph.cshtml:line 2475
   at CompiledRazorTemplates.Dynamic.RazorEngine_e061baa2e43e4ff88d26a4fd7ae3cd7f.Execute() in c:\Domains\Sites\hewittrad.com\Files\Templates\Designs\Hewitt\Paragraph\StandardParagraph.cshtml:line 2603
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 2 @using System.Collections.Generic 3 @using System.Linq 4 @using Dynamicweb.Rendering 5 @using Dynamicweb.Core 6 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 7 @using System 8 @using System.Linq 9 @using System.Text 10 @using System.Web 11 @using System.Collections.Generic 12 @using Dna.Frontend 13 @using Dna.Frontend.UI 14 @using Dna.Frontend.Forms 15 @using Dna.UrlServices 16 @using Dna.Validation 17 @using Dynamicweb.Core 18 @using Dynamicweb.Forms 19 @using Dynamicweb.Content 20 @using Dynamicweb.Ecommerce 21 @using Dynamicweb.Rendering 22 @using Dynamicweb.Security.UserManagement 23 @using ImageSettings = Dna.Frontend.UI.ImageSettings 24 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 25 @using System 26 @using System.IO 27 @using System.Web 28 @using System.Linq 29 @using System.Text 30 @using System.Text.RegularExpressions 31 @using System.Collections.Generic 32 @using System.Collections.Specialized 33 @using Dna.Frontend 34 @using Dna.Validation 35 @using Dna.Frontend.UI 36 @using Dna.UrlServices 37 @using Dna.Frontend.Forms 38 @using Dynamicweb.Core 39 @using Dynamicweb.Forms 40 @using Dynamicweb.Rendering 41 @functions{ 42 43 #region Url functions 44 45 public string GetCustomerCenterSortUrl(string field, string listType = "Order") 46 { 47 var paragraphId = Pageview.CurrentParagraph.ID.ToString(); 48 var sortDirectionParameter = "CCSort" + listType + paragraphId; 49 var sortFieldParameter = "CC" + listType + "ByField" + paragraphId; 50 var sortDirection = Sanitize.Parameter(sortDirectionParameter) == "Desc" || Sanitize.Parameter(sortFieldParameter) != field ? "Asc" : "Desc"; 51 52 if (field.IsNotNullOrEmpty()) 53 { 54 return "/Default.aspx?Id=" + Pageview.Page.ID + "&" + sortFieldParameter + "=" + field + "&" + sortDirectionParameter + "=" + sortDirection; 55 } 56 57 return string.Empty; 58 } 59 60 public string GetDataListSortUrl(string field) 61 { 62 var paragraphId = Pageview.CurrentParagraph.ID.ToString(); 63 var sortDirectionParameter = "sortorder"; 64 var sortFieldParameter = "sortby"; 65 var sortByParameter = Sanitize.Parameter(sortFieldParameter).IsNotNullOrEmpty() ? Sanitize.Parameter(sortFieldParameter) : string.Empty; 66 var sortOrderParameter = Sanitize.Parameter(sortDirectionParameter).IsNotNullOrEmpty() ? Sanitize.Parameter(sortDirectionParameter) : "ASC"; 67 var sortDirection = sortOrderParameter.ToUpper() == "DESC" || sortByParameter != field ? "ASC" : "DESC"; 68 69 if (field.IsNotNullOrEmpty()) 70 { 71 return "/Default.aspx?Id=" + Pageview.Page.ID + "&" + sortFieldParameter + "=" + field + "&" + sortDirectionParameter + "=" + sortDirection + "&ViewPID=" + paragraphId; 72 } 73 return string.Empty; 74 } 75 76 public string GetSortFieldParameter(string key, string field = "", string listType = "Order") 77 { 78 var paragraphId = Pageview.CurrentParagraph.ID.ToString(); 79 if (key.IsNullOrEmpty()) throw new NotSupportedException("'key' is a required field"); 80 81 switch (key) 82 { 83 case "name": 84 var parameter = "CC" + listType + "ByField" + paragraphId; 85 return Sanitize.Parameter(parameter); 86 case "value": 87 if (field.IsNullOrEmpty()) return "asc"; 88 var sortDirectionParameter = "CCSort" + listType + paragraphId; 89 var sortFieldParameter = "CC" + listType + "ByField" + paragraphId; 90 return Sanitize.Parameter(sortDirectionParameter) == "Desc" || Sanitize.Parameter(sortFieldParameter) != field ? "Asc" : "Desc"; 91 default: 92 throw new NotSupportedException(string.Format("The key '{0}' in not supported", key)); 93 } 94 } 95 96 #endregion Url functions 97 98 #region Generic functions 99 100 public static string GetAttributes(Dictionary<string, string> attributes) 101 { 102 if (attributes == null || !attributes.Any()) 103 { 104 return string.Empty; 105 } 106 107 var attributesConcat = attributes.Aggregate(string.Empty, (current, attribute) => current + GetAttribute(attribute.Key, attribute.Value)); 108 109 return attributesConcat; 110 } 111 112 public static string GetAttribute(string attributeName, string attributeValue) 113 { 114 if (attributeValue.IsNullOrEmpty() && !attributeName.Equals("value", StringComparison.InvariantCultureIgnoreCase)) return string.Empty; 115 return " " + attributeName + "=\"" + attributeValue + "\""; 116 } 117 118 #endregion Generic functions 119 120 #region Files functions 121 122 const string ImagesListTitleKey = "title"; 123 const string ImagesListImageKey = "image"; 124 125 /// <summary> 126 /// Gets the list of files from a folder. 127 /// </summary> 128 /// <return>Item1 is filename (with extension), Item2 is the title and Item3 is the FileType.</return> 129 public static IEnumerable<Tuple<string, string, FileType>> GetFilesInFolder(string defaultFile, string searchPattern, string fileTitle = "", bool addDefaultFile = true) 130 { 131 var files = new List<Tuple<string,string,FileType>>(); 132 var mapPath = HttpContext.Current.Server.MapPath(defaultFile); 133 var folderServerPath = Path.GetDirectoryName(mapPath); 134 135 if (folderServerPath == null || !Directory.Exists(folderServerPath)) return files; 136 137 // Get Images from folder 138 const string temp = @"\"; 139 const string metafield = "title"; 140 var metadata = Dynamicweb.Content.Files.Metadata.EditorFactory.GetMetadataForFile(defaultFile); 141 var title = metadata != null && metadata.GetValue(metafield).IsNotNullOrEmpty() ? metadata.GetValue(metafield) : fileTitle; 142 var folderWebPath = defaultFile.Contains("/") ? defaultFile.Substring(0, defaultFile.LastIndexOf("/", StringComparison.Ordinal)) : defaultFile; 143 144 if (addDefaultFile && File.Exists(mapPath)) 145 { 146 files.Add(new Tuple<string, string, FileType>(defaultFile, title, defaultFile.GetFileType())); 147 } 148 149 foreach (var file in Directory.GetFiles(folderServerPath, searchPattern)) 150 { 151 var filePath = folderWebPath + "/" + file.Substring(file.LastIndexOf(temp, StringComparison.Ordinal) + 1, file.Length - file.LastIndexOf(temp, StringComparison.Ordinal) - 1); 152 metadata = Dynamicweb.Content.Files.Metadata.EditorFactory.GetMetadataForFile(filePath); 153 title = metadata != null && metadata.GetValue(metafield).IsNullOrEmpty() ? metadata.GetValue(metafield) : fileTitle; 154 155 files.Add(new Tuple<string, string, FileType>(filePath, title, file.GetFileType())); 156 } 157 158 return files; 159 } 160 /// <summary> 161 /// Gets the list of image or HTML5 video files from a folder. 162 /// </summary> 163 /// <return>Item1 is filename (with extension), Item2 is the title and Item3 is the FileType (Image, Video).</return> 164 public static IEnumerable<Tuple<string,string,FileType>> GetMediaFilesInFolder(string defaulMedia, string searchPattern, string defaultName = "", bool addDefaultMedia = true) 165 { 166 return GetFilesInFolder(defaulMedia, searchPattern, defaultName, addDefaultMedia).Where(f => f.Item3 == FileType.Image || f.Item3 == FileType.Video).ToList(); 167 } 168 169 #endregion Files functions 170 171 #region Image functions 172 173 public static Dictionary<string, string> GetWidthAndHeightFromQueryString(string imageSource, bool addSource = false) 174 { 175 var widthAndHeight = new Dictionary<string, string>(); 176 177 if(imageSource.Contains("?")){ 178 var querySubstring = imageSource.Substring(imageSource.LastIndexOf('?') + 1); 179 var queryParams = HttpUtility.HtmlDecode(querySubstring).Split('&'); 180 181 if (!queryParams.Any()) 182 return widthAndHeight; 183 184 foreach (var param in queryParams.Where(k => k.StartsWith("width") || k.StartsWith("height"))) 185 { 186 var keyValuePair = param.Split('='); 187 188 if (keyValuePair[1].IsNotNullOrEmpty()) 189 { 190 widthAndHeight.Add(keyValuePair[0].ToLower(), keyValuePair[1]); 191 } 192 } 193 } 194 else if(imageSource.Contains("width") || imageSource.Contains("height")) 195 { 196 var queryParams = imageSource.Split('/'); 197 var imgParam = string.Empty; 198 199 foreach (var param in queryParams) 200 { 201 switch (imgParam) 202 { 203 case "width": 204 widthAndHeight.Add("width", param); 205 break; 206 case "height": 207 widthAndHeight.Add("height", param); 208 break; 209 } 210 211 switch (param) 212 { 213 case "width": 214 imgParam = "width"; 215 break; 216 case "height": 217 imgParam = "height"; 218 break; 219 default: 220 imgParam = string.Empty; 221 break; 222 } 223 } 224 } 225 226 if (addSource && imageSource.IsNotNullOrEmpty()) 227 { 228 widthAndHeight.Add("srcset", imageSource); 229 } 230 231 return widthAndHeight; 232 } 233 234 #endregion Image functions 235 236 #region Form Field functions 237 238 public string GetWrapperStart(bool includeWrapper, FieldType fieldType, string htmlElement, bool isRequired = false, string fieldClass = "") 239 { 240 if (!includeWrapper || htmlElement.IsNullOrEmpty()) return string.Empty; 241 var cssClass = new List<string> {fieldType.ToString().ToLower()}; 242 243 if (fieldClass.IsNotNullOrEmpty()) 244 cssClass.Add(fieldClass); 245 if (isRequired) 246 cssClass.Add("mandatory"); 247 248 var attributes = new Dictionary<string, string>() 249 { 250 {"class", string.Join(" ", cssClass)} 251 }; 252 253 return GetHtmlElement(htmlElement, attributes); 254 } 255 256 public string GetWrapperEnd(bool includeWrapper, string htmlElement) 257 { 258 return !includeWrapper ? string.Empty : GetHtmlElement(htmlElement, true); 259 } 260 261 public string GetControlWithRequiredClass(bool isRequired, string control, string fieldClass = "") 262 { 263 if (!isRequired) return control; 264 if (fieldClass.IsNotNullOrEmpty()) fieldClass += " "; 265 fieldClass += "mandatory"; 266 var regex = new Regex(Regex.Escape(" ")); 267 return regex.Replace(control, " class=\"" + fieldClass + "\" ", 1); 268 } 269 270 public static string GetAttributes(FieldSettings settings, bool returnFieldType = true) 271 { 272 var attributes = new StringBuilder(); 273 if (returnFieldType) 274 { 275 var fieldType = string.Empty; 276 switch (settings.Type) 277 { 278 case FieldType.Select: 279 break; 280 case FieldType.Checkboxlist: 281 fieldType = FieldType.Checkbox.ToString().ToLower(); 282 break; 283 case FieldType.DatetimeLocal: 284 fieldType = "datetime-local"; 285 break; 286 case FieldType.Textarea: 287 case FieldType.File: 288 case FieldType.Text: 289 case FieldType.Hidden: 290 case FieldType.Submit: 291 case FieldType.Reset: 292 case FieldType.Radio: 293 case FieldType.Checkbox: 294 case FieldType.Divider: 295 case FieldType.Image: 296 case FieldType.Password: 297 case FieldType.Textstring: 298 case FieldType.Button: 299 case FieldType.Search: 300 case FieldType.Email: 301 case FieldType.Url: 302 case FieldType.Tel: 303 case FieldType.Number: 304 case FieldType.Range: 305 case FieldType.Date: 306 case FieldType.Month: 307 case FieldType.Week: 308 case FieldType.Time: 309 case FieldType.Datetime: 310 case FieldType.Color: 311 case FieldType.Unknown: 312 default: 313 fieldType = settings.Type.ToString().ToLower(); 314 break; 315 } 316 if (!settings.Attributes.ContainsKey("type")) 317 { 318 attributes.Append(GetAttribute("type", fieldType)); 319 } 320 } 321 attributes.Append(GetAttribute("class", settings.CssClass)); 322 attributes.Append(GetAttribute("id", settings.Id)); 323 attributes.Append(GetAttribute("name", settings.SystemName)); 324 if (settings.Type != FieldType.Textarea) 325 { 326 attributes.Append(GetAttribute("value", settings.Value)); 327 } 328 if (settings.Type == FieldType.Email || settings.Type == FieldType.Password || settings.Type == FieldType.Search || settings.Type == FieldType.Tel || settings.Type == FieldType.Text || settings.Type == FieldType.Url) 329 { 330 // Only works wit these types 331 attributes.Append(GetAttribute("placeholder", settings.Placeholder)); 332 } 333 if (settings.Type == FieldType.Datetime) 334 { 335 attributes.Append(GetAttribute("placeholder", "&#x1f4c5;")); 336 } 337 if (settings.Type != FieldType.Checkboxlist) 338 { 339 attributes.Append(GetAttribute("required", settings.IsRequired)); 340 } 341 attributes.Append(GetAttributes(settings.Attributes)); 342 return attributes.ToString(); 343 } 344 345 public static string GetAttributes(FieldOption optionSettings, FieldType fieldType = FieldType.Select) 346 { 347 var attributes = new StringBuilder(); 348 if (fieldType != FieldType.Select) 349 { 350 attributes.Append(GetAttribute("name", optionSettings.SystemName)); 351 } 352 attributes.Append(GetAttribute("value", optionSettings.Value)); 353 attributes.Append(GetAttributes(optionSettings.Attributes)); 354 return attributes.ToString(); 355 } 356 357 public static string GetAttribute(string attributeName, bool attributeValue) 358 { 359 if (!attributeValue) return string.Empty; 360 return " " + attributeName + "=\"" + attributeName + "\""; 361 } 362 363 public static string GetAttributeString(string string1 = "", string string2 = "") 364 { 365 var result = new List<string>(); 366 367 if (string1.IsNotNullOrEmpty()) 368 result.AddRange(string1.Split(' ').ToList()); 369 if (string2.IsNotNullOrEmpty()) 370 result.AddRange(string2.Split(' ').ToList()); 371 372 return string.Join(" ", result); 373 } 374 375 #endregion 376 377 #region Dynamicweb Template Engine Workaround 378 379 public static string GetHtmlElement(string element, bool isClosingElement = false) 380 { 381 return GetHtmlElementForDw(element, null, string.Empty, isClosingElement); 382 } 383 384 public static string GetHtmlElement(string element, Dictionary<string, string> attributes, bool isClosingElement = false) 385 { 386 return GetHtmlElementForDw(element, attributes, string.Empty, isClosingElement); 387 } 388 389 public static string GetHtmlElement(string element, string processedAttributes, bool isClosingElement = false) 390 { 391 return GetHtmlElementForDw(element, null, processedAttributes, isClosingElement); 392 } 393 394 private static string GetHtmlElementForDw(string element, Dictionary<string, string> attributes = null, string processedAttributes = "", bool isClosingElement = false) 395 { 396 var result = new StringBuilder("<"); 397 398 if (attributes != null || processedAttributes.IsNotNullOrEmpty()) 399 { 400 result.Append(element); 401 if (attributes != null) 402 { 403 result.Append(GetAttributes(attributes)); 404 } 405 else if (processedAttributes.IsNotNullOrEmpty()) 406 { 407 result.Append(processedAttributes); 408 } 409 if (isClosingElement) 410 { 411 result.Append("/"); 412 } 413 } 414 else 415 { 416 if (isClosingElement) 417 { 418 result.Append("/"); 419 } 420 result.Append(element); 421 } 422 423 result.Append(">"); 424 425 return result.ToString(); 426 } 427 428 #endregion Dynamicweb Template Engine Workaround 429 } 430 @{ 431 432 @* Tab helpers *@ 433 @helper InternalRenderTabHeader(string key, string label, string cssClass = "") 434 { 435 @SnippetStart("tabHeaders") 436 <li class="@cssClass"> 437 <a href="@key">@label</a> 438 </li> 439 @SnippetEnd("tabHeaders") 440 } 441 442 443 @* Paging helpers *@ 444 @helper InternalRenderGoToFirstPage(NameValueCollection queryParameters, string pageNumQueryParameter, int currentPage, int numOfPages, int loopPageSize, int currentPageNum = 0) 445 { 446 if (currentPageNum == 0) 447 { 448 currentPageNum = currentPage; 449 } 450 451 if (currentPage > 2 && numOfPages > loopPageSize && currentPageNum != 1) 452 { 453 queryParameters.Remove(pageNumQueryParameter); 454 @InternalRenderPageItem(queryParameters, "1") 455 @InternalRenderEllipsis() 456 } 457 } 458 459 @helper InternalRenderGoToLastPage(NameValueCollection queryParameters, string pageNumQueryParameter, int currentPage, int numOfPages, int loopPageSize, int endPage) 460 { 461 if (currentPage < numOfPages - 1 && numOfPages > loopPageSize && endPage != numOfPages) 462 { 463 queryParameters = Helpers.UpdateQueryStringKeyValue(queryParameters, pageNumQueryParameter, numOfPages.ToString()); 464 @InternalRenderEllipsis() 465 @InternalRenderPageItem(queryParameters, numOfPages.ToString()) 466 } 467 } 468 469 @helper InternalRenderPageItem(NameValueCollection queryParameters, string pageNum, string cssClass = "") 470 { 471 var url = Helpers.GetCurrentUrl(true, true); 472 var href = Helpers.BuildUri(url, queryParameters); 473 474 <li class="@cssClass"> 475 <a href="@href.PathAndQuery"> 476 @pageNum 477 </a> 478 </li> 479 } 480 481 @helper InternalRenderPageItem(string href, string label, string cssPartialClass, IconPosition position) 482 { 483 <li> 484 <a href="@href"> 485 @RenderIcon(cssPartialClass, label, position) 486 </a> 487 </li> 488 } 489 490 @helper InternalRenderEllipsis() 491 { 492 <li> 493 <span>...</span> 494 </li> 495 } 496 497 498 @* Form field helpers *@ 499 @helper InternalRenderLabel(FieldSettings settings) 500 { 501 @InternalRenderLabel(settings.Label, settings.TranslateKeyForLabel) 502 } 503 504 @helper InternalRenderLabel(string label, string translateKey = "") 505 { 506 @( translateKey.IsNotNullOrEmpty() ? Translate(translateKey) : label) 507 } 508 509 @helper InternalRenderCheckboxField(FieldSettings settings) 510 { 511 if (settings.SystemName.IsNotNullOrEmpty() || settings.Control.IsNotNullOrEmpty()) 512 { 513 settings.Assert(FieldType.Checkbox); 514 if (settings.IsChecked && !settings.Attributes.ContainsKey("checked")) 515 { 516 settings.Attributes.Add("checked", "checked"); 517 } 518 519 @InternalRenderFieldHeader(settings, false) 520 521 if (settings.Label.IsNotNullOrEmpty() || settings.TranslateKeyForLabel.IsNotNullOrEmpty()) 522 { 523 var cssClassList = new List<string> {settings.Type.ToString().ToLower(), settings.LabelCssClass}; 524 var cssClass = string.Join(" ", cssClassList.Where(s => s.IsNotNullOrEmpty())); 525 526 if (!settings.LabelAttributes.ContainsKey("class")) 527 { 528 settings.LabelAttributes.Add("class", cssClass); 529 } 530 else 531 { 532 settings.LabelAttributes["class"] = string.Concat(cssClass, " ", settings.LabelAttributes["class"]); 533 } 534 if (!settings.LabelAttributes.ContainsKey("for")) 535 { 536 settings.LabelAttributes.Add("for", settings.Id); 537 } 538 539 @GetHtmlElement("label", settings.LabelAttributes) 540 if (settings.Control.IsNotNullOrEmpty()) 541 { 542 if (settings.Value.IsNullOrEmpty() && settings.IsRequired) 543 { 544 var checkedAttribute = "checked=\"checked\""; 545 settings.Control = settings.Control.Replace(checkedAttribute, string.Empty); 546 } 547 @settings.Control 548 } 549 else 550 { 551 @GetHtmlElement("input", GetAttributes(settings), true) 552 } 553 <span> 554 @InternalRenderLabel(settings) 555 </span> 556 @GetHtmlElement("label", true) 557 } 558 else 559 { 560 if (settings.Control.IsNotNullOrEmpty()) 561 { 562 if (settings.Value.IsNullOrEmpty() && settings.IsRequired) 563 { 564 var checkedAttribute = "checked=\"checked\""; 565 settings.Control = settings.Control.Replace(checkedAttribute, string.Empty); 566 } 567 @settings.Control 568 } 569 else 570 { 571 @GetHtmlElement("input", GetAttributes(settings), true) 572 } 573 } 574 575 @InternalRenderFieldFooter(settings) 576 } 577 } 578 579 @helper InternalRenderTextareaField(FieldSettings settings) 580 { 581 if (settings.SystemName.IsNotNullOrEmpty() || settings.Control.IsNotNullOrEmpty()) 582 { 583 settings.Assert(FieldType.Textarea); 584 585 @InternalRenderFieldHeader(settings) 586 587 if (settings.Control.IsNotNullOrEmpty()) 588 { 589 @GetControlWithRequiredClass(settings.IsRequired, settings.Control) 590 } 591 else 592 { 593 if (!settings.Attributes.ContainsKey("rows")) 594 { 595 settings.Attributes.Add("rows", "6"); 596 } 597 if (!settings.Attributes.ContainsKey("cols")) 598 { 599 settings.Attributes.Add("cols", "50"); 600 } 601 @GetHtmlElement("textarea", GetAttributes(settings, false)) 602 @settings.Value 603 @GetHtmlElement("textarea", true) 604 } 605 606 @InternalRenderFieldFooter(settings) 607 } 608 } 609 610 @helper InternalRenderRadioOrCheckboxListField(FieldSettings settings) 611 { 612 if (settings.LoopOptions.Any() || settings.FieldOptionsList.Any() || settings.Control.IsNotNullOrEmpty()) 613 { 614 var optionCount = 0; 615 616 settings.Assert(FieldType.Radio); 617 618 @InternalRenderFieldHeader(settings) 619 620 if (settings.LoopOptions.Any()) 621 { 622 settings.CssClass = settings.Type.ToString().ToLower(); 623 foreach (var option in settings.LoopOptions) 624 { 625 optionCount++; 626 if (settings.Id.IsNullOrEmpty() || settings.Id == settings.SystemName) 627 { 628 settings.Id = settings.SystemName + optionCount; 629 } 630 631 var cssClassList = new List<string> {settings.Type.ToString().ToLower(), settings.CssClass}; 632 var cssClass = string.Join(" ", cssClassList.Where(s => s.IsNotNullOrEmpty())); 633 634 if (!settings.LabelAttributes.ContainsKey("class")) 635 { 636 settings.LabelAttributes.Add("class", cssClass); 637 } 638 else 639 { 640 settings.LabelAttributes["class"] = string.Concat(cssClass, " ", settings.LabelAttributes["class"]); 641 } 642 if (!settings.LabelAttributes.ContainsKey("for")) 643 { 644 settings.LabelAttributes.Add("for", settings.Id); 645 } 646 647 @GetHtmlElement("label", settings.LabelAttributes) 648 @GetHtmlElement("input", GetAttributes(settings), true) 649 <span>@option.GetString(settings.LabelLoopTag)</span> 650 @GetHtmlElement("label", true) 651 } 652 } 653 else if (settings.FieldOptionsList.Any()) 654 { 655 foreach (var option in settings.FieldOptionsList) 656 { 657 optionCount++; 658 659 if (option.SystemName.IsNullOrEmpty()) 660 { 661 option.SystemName = settings.SystemName; 662 } 663 if (option.Id.IsNullOrEmpty() || option.Id == option.SystemName) 664 { 665 option.Id = option.SystemName + optionCount; 666 } 667 var cssClassList = new List<string> {settings.Type.ToString().ToLower(), option.CssClass}; 668 var cssClass = string.Join(" ", cssClassList.Where(s => s.IsNotNullOrEmpty())); 669 670 if (!option.LabelAttributes.ContainsKey("class")) 671 { 672 option.LabelAttributes.Add("class", cssClass); 673 } 674 else 675 { 676 option.LabelAttributes["class"] = string.Concat(cssClass, " ", option.LabelAttributes["class"]); 677 } 678 if (!option.LabelAttributes.ContainsKey("for")) 679 { 680 option.LabelAttributes.Add("for", option.Id); 681 } 682 683 @GetHtmlElement("label", option.LabelAttributes) 684 @InternalRenderInputOptionField("input", option, settings.Type) 685 <span>@option.Label</span> 686 @GetHtmlElement("label", true) 687 } 688 } 689 else if (settings.Control.IsNotNullOrEmpty()) 690 { 691 @settings.Control 692 } 693 694 @InternalRenderFieldFooter(settings) 695 } 696 } 697 698 @helper InternalRenderInputField(FieldSettings settings) 699 { 700 if (settings.SystemName.IsNotNullOrEmpty() || settings.Control.IsNotNullOrEmpty()) 701 { 702 settings.Assert(FieldType.Text); 703 704 @InternalRenderFieldHeader(settings) 705 706 if (settings.Control.IsNotNullOrEmpty()) 707 { 708 var type = settings.Type.ToString().ToLower(); 709 if (settings.Type == FieldType.DatetimeLocal) 710 { 711 type = "datetime-local"; 712 } 713 714 if (settings.Type == FieldType.Password) 715 { 716 settings.Control = settings.Control.Replace("input ", "input autocomplete=\"off\" "); 717 } 718 @GetControlWithRequiredClass(settings.IsRequired, settings.Control) 719 } 720 else 721 { 722 if (settings.Type == FieldType.Password && !settings.Attributes.ContainsKey("autocomplete")) 723 { 724 settings.Attributes.Add("autocomplete", "off"); 725 } 726 @GetHtmlElement("input", GetAttributes(settings), true) 727 } 728 729 @InternalRenderFieldFooter(settings) 730 } 731 } 732 733 @helper InternalRenderDateTimeField(FieldSettings settings) 734 { 735 if (settings.SystemName.IsNotNullOrEmpty() || settings.Control.IsNotNullOrEmpty()) 736 { 737 settings.Assert(FieldType.Datetime); 738 settings.Attributes = new Dictionary<string, string> 739 { 740 {"placeholder", "&#xf073;"} 741 }; 742 743 @InternalRenderFieldHeader(settings) 744 745 if (settings.Control.IsNotNullOrEmpty()) 746 { 747 var type = settings.Type.ToString().ToLower(); 748 749 settings.Control = settings.Control.Replace("type=\"text\"", "type=\"" + type + "\""); 750 @GetControlWithRequiredClass(settings.IsRequired, settings.Control) 751 } 752 else 753 { 754 @GetHtmlElement("input", GetAttributes(settings), true) 755 } 756 757 @InternalRenderFieldFooter(settings) 758 } 759 } 760 761 @helper InternalRenderSelectField(FieldSettings settings) 762 { 763 const int limit = 10; 764 765 settings.Assert(FieldType.Select); 766 767 if (settings.CssClass.ToLower().Contains("country")) 768 { 769 @RenderCountriesDropdownField(settings, true, settings.CssClass.ToLower().Contains("highlights")) 770 } 771 else 772 { 773 if (settings.SystemName.IsNotNullOrEmpty() || settings.Control.IsNotNullOrEmpty() || settings.FieldOptionsList.Any() || settings.ValuesList.Any()) 774 { 775 @InternalRenderFieldHeader(settings) 776 777 int optionsCount; 778 if (settings.Control.IsNotNullOrEmpty()) 779 { 780 optionsCount = Regex.Matches(settings.Control, "option ").Count; 781 782 if (optionsCount > limit || optionsCount == 0) 783 { 784 settings.Control = settings.Control.Replace("select ", "select data-live-search=\"true\" "); 785 } 786 @GetControlWithRequiredClass(settings.IsRequired, settings.Control, settings.CssClass) 787 } 788 else 789 { 790 optionsCount = settings.FieldOptionsList.Count + settings.ValuesList.Count; 791 792 if (!settings.Attributes.ContainsKey("multiple") && !settings.Attributes.ContainsKey("data-live-search") && (optionsCount > limit || optionsCount == 0)) 793 { 794 settings.Attributes.Add("data-live-search", "true"); 795 } 796 @GetHtmlElement("select", GetAttributes(settings, false)) 797 798 if (settings.FirstHardcodedOptionLabel.IsNotNullOrEmpty()) 799 { 800 @InternalRenderOption(FieldOption.CreateOption(settings.FirstHardcodedOptionLabel, settings.FirstHardcodedOptionValue, settings.IsFirstHardcodedOptionSelected)) 801 } 802 803 foreach (var option in settings.FieldOptionsList) 804 { 805 @InternalRenderOption(option) 806 } 807 foreach (var option in settings.ValuesList) 808 { 809 @InternalRenderOption(FieldOption.CreateOption(option, option)) 810 } 811 812 @GetHtmlElement("select", true) 813 } 814 815 @InternalRenderFieldFooter(settings) 816 } 817 } 818 } 819 820 @helper InternalRenderButtonField(FieldSettings settings) 821 { 822 settings.Assert(FieldType.Button); 823 824 @InternalRenderFieldHeader(settings, false) 825 826 if (settings.Control.IsNotNullOrEmpty()) 827 { 828 var controlOutput = settings.Control; 829 switch (settings.Type) 830 { 831 case FieldType.Submit: 832 controlOutput = controlOutput.Replace("input ", "input class='btn btn-default'"); 833 break; 834 case FieldType.Reset: 835 controlOutput = controlOutput.Replace("input ", "input class='btn btn-bg2'"); 836 break; 837 case FieldType.Button: 838 case FieldType.Textarea: 839 case FieldType.File: 840 case FieldType.Text: 841 case FieldType.Hidden: 842 case FieldType.Radio: 843 case FieldType.Checkbox: 844 case FieldType.Select: 845 case FieldType.Checkboxlist: 846 case FieldType.Divider: 847 case FieldType.Image: 848 case FieldType.Password: 849 case FieldType.Textstring: 850 case FieldType.Search: 851 case FieldType.Email: 852 case FieldType.Url: 853 case FieldType.Tel: 854 case FieldType.Number: 855 case FieldType.Range: 856 case FieldType.Date: 857 case FieldType.Month: 858 case FieldType.Week: 859 case FieldType.Time: 860 case FieldType.Datetime: 861 case FieldType.DatetimeLocal: 862 case FieldType.Color: 863 case FieldType.Unknown: 864 default: 865 throw new NotSupportedException(string.Format("Unsupported Field Type: {0}.", settings.Type.ToString())); 866 } 867 @controlOutput 868 } 869 else 870 { 871 settings.CssClass = settings.CssClass.IsNullOrEmpty() ? "btn btn-default" : "btn " + settings.CssClass; 872 if (settings.Type == FieldType.Button) 873 { 874 if (settings.Label.IsNullOrEmpty()) 875 { 876 settings.Label = Translate("Button"); 877 } 878 @GetHtmlElement("button", GetAttributes(settings)) 879 @InternalRenderLabel(settings) 880 @GetHtmlElement("button", true) 881 } 882 else 883 { 884 @GetHtmlElement("input", GetAttributes(settings), true) 885 } 886 } 887 888 @InternalRenderFieldFooter(settings) 889 } 890 891 892 @* Forms for Editors field types in enum FieldType *@ 893 @helper InternalRenderTextStringField(FieldSettings settings) 894 { 895 settings.Assert(FieldType.Textstring); 896 897 if (settings.Description.IsNotNullOrEmpty() || settings.Control.IsNotNullOrEmpty()) 898 { 899 if (settings.Control.IsNotNullOrEmpty()) 900 { 901 @settings.Control 902 } 903 else 904 { 905 <p class="help-block">@settings.Description</p> 906 } 907 } 908 } 909 910 @helper InternalRenderImageField(FieldSettings settings) 911 { 912 settings.Assert(FieldType.Image); 913 914 if (settings.Control.IsNotNullOrEmpty()) 915 { 916 @settings.Control 917 } 918 } 919 920 @helper InternalRenderDividerField(FieldSettings settings) 921 { 922 settings.Assert(FieldType.Divider); 923 924 <hr class="divider" /> 925 } 926 927 @helper InternalRenderInputOptionField(string htmlElement, FieldOption optionSettings, FieldType type = FieldType.Radio) 928 { 929 var fieldType = type == FieldType.Checkboxlist ? FieldType.Checkbox.ToString().ToLower() : type.ToString().ToLower(); 930 var attributes = new StringBuilder(GetAttribute("type", fieldType)); 931 attributes.Append(GetAttribute("value", optionSettings.Value)); 932 attributes.Append(GetAttribute("name", optionSettings.SystemName)); 933 attributes.Append(optionSettings.Id.IsNotNullOrEmpty() ? GetAttribute("id", optionSettings.Id) : optionSettings.SystemName); 934 attributes.Append(GetAttributes(optionSettings.Attributes)); 935 936 if (optionSettings.IsSelected) 937 { 938 attributes.Append(GetAttribute("checked", "checked")); 939 } 940 if (optionSettings.IsDisabled) 941 { 942 attributes.Append(GetAttribute("disabled", "disabled")); 943 } 944 945 @GetHtmlElement(htmlElement, attributes.ToString()) 946 } 947 948 @helper InternalRenderOption(FieldOption optionSettings) 949 { 950 var selected = optionSettings.IsSelected ? " selected" : string.Empty; 951 var disabled = optionSettings.IsDisabled ? " disabled" : string.Empty; 952 var readOnly = optionSettings.IsReadOnly ? " readonly" : string.Empty; 953 var attributes = GetAttributes(optionSettings); 954 955 @GetHtmlElement("option", attributes + selected + disabled + readOnly) 956 @InternalRenderLabel(optionSettings.Label, optionSettings.TranslateKeyForLabel) 957 @GetHtmlElement("option", true) 958 } 959 960 @helper InternalRenderFieldHeader(FieldSettings settings, bool renderLabel = true) 961 { 962 @GetWrapperStart(settings.IncludeWrapper, settings.Type, settings.WrapperElement, settings.IsRequired, settings.WrapperCssClass) 963 if ((settings.Label.IsNotNullOrEmpty() || settings.TranslateKeyForLabel.IsNotNullOrEmpty()) && renderLabel) 964 { 965 var attributes = new Dictionary<string, string> 966 { 967 {"class", GetAttributeString("form-label", settings.LabelCssClass)} 968 }; 969 970 if (settings.Type != FieldType.Checkboxlist && settings.Type != FieldType.Radio) 971 { 972 attributes.Add("for", settings.SystemName); 973 } 974 975 @GetHtmlElement("label", attributes) 976 @InternalRenderLabel(settings) 977 @GetHtmlElement("label", true) 978 } 979 if (settings.Prepend.IsNotNullOrEmpty()) 980 { 981 var attributes = new Dictionary<string, string> 982 { 983 {"class", "fieldPrepend input-group-addon"} 984 }; 985 @GetHtmlElement("div", attributes) 986 @settings.Prepend 987 @GetHtmlElement("div", true) 988 } 989 if (settings.IncludeFieldWrapper) 990 { 991 @:<div class="fieldContainer hidden @settings.FieldWrapperCssClass"> 992 } 993 } 994 995 @helper InternalRenderFieldFooter(FieldSettings settings) 996 { 997 if (settings.Icon.IsNotNullOrEmpty()) 998 { 999 @RenderIcon(settings.Icon, settings.Tooltip, IconPosition.Left, true) 1000 } 1001 if (settings.Append.IsNotNullOrEmpty()) 1002 { 1003 <div class="fieldAppend input-group-addon">@settings.Append</div> 1004 } 1005 if (settings.Description.IsNotNullOrEmpty()) 1006 { 1007 <p class="help-block">@settings.Description</p> 1008 } 1009 if (settings.IncludeFieldWrapper) 1010 { 1011 @:</div> 1012 } 1013 @GetWrapperEnd(settings.IncludeWrapper, settings.WrapperElement) 1014 } 1015 1016 @helper InternalRenderQuantityField(int productStock, int productAvailableAmount, int selectedQuantity = 1, int productType = 0) 1017 { 1018 @InternalRenderQuantityField(productStock, productAvailableAmount, selectedQuantity, string.Empty, 10, false, false, productType) 1019 } 1020 1021 @helper InternalRenderQuantityField(int productStock, int productAvailableAmount, int selectedQuantity = 1, bool variantGroupsExistList = false) 1022 { 1023 @InternalRenderQuantityField(productStock, productAvailableAmount, selectedQuantity, string.Empty, 10, false, variantGroupsExistList) 1024 } 1025 1026 @helper InternalRenderQuantityField(int productStock, int productAvailableAmount, int selectedQuantity = 1, string fieldSystemName = "", int limit = 10, bool isCheckout = true, bool variantGroupsExistList = false, int productType = 0, string productId = "") 1027 { 1028 var isQuantityTextHidden = selectedQuantity < 10 && productStock > 0 || !isCheckout ? " hidden" : string.Empty; 1029 var isSelectDisabled = productStock <= 0 && !isCheckout; 1030 var quantityTextFieldSettings = new FieldSettings 1031 { 1032 Value = selectedQuantity.ToString(), 1033 SystemName = fieldSystemName.IsNullOrEmpty() ? "quantity" : fieldSystemName, 1034 Id = (fieldSystemName.IsNullOrEmpty() ? "quantity_" : fieldSystemName) + productId, 1035 Attributes = new Dictionary<string, string> 1036 { 1037 {"maxlength", "5"}, 1038 {"data-productStock", productStock.ToString()}, 1039 {"data-productAvailable", productAvailableAmount.ToString()}, 1040 {"data-outofstock", Translate("Out of stock")}, 1041 {"data-stocktranslate", Translate("The current stock is")}, 1042 {"data-currentValue", selectedQuantity.ToString()} 1043 } 1044 }; 1045 1046 if (productType != 1 && productType != 3) 1047 { 1048 quantityTextFieldSettings.Type = FieldType.Number; 1049 quantityTextFieldSettings.Label = Translate("Qty"); 1050 quantityTextFieldSettings.CssClass = "col-xs-4 col-sm-7 quantityInput" + isQuantityTextHidden; 1051 quantityTextFieldSettings.LabelCssClass = productStock > 0 ? "" : "hidden"; 1052 quantityTextFieldSettings.Attributes.Add("min", "1"); 1053 quantityTextFieldSettings.Attributes.Add("onblur", "checkMinValue(this);"); 1054 1055 <fieldset class="quantity-container pull-left"> 1056 @if (isCheckout) 1057 { 1058 <div class="@isQuantityTextHidden quantityPriceContainer"> 1059 @RenderField(quantityTextFieldSettings) 1060 @RenderBootstrapButton(new BootstrapButtonSettings {IconCssClass = "fa-refresh", CssClass = "submitQuantity btnCart-blue", ButtonType = BootstrapButtonSettings.BootstrapButtonType.Button}) 1061 </div> 1062 } 1063 else 1064 { 1065 @RenderField(quantityTextFieldSettings) 1066 } 1067 1068 @if (selectedQuantity < limit) 1069 { 1070 var quantityOptionLimit = productStock <= 0 ? 10 : productStock >= limit || variantGroupsExistList ? limit : productStock + 1; 1071 var quantityFieldSettings = new FieldSettings 1072 { 1073 Type = FieldType.Select, 1074 SystemName = "quantitySelect", 1075 Id = "quantitySelect" + productId 1076 }; 1077 if (isSelectDisabled) 1078 { 1079 quantityFieldSettings.Attributes.Add("disabled", "disabled"); 1080 } 1081 1082 for (var num = 1; num < quantityOptionLimit; num++) 1083 { 1084 var cssClass = num >= quantityOptionLimit ? "hidden" : ""; 1085 quantityFieldSettings.FieldOptionsList.Add(new FieldOption {Label = num.ToString(), Value = num.ToString(), IsSelected = selectedQuantity == num, CssClass = cssClass}); 1086 } 1087 1088 if (productStock >= limit || variantGroupsExistList) 1089 { 1090 var limitPlus = limit + "+"; 1091 var cssClass = variantGroupsExistList && productStock < limit ? "hidden" : ""; 1092 quantityFieldSettings.FieldOptionsList.Add(new FieldOption {Label = limitPlus, Value = limitPlus, CssClass = cssClass}); 1093 } 1094 @RenderField(quantityFieldSettings) 1095 } 1096 </fieldset> 1097 } 1098 else 1099 { 1100 quantityTextFieldSettings.Type = FieldType.Hidden; 1101 @RenderField(quantityTextFieldSettings) 1102 } 1103 } 1104 1105 @* Countries and Regions helpers *@ 1106 @helper InternalRenderCountryAndRegionsJsVariables(Dynamicweb.Ecommerce.International.CountryCollection countries = null) 1107 { 1108 if (countries == null) 1109 { 1110 countries = Dynamicweb.Ecommerce.Services.Countries.GetCountries(); 1111 } 1112 1113 if (countries.Any()) 1114 { 1115 @: @SnippetStart("jsVariables") var countryRegions = {}; @SnippetEnd("jsVariables") 1116 1117 foreach (var country in countries.OrderBy(s => s.Name)) 1118 { 1119 var regions = Dynamicweb.Ecommerce.Services.Countries.GetRegions(country.Code2); 1120 1121 if (regions.Any()) 1122 { 1123 @: @SnippetStart("jsVariables") countryRegions.@( country.Code2) = {}; @SnippetEnd("jsVariables") 1124 <text> 1125 @SnippetStart("jsVariables") 1126 countryRegions.@( country.Code2).code = []; 1127 countryRegions.@( country.Code2).name = []; 1128 @SnippetEnd("jsVariables") 1129 </text> 1130 foreach (var region in regions.OrderBy(s => s.Name)) 1131 { 1132 <text> 1133 @SnippetStart("jsVariables") 1134 countryRegions["@country.Code2"].code.push("@region.RegionCode"); 1135 countryRegions["@country.Code2"].name.push("@region.Name"); 1136 @SnippetEnd("jsVariables") 1137 </text> 1138 } 1139 } 1140 } 1141 } 1142 } 1143 1144 }@inherits RazorTemplateBase<RazorTemplateModel<Template>> 1145 @using Dynamicweb.Rendering 1146 @functions 1147 { 1148 public static bool IsBillingAddressReadOnly() 1149 { 1150 return Dna.Modules.Features.FeatureManager.IsEnabled("IsBillingAddressReadOnly", "Set to 'true' if the Billing Address should be read-only."); 1151 } 1152 1153 public static bool IsBillingAddressEditable() 1154 { 1155 return Dna.Modules.Features.FeatureManager.IsEnabled("IsBillingAddressEditable", "Set to 'true' if the Billing Address should be editable."); 1156 } 1157 1158 public static bool IsShippingAddressEditable() 1159 { 1160 return Dna.Modules.Features.FeatureManager.IsEnabled("IsShippingAddressEditable", "Set to 'true' if the Shipping Address should be editable."); 1161 } 1162 1163 public static bool ShowNoErpConnectionMessage() 1164 { 1165 return Dna.Modules.Features.FeatureManager.IsEnabled("showNoErpConnectionMessage", "Set to 'true' if want to show the 'No ERP Connection Message'."); 1166 } 1167 1168 public static bool ShowStateFieldAsDropdown() 1169 { 1170 return Dna.Modules.Features.FeatureManager.IsEnabled("showStateFieldAsDropdown", "Set to 'true' if the State field should be a drop-down."); 1171 } 1172 public static bool ShowVariantsAsDropdown() 1173 { 1174 return Dna.Modules.Features.FeatureManager.IsEnabled("showVariantsAsDropdown", "Set to 'true' if the Variant field should be a drop-down."); 1175 } 1176 public static bool ShowB2BLogin() 1177 { 1178 return Dna.Modules.Features.FeatureManager.IsEnabled("showB2BLogin", "Set to 'true' if it should display a login page."); 1179 } 1180 public static bool ShowRatings() 1181 { 1182 return Dna.Modules.Features.FeatureManager.IsEnabled("showRatrings", "Set to 'true' if ratings should be displayed."); 1183 } 1184 public static bool ShowReviews() 1185 { 1186 return Dna.Modules.Features.FeatureManager.IsEnabled("showReviews", "Set to 'true' if reviews should be displayed."); 1187 } 1188 1189 public static bool ShowRatingInProductList() 1190 { 1191 return Dna.Modules.Features.FeatureManager.IsEnabled("showRatingInProductList", "Set to 'true' if ratings in product list should be displayed."); 1192 } 1193 } 1194 @functions{ 1195 1196 #region Css functions 1197 1198 public static string GetPalletColorNumber(int number = 0) 1199 { 1200 switch (number) 1201 { 1202 case 1: 1203 return "#666666"; 1204 case 2: 1205 return "#092138"; 1206 default: 1207 return "#ffffff"; 1208 } 1209 } 1210 1211 public static string GetFontFamilyNumber(int number = 0) 1212 { 1213 switch (number) 1214 { 1215 case 1: 1216 return "font-family: Arial, sans-serif;"; 1217 default: 1218 return "font-family: Helvetica, Arial, sans-serif;"; 1219 } 1220 } 1221 1222 public static string GetFontSize(int fontSize = 0) 1223 { 1224 return fontSize >= 0 ? string.Concat("font-size: ", fontSize, "px;") : "font-size: 14px"; 1225 } 1226 1227 #endregion Css functions 1228 1229 #region Icon functions 1230 1231 public static string GetIcon(string cssPartialClass, string label = "", string position = "") 1232 { 1233 var icon = "<i class='fa " + cssPartialClass + "'></i>"; 1234 var spacing = string.Empty; 1235 1236 if (!label.IsNullOrEmpty()) 1237 { 1238 spacing = "&nbsp;"; 1239 } 1240 1241 if (cssPartialClass.IsNullOrEmpty()) return label; 1242 if (position == IconPosition.Left.ToString() || position.IsNullOrEmpty()) 1243 { 1244 return icon + spacing + label; 1245 } 1246 return label + spacing + icon; 1247 } 1248 1249 #endregion Icon functions 1250 1251 #region Address functions 1252 1253 public string GetAddressFormatted(User user, bool getRegionName = false, bool getCountryName = false, bool addLineBreakBetweenAddressAndCity = false, string splitBetweenRegionAndCountry = " ") 1254 { 1255 return GetAddressFormatted(user.Address, user.Address2, user.City, user.State, user.Zip, user.Country, getRegionName, getCountryName, addLineBreakBetweenAddressAndCity, splitBetweenRegionAndCountry); 1256 } 1257 1258 public string GetAddressFormatted(UserAddress userAddress, bool getRegionName = false, bool getCountryName = false, bool addLineBreakBetweenAddressAndCity = false, string splitBetweenRegionAndCountry = " ") 1259 { 1260 return GetAddressFormatted(userAddress.Address, userAddress.Address2, userAddress.City, userAddress.State, userAddress.Zip, userAddress.Country, getRegionName, getCountryName, addLineBreakBetweenAddressAndCity, splitBetweenRegionAndCountry); 1261 } 1262 1263 public string GetAddressFormatted(AddressSource addressSource, bool getRegionName = false, bool getCountryName = false, bool addLineBreakBetweenAddressAndCity = false, string splitBetweenRegionAndCountry = " ") 1264 { 1265 switch (addressSource) 1266 { 1267 case AddressSource.UserProfile: 1268 return GetAddressFormatted( 1269 GetString("UserManagement:User.Address"), 1270 GetString("UserManagement:User.Address2"), 1271 GetString("UserManagement:User.City"), 1272 GetString("UserManagement:User.State"), 1273 GetString("UserManagement:User.Zip"), 1274 GetString("UserManagement:User.Country"), 1275 getRegionName, 1276 getCountryName, 1277 addLineBreakBetweenAddressAndCity, 1278 splitBetweenRegionAndCountry 1279 ); 1280 case AddressSource.EcomCustomer: 1281 return GetAddressFormatted( 1282 GetString("Ecom:Order.Customer.Address"), 1283 GetString("Ecom:Order.Customer.Address2"), 1284 GetString("Ecom:Order.Customer.City"), 1285 GetString("Ecom:Order.Customer.Region"), 1286 GetString("Ecom:Order.Customer.Zip"), 1287 GetString("Ecom:Order.Customer.Country"), 1288 getRegionName, 1289 getCountryName, 1290 addLineBreakBetweenAddressAndCity, 1291 splitBetweenRegionAndCountry 1292 ); 1293 case AddressSource.EcomDelivery: 1294 return GetAddressFormatted( 1295 GetString("Ecom:Order.Delivery.Address"), 1296 GetString("Ecom:Order.Delivery.Address2"), 1297 GetString("Ecom:Order.Delivery.City"), 1298 GetString("Ecom:Order.Delivery.Region"), 1299 GetString("Ecom:Order.Delivery.Zip"), 1300 GetString("Ecom:Order.Delivery.Country"), 1301 getRegionName, 1302 getCountryName, 1303 addLineBreakBetweenAddressAndCity, 1304 splitBetweenRegionAndCountry 1305 ); 1306 case AddressSource.UserAddress: 1307 throw new NotImplementedException("Not applicable"); 1308 default: 1309 throw new ArgumentOutOfRangeException("addressSource property", addressSource, null); 1310 } 1311 } 1312 1313 public string GetAddressFormatted(string address, string address2, string city, string zip, string region, string country, bool getRegionName = false, bool getCountryName = false, bool addLineBreakBetweenAddressAndCity = false, string splitBetweenRegionAndCountry = " ") 1314 { 1315 var formattedAddress = new StringBuilder(address); 1316 1317 if (address2.IsNotNullOrEmpty()) 1318 { 1319 formattedAddress.Append(string.Concat(" ",address2)); 1320 } 1321 if (addLineBreakBetweenAddressAndCity && (city + region + country).IsNotNullOrEmpty()) 1322 { 1323 formattedAddress.Append("<br/>"); 1324 } 1325 if (city.IsNotNullOrEmpty()) 1326 { 1327 formattedAddress.Append(string.Concat(" ",city)); 1328 } 1329 if (zip.IsNotNullOrEmpty()) 1330 { 1331 formattedAddress.Append(string.Concat(" ",zip)); 1332 } 1333 if (region.IsNotNullOrEmpty()) 1334 { 1335 formattedAddress.Append(zip.IsNotNullOrEmpty() ? string.Empty : ","); 1336 if (getRegionName && country.IsNotNullOrEmpty()) 1337 { 1338 var getRegions = Services.Countries.GetRegions(country); 1339 if(getRegions != null) { 1340 var regionName = getRegions.First(c => c.RegionCode == region).Name; 1341 region = regionName.IsNotNullOrEmpty() ? regionName : region; 1342 } 1343 } 1344 formattedAddress.Append(string.Concat(" ",region)); 1345 } 1346 1347 if (country.IsNullOrEmpty()) 1348 { 1349 return formattedAddress.ToString(); 1350 } 1351 1352 formattedAddress.Append(splitBetweenRegionAndCountry.IsNotNullOrEmpty() ? splitBetweenRegionAndCountry : " "); 1353 if (getCountryName) 1354 { 1355 var getCountry = Services.Countries.GetCountry(country); 1356 if(getCountry != null) 1357 { 1358 var countryName = getCountry.Name; 1359 country = countryName.IsNotNullOrEmpty() ? countryName : country; 1360 } 1361 } 1362 formattedAddress.Append(country); 1363 1364 return formattedAddress.ToString(); 1365 } 1366 1367 #endregion Address functions 1368 1369 #region Field helper functions 1370 1371 const string HighlightedCountriesSplit = "----------------"; 1372 1373 internal readonly List<string> HighlightedCountries = new List<string> 1374 { 1375 "CA", 1376 "US", 1377 HighlightedCountriesSplit 1378 }; 1379 1380 #endregion Field helper functions 1381 1382 #region Generic functions 1383 1384 private static int FormatInteger(object value) 1385 { 1386 int num; 1387 if (value == null) 1388 { 1389 value = string.Empty; 1390 } 1391 return int.TryParse(value.ToString(), out num) ? num : 0; 1392 } 1393 1394 #endregion Generic functions 1395 } 1396 @{ 1397 @* Tables and list helpers *@ 1398 @helper RenderTableHeading(string label, string sortByField = "", string listType = "Order") 1399 { 1400 if (sortByField.IsNotNullOrEmpty()) 1401 { 1402 var href = string.Empty; 1403 var icon = "fa-sort-amount-asc"; 1404 var sortOrder = "asc"; 1405 1406 if (listType == "Order" || listType == "Rma") 1407 { 1408 href = GetCustomerCenterSortUrl(sortByField, listType); 1409 if (GetSortFieldParameter("name") == sortByField) 1410 { 1411 sortOrder = GetSortFieldParameter("value", sortByField).ToLower(); 1412 icon = "fa-sort-amount-" + sortOrder; 1413 1414 } 1415 } 1416 else if (listType == "DataList") 1417 { 1418 var sortByParameter = Sanitize.Parameter("sortby").IsNotNullOrEmpty() ? Sanitize.Parameter("sortby") : string.Empty; 1419 var sortOrderParameter = Sanitize.Parameter("sortorder").IsNotNullOrEmpty() ? Sanitize.Parameter("sortorder") : "ASC"; 1420 1421 href = GetDataListSortUrl(sortByField); 1422 if (sortByParameter == sortByField) 1423 { 1424 sortOrder = sortOrderParameter.ToLower(); 1425 icon = "fa-sort-amount-" + sortOrder; 1426 sortOrder = sortOrder == "asc" ? "desc" : "asc"; 1427 } 1428 } 1429 <a href="@href" data-sortby="@sortByField" data-sortorder="@sortOrder.ToUpperInvariant()"> 1430 @RenderIcon(icon, label, IconPosition.Right) 1431 </a> 1432 } 1433 else 1434 { 1435 @label 1436 } 1437 } 1438 1439 @helper RenderDataListItem(string label, string value, string labelCss = "col-xs-4 text-right", string valueCss = "col-xs-8", string alternativeValue = "", bool isLabelBold = true) 1440 { 1441 if (value.IsNotNullOrEmpty() || alternativeValue.IsNotNullOrEmpty()) 1442 { 1443 var displayValue = alternativeValue.IsNullOrEmpty() ? value : alternativeValue; 1444 1445 <dt class="@labelCss"> 1446 @if (isLabelBold) 1447 { 1448 @: <strong> 1449 } 1450 @label 1451 @if (isLabelBold) 1452 { 1453 @: </strong> 1454 } 1455 </dt> 1456 <dd class="@valueCss"> 1457 @displayValue 1458 </dd> 1459 } 1460 } 1461 1462 @helper RenderTableRowSpacer(int height = 30, int colspan = 1) 1463 { 1464 if (height == 0) 1465 { 1466 height = 30; 1467 } 1468 1469 <tr> 1470 @if (colspan > 1) 1471 { 1472 @: <td colspan="@colspan" height="@height"></td> 1473 } 1474 else 1475 { 1476 <td height="@height"></td> 1477 } 1478 </tr> 1479 } 1480 1481 @helper RenderTableCellSpacer(int width = 10, int height = 10) 1482 { 1483 if (width == 0) 1484 { 1485 width = 10; 1486 } 1487 if (height == 0) 1488 { 1489 height = 10; 1490 } 1491 <td width="@width" height="@height">&nbsp;</td> 1492 } 1493 1494 1495 @* Tab helpers *@ 1496 @helper RenderTabContent(string tabKey, string tabLabel, string tabContent, string cssClass = "") 1497 { 1498 if (tabContent.IsNotNullOrEmpty()) 1499 { 1500 @InternalRenderTabHeader("#" + tabKey, tabLabel, cssClass) 1501 <div class="col-xs-12 @cssClass" id="@tabKey"> 1502 @tabContent 1503 </div> 1504 } 1505 } 1506 1507 1508 @* Field helpers *@ 1509 @helper RenderField(FieldSettings settings) 1510 { 1511 switch (settings.Type) 1512 { 1513 case FieldType.Button: 1514 case FieldType.Reset: 1515 case FieldType.Submit: 1516 @InternalRenderButtonField(settings) 1517 break; 1518 case FieldType.Checkbox: 1519 @InternalRenderCheckboxField(settings) 1520 break; 1521 case FieldType.Image: 1522 @InternalRenderImageField(settings) 1523 break; 1524 case FieldType.Checkboxlist: 1525 case FieldType.Radio: 1526 @InternalRenderRadioOrCheckboxListField(settings) 1527 break; 1528 case FieldType.Select: 1529 @InternalRenderSelectField(settings) 1530 break; 1531 case FieldType.Color: 1532 case FieldType.Date: 1533 case FieldType.DatetimeLocal: 1534 case FieldType.Email: 1535 case FieldType.File: 1536 case FieldType.Hidden: 1537 case FieldType.Password: 1538 case FieldType.Month: 1539 case FieldType.Number: 1540 case FieldType.Range: 1541 case FieldType.Search: 1542 case FieldType.Tel: 1543 case FieldType.Text: 1544 case FieldType.Time: 1545 case FieldType.Url: 1546 case FieldType.Week: 1547 @InternalRenderInputField(settings) 1548 break; 1549 case FieldType.Textarea: 1550 @InternalRenderTextareaField(settings) 1551 break; 1552 case FieldType.Textstring: 1553 @InternalRenderTextStringField(settings) 1554 break; 1555 case FieldType.Divider: 1556 @InternalRenderDividerField(settings) 1557 break; 1558 case FieldType.Datetime: 1559 @InternalRenderDateTimeField(settings) 1560 break; 1561 case FieldType.Unknown: 1562 @:<div style="color: #f00">Undefined FieldType: <strong>@settings.Type</strong></div> 1563 break; 1564 default: 1565 throw new NotSupportedException(string.Format("Unsupported Field Type: {0}.", settings.Type.ToString())); 1566 } 1567 } 1568 1569 @helper RenderCountriesDropdownField(List<string> countries, bool renderJsVariables = true, bool renderHighlightOptions = true, bool isFirstHardcodedOptionDisabled = true) 1570 { 1571 var settings = new FieldSettings 1572 { 1573 SystemName = "country", 1574 Id = "country", 1575 Label = Translate("Select your country:"), 1576 FirstHardcodedOptionLabel = Translate("All"), 1577 ValuesList = countries 1578 }; 1579 @RenderCountriesDropdownField(settings, renderJsVariables, renderHighlightOptions, isFirstHardcodedOptionDisabled) 1580 } 1581 1582 @helper RenderCountriesDropdownField(FieldSettings settings, bool renderJsVariables = true, bool renderHighlightOptions = true, bool isFirstHardcodedOptionDisabled = true) 1583 { 1584 1585 if (settings.SystemName.IsNotNullOrEmpty()) 1586 { 1587 const int limit = 10; 1588 const int numOfCountriesForHighlight = 10; 1589 var countries = EcommerceHelpers.GetEcomCountries(); 1590 var numOfCountries = settings.LoopOptions.Any() ? settings.LoopOptions.Count : settings.ValuesList.Any() ? settings.ValuesList.Count : countries.Count; 1591 1592 settings.Assert(FieldType.Select); 1593 if (settings.FirstHardcodedOptionLabel.IsNullOrEmpty()) 1594 { 1595 settings.FirstHardcodedOptionLabel = Translate("Select an option"); 1596 } 1597 if (!settings.Attributes.ContainsKey("multiple") && !settings.Attributes.ContainsKey("data-live-search") && numOfCountries > limit) 1598 { 1599 settings.Attributes.Add("data-live-search", "true"); 1600 } 1601 1602 if (renderJsVariables) 1603 { 1604 @InternalRenderCountryAndRegionsJsVariables(countries) 1605 } 1606 1607 @InternalRenderFieldHeader(settings) 1608 @GetHtmlElement("select", GetAttributes(settings)) 1609 @InternalRenderOption(FieldOption.CreateOption(settings.FirstHardcodedOptionLabel, settings.FirstHardcodedOptionValue, settings.IsFirstHardcodedOptionSelected, isFirstHardcodedOptionDisabled)) 1610 1611 1612 if (numOfCountries > numOfCountriesForHighlight) 1613 { 1614 @RenderSnippet("highlightedContries") 1615 } 1616 1617 if (settings.LoopOptions.Any()) 1618 { 1619 1620 foreach (var country in settings.LoopOptions) 1621 { 1622 var countryName = country.GetString("Ecom:Country.Name"); 1623 var countryCode = country.GetString("Ecom:Country.Code2"); 1624 1625 if (renderHighlightOptions && HighlightedCountries.Any(c => c.Equals(countryCode, StringComparison.CurrentCultureIgnoreCase))) 1626 { 1627 @PopulateHighlightedCountries(countryName, countryCode) 1628 } 1629 else 1630 { 1631 @InternalRenderOption(FieldOption.CreateOption(countryName, countryCode)) 1632 } 1633 1634 } 1635 } 1636 else if (settings.ValuesList.Any()) 1637 { 1638 foreach (var countryCode in settings.ValuesList.OrderBy(s => s)) 1639 { 1640 var countryName = countries.Any(c => c.Code2 == countryCode) ? countries.First(c => c.Code2 == countryCode).Name : countryCode; 1641 1642 if (renderHighlightOptions && HighlightedCountries.Any(c => c.Equals(countryCode, StringComparison.CurrentCultureIgnoreCase))) 1643 { 1644 @PopulateHighlightedCountries(countryName, countryCode) 1645 } 1646 else 1647 { 1648 @InternalRenderOption(FieldOption.CreateOption(countryName, countryCode)) 1649 } 1650 1651 } 1652 } 1653 else 1654 { 1655 foreach (var country in countries.OrderBy(s => s.Name)) 1656 { 1657 var countryCode = country.Code2; 1658 1659 if (renderHighlightOptions && HighlightedCountries.Any(c => c.Equals(countryCode, StringComparison.CurrentCultureIgnoreCase))) 1660 { 1661 @PopulateHighlightedCountries(country.Name, countryCode) 1662 } 1663 else 1664 { 1665 @InternalRenderOption(FieldOption.CreateOption(country.Name, countryCode)) 1666 } 1667 1668 } 1669 } 1670 1671 if (renderHighlightOptions && numOfCountries > numOfCountriesForHighlight && HighlightedCountries.Any(c => HighlightedCountriesSplit.Equals(c, StringComparison.CurrentCultureIgnoreCase))) 1672 { 1673 @PopulateHighlightedCountries(HighlightedCountriesSplit, string.Empty, false, true) 1674 } 1675 1676 @GetHtmlElement("select", true) 1677 1678 @InternalRenderFieldFooter(settings) 1679 } 1680 } 1681 1682 @helper PopulateHighlightedCountries(string label, string value, bool isSelected = false, bool isDisabled = false) 1683 { 1684 HighlightedCountries.Remove(value); 1685 if (value.IsNullOrEmpty()) 1686 { 1687 HighlightedCountries.Remove(label); 1688 } 1689 @SnippetStart("highlightedContries") 1690 @InternalRenderOption(FieldOption.CreateOption(label, value, isSelected, isDisabled)) 1691 @SnippetEnd("highlightedContries") 1692 } 1693 1694 1695 @* Paging helpers *@ 1696 @helper RenderPaging() 1697 { 1698 @RenderPaging( 1699 GetInteger("Ecom:CustomerCenter.Paging.NumPages"), 1700 "CCPage", 1701 GetString("Ecom:CustomerCenter.Paging.Back.URL"), 1702 GetString("Ecom:CustomerCenter.Paging.Forward.URL"), 1703 GetInteger("Ecom:CustomerCenter.Paging.CurrentPage"), 1704 GetLoop("Ecom:CustomerCenter.Paging.Pages"), 1705 "Ecom:CustomerCenter.Paging.PageIndex" 1706 ) 1707 } 1708 1709 @helper RenderPaging(int numOfPages, string pageQueryParameter, int currentPage) 1710 { 1711 var queryParameters = HttpUtility.ParseQueryString(Dynamicweb.Context.Current.Request.Url.Query); 1712 var url = Helpers.GetCurrentUrl(true, true); 1713 var previousPageUrl = string.Empty; 1714 var nextPageUrl = string.Empty; 1715 1716 if (currentPage > 1) 1717 { 1718 queryParameters = Helpers.UpdateQueryStringKeyValue(queryParameters, pageQueryParameter, (currentPage - 1).ToString()); 1719 previousPageUrl = Helpers.BuildUri(url, queryParameters).ToString(); 1720 } 1721 if (currentPage < numOfPages) 1722 { 1723 queryParameters = Helpers.UpdateQueryStringKeyValue(queryParameters, pageQueryParameter, (currentPage + 1).ToString()); 1724 nextPageUrl = Helpers.BuildUri(url, queryParameters).ToString(); 1725 } 1726 1727 @RenderPaging(numOfPages, pageQueryParameter, previousPageUrl, nextPageUrl, currentPage) 1728 } 1729 1730 @helper RenderPaging(int numOfPages, string pageQueryParameter, string previousPageUrl, string nextPageUrl, int currentPage, List<LoopItem> pagesLoop = null, string pageNumTag = "", string pageHrefTag = "", bool includeWrapper = true) 1731 { 1732 if (numOfPages > 1) 1733 { 1734 @* NOTE: pageIndex needs to be a tag name, because it will be instanciated within the loop *@ 1735 @* NOTE: 1736 queryParamenter == "PageNum" --> Product Catalog module 1737 queryParamenter == "page" --> Item Publisher module 1738 queryParamenter == "CC*" --> Customer Center module 1739 queryParamenter == "DWPagingPageNum" --> Data List module 1740 *@ 1741 1742 var loopPageSize = 3; 1743 var startPage = 1; 1744 var endPage = numOfPages; 1745 1746 var pageQueryParameter2 = pageQueryParameter == "PageNum" || pageQueryParameter == "page" || pageQueryParameter == "DWPagingPageNum" ? string.Empty : Pageview.CurrentParagraph.ID.ToString(); 1747 var pageNumQueryParameter = pageQueryParameter + pageQueryParameter2; 1748 1749 var queryParameters = HttpUtility.ParseQueryString(Dynamicweb.Context.Current.Request.Url.Query); 1750 queryParameters.Remove(pageNumQueryParameter); 1751 queryParameters.Remove("pid"); 1752 1753 if (pageQueryParameter == "page") 1754 { 1755 queryParameters.Add("pid", Pageview.CurrentParagraph.ID.ToString()); 1756 } 1757 1758 if (pagesLoop != null) 1759 { 1760 loopPageSize = pagesLoop.Count; 1761 endPage = 1; 1762 } 1763 else 1764 { 1765 var pageOffset = Math.Floor(Convert.ToDecimal(loopPageSize / 2)); 1766 var middlePage = pageOffset + 1; 1767 1768 if (numOfPages > loopPageSize) 1769 { 1770 startPage = Convert.ToInt32(currentPage - pageOffset) < 1 ? 1 : Convert.ToInt32(currentPage - pageOffset); 1771 endPage = Convert.ToInt32(currentPage + pageOffset) > numOfPages ? numOfPages : Convert.ToInt32(currentPage + pageOffset); 1772 1773 if (currentPage < middlePage) 1774 { 1775 endPage = loopPageSize; 1776 } 1777 else if (currentPage >= middlePage) 1778 { 1779 if (numOfPages < currentPage + pageOffset) 1780 { 1781 startPage = numOfPages - loopPageSize; 1782 if (loopPageSize % 2 != 0) 1783 { 1784 startPage += 1; 1785 } 1786 } 1787 1788 if (loopPageSize % 2 == 0) 1789 { 1790 startPage += 1; 1791 } 1792 } 1793 } 1794 } 1795 1796 if (includeWrapper) 1797 { 1798 @:<div class="col-xs-12 text-center paginationContainer"> 1799 } 1800 <ul class="pagination"> 1801 @if (previousPageUrl.IsNotNullOrEmpty() && previousPageUrl != "#") 1802 { 1803 @InternalRenderPageItem(previousPageUrl, Translate("Previous"), "fa-caret-left", IconPosition.Left) 1804 } 1805 @if (pagesLoop != null) 1806 { 1807 @InternalRenderGoToFirstPage(queryParameters, pageNumQueryParameter, currentPage, numOfPages, loopPageSize, pagesLoop[0].GetInteger(pageNumTag)) 1808 foreach (var page in pagesLoop) 1809 { 1810 var pageItemHref = pageQueryParameter == "PageNum" || pageQueryParameter == "page" ? page.GetString(pageHrefTag) : string.Empty; 1811 endPage = page.GetInteger(pageNumTag); 1812 1813 queryParameters.Remove(pageNumQueryParameter); 1814 if (pageItemHref.IsNotNullOrEmpty()) 1815 { 1816 queryParameters.Add(pageNumQueryParameter, page.GetString(pageNumTag)); 1817 } 1818 @InternalRenderPageItem(queryParameters, page.GetString(pageNumTag), page.GetInteger(pageNumTag) == currentPage ? "active" : string.Empty) 1819 1820 } 1821 @InternalRenderGoToLastPage(queryParameters, pageNumQueryParameter, currentPage, numOfPages, loopPageSize, endPage) 1822 } 1823 else 1824 { 1825 @InternalRenderGoToFirstPage(queryParameters, pageNumQueryParameter, currentPage, numOfPages, loopPageSize) 1826 for (var page = startPage; page <= endPage; page++) 1827 { 1828 queryParameters = Helpers.UpdateQueryStringKeyValue(queryParameters, pageNumQueryParameter, page.ToString()); 1829 @InternalRenderPageItem(queryParameters, page.ToString(), page == currentPage ? "active" : string.Empty) 1830 } 1831 @InternalRenderGoToLastPage(queryParameters, pageNumQueryParameter, currentPage, numOfPages, loopPageSize, endPage) 1832 } 1833 1834 @if (nextPageUrl.IsNotNullOrEmpty() && nextPageUrl != "#") 1835 { 1836 @InternalRenderPageItem(nextPageUrl, Translate("Next"), "fa-caret-right", IconPosition.Right) 1837 } 1838 </ul> 1839 if (includeWrapper) 1840 { 1841 @:</div> 1842 } 1843 } 1844 } 1845 1846 1847 @* Generic helpers *@ 1848 @helper RenderIcon(string cssPartialClass, string label = "", IconPosition position = IconPosition.Left, bool isLabelATooltip = false) 1849 { 1850 var icon = !isLabelATooltip ? "<i class='fa " + cssPartialClass + "'></i>" : "<i class='fa " + cssPartialClass + "' data-toggle='" + label + "'></i>"; 1851 var spacing = string.Empty; 1852 1853 if (label.IsNotNullOrEmpty()) 1854 { 1855 spacing = "&nbsp;"; 1856 } 1857 if (cssPartialClass.IsNotNullOrEmpty()) 1858 { 1859 if (isLabelATooltip) 1860 { 1861 @icon 1862 } 1863 else if (position == IconPosition.Left) 1864 { 1865 @icon 1866 @spacing 1867 @label 1868 } 1869 else 1870 { 1871 @label 1872 @spacing 1873 @icon 1874 } 1875 } 1876 else 1877 { 1878 @label 1879 } 1880 } 1881 1882 @helper RenderStackedIcons(string cssPrincipalPartialClass, string cssSecondaryPartialClass, string label = "", IconPosition position = IconPosition.Left, bool isLabelATooltip = false) 1883 { 1884 var spacing = string.Empty; 1885 var icon = new StringBuilder("<span class='fa-stack'>"); 1886 1887 icon.Append(!isLabelATooltip ? "<i class='fa " + cssPrincipalPartialClass + " fa-stack-2x'></i>" : "<i class='fa " + cssPrincipalPartialClass + " fa-stack-2x' data-toggle='" + label + "'></i>"); 1888 icon.Append("<i class='fa " + cssSecondaryPartialClass + " fa-stack-1x'></i>"); 1889 icon.Append("</span>"); 1890 1891 if (label.IsNotNullOrEmpty()) 1892 { 1893 spacing = "<text>&nbsp;</text>"; 1894 } 1895 if (cssPrincipalPartialClass.IsNotNullOrEmpty() && cssSecondaryPartialClass.IsNotNullOrEmpty()) 1896 { 1897 if (isLabelATooltip) 1898 { 1899 @icon.ToString() 1900 } 1901 else if (position == IconPosition.Left) 1902 { 1903 @icon.ToString() 1904 @spacing 1905 @label 1906 } 1907 else 1908 { 1909 @label 1910 @spacing 1911 @icon.ToString() 1912 } 1913 } 1914 else 1915 { 1916 @label 1917 } 1918 } 1919 1920 @helper RenderAction(IconAction action, string href = "", string title = "", string onClickConfirm = "") 1921 { 1922 var attributes = new Dictionary<string, string>(); 1923 1924 if (title.IsNotNullOrEmpty()) 1925 { 1926 attributes.Add("title", title); 1927 } 1928 if (onClickConfirm.IsNotNullOrEmpty()) 1929 { 1930 attributes.Add("onclick", "return confirm('" + onClickConfirm + "');"); 1931 } 1932 if (href.IsNotNullOrEmpty()) 1933 { 1934 attributes.Add("href", href); 1935 } 1936 @RenderAction(action, href, attributes) 1937 } 1938 1939 @helper RenderAction(IconAction action, string href, Dictionary<string, string> attributes) 1940 { 1941 var icon = string.Empty; 1942 var linkAttributes = string.Empty; 1943 var label = Translate(action.ToString()); 1944 1945 switch (action) 1946 { 1947 case IconAction.Add: 1948 break; 1949 case IconAction.View: 1950 icon = "fa-eye"; 1951 break; 1952 case IconAction.Edit: 1953 icon = "fa-edit"; 1954 break; 1955 case IconAction.Cancel: 1956 case IconAction.Remove: 1957 icon = "fa-times"; 1958 break; 1959 case IconAction.Delete: 1960 icon = "fa-trash"; 1961 break; 1962 case IconAction.Print: 1963 icon = "fa-print"; 1964 attributes.Add("target", "_blank"); 1965 label = string.Empty; 1966 break; 1967 case IconAction.Save: 1968 break; 1969 case IconAction.Reset: 1970 break; 1971 case IconAction.Undo: 1972 break; 1973 case IconAction.Reorder: 1974 icon = "fa-repeat"; 1975 break; 1976 case IconAction.SetDefault: 1977 icon = "fa-times"; 1978 label = string.Empty; 1979 break; 1980 case IconAction.IsDefault: 1981 icon = "fa-check"; 1982 label = string.Empty; 1983 break; 1984 default: 1985 throw new NotSupportedException("An action is needed to render this helper!"); 1986 } 1987 if (icon.IsNotNullOrEmpty()) 1988 { 1989 if (href.IsNotNullOrEmpty()) 1990 { 1991 @GetHtmlElement("a", GetAttributes(attributes)) 1992 @RenderIcon(icon, label) 1993 @GetHtmlElement("a", true) 1994 } 1995 else if (label.IsNullOrEmpty()) 1996 { 1997 @RenderIcon(icon) 1998 } 1999 } 2000 2001 } 2002 2003 @helper RenderBootstrapButton(BootstrapButtonSettings settings) 2004 { 2005 var attributes = new StringBuilder(GetAttribute("class", "btn " + (settings.CssClass.IsNotNullOrEmpty() ? settings.CssClass : "btn-default"))); 2006 attributes.Append(GetAttribute("target", settings.Target)); 2007 attributes.Append(GetAttribute("href", settings.Href)); 2008 attributes.Append(GetAttribute("name", settings.SystemName)); 2009 attributes.Append(GetAttribute("id", settings.Id)); 2010 attributes.Append(GetAttribute("value", settings.Value)); 2011 if (settings.ButtonType == BootstrapButtonSettings.BootstrapButtonType.Button && !settings.Attributes.ContainsKey("type")) 2012 { 2013 settings.Attributes.Add("type","submit"); 2014 } 2015 2016 attributes.Append(GetAttributes(settings.Attributes)); 2017 string htmlElement; 2018 2019 switch (settings.ButtonType) 2020 { 2021 case BootstrapButtonSettings.BootstrapButtonType.Button: 2022 htmlElement = "button"; 2023 break; 2024 case BootstrapButtonSettings.BootstrapButtonType.Anchor: 2025 htmlElement = "a"; 2026 break; 2027 default: 2028 throw new NotSupportedException(string.Format("Unsupported Bootstrap Button type: {0}.", settings.ButtonType.ToString())); 2029 } 2030 @GetHtmlElement(htmlElement, attributes.ToString()) 2031 @RenderIcon(settings.IconCssClass, settings.Label, settings.IconPosition) 2032 @GetHtmlElement(htmlElement, true) 2033 } 2034 2035 @helper RenderAddToCart(string productId, string productVariantId, int availableAmount = 0, bool doNotRenderHiddenFields = false) 2036 { 2037 var addToCartButtonSettings = new BootstrapButtonSettings 2038 { 2039 Label = Translate("Add to Cart"), 2040 CssClass = availableAmount <= 0 ? "btn-default addToCartSubmit disabled" : "btn-default addToCartSubmit", 2041 Href = string.Concat(Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "MiniCart").ID),"?productid=", productId, "&amp;variantID=", productVariantId, "&amp;cartcmd=add"), 2042 IconCssClass = "fa-shopping-cart", 2043 Attributes = new Dictionary<string, string> 2044 { 2045 {"data-add", Translate("Add to Cart")}, 2046 {"data-added", Translate("Added")}, 2047 {"data-outofstock", Translate("Out of stock")}, 2048 {"data-stock", availableAmount.ToString()} 2049 } 2050 }; 2051 @RenderBootstrapButton(addToCartButtonSettings) 2052 if (!doNotRenderHiddenFields) 2053 { 2054 @RenderField(FieldSettings.CreateHiddenField("redirect", "false", "redirect" + productId)) 2055 @RenderField(FieldSettings.CreateHiddenField("cartcmd", "add", "cartcmd" + productId)) 2056 @RenderField(FieldSettings.CreateHiddenField("productid", productId, "productId" + productId)) 2057 @RenderField(FieldSettings.CreateHiddenField("variantid", productVariantId, "variantId" + productId + productVariantId)) 2058 } 2059 @RenderField(FieldSettings.CreateSubmitField(Translate("Add to Cart"), "hidden")) 2060 } 2061 2062 @helper RenderSocialMediaShare() 2063 { 2064 <div class="shareIcons"> 2065 <span>@Translate("Share")</span> 2066 @RenderSocialMedia(false, true) 2067 </div> 2068 } 2069 2070 @helper RenderOpenGraphMeta(string type, string image, string title, string teaser = "", string imageAlt = "") 2071 { 2072 var culture = Pageview.Area.Culture.Replace("-", "_"); 2073 teaser = System.Text.RegularExpressions.Regex.Replace(teaser, "<.*?>", string.Empty); 2074 if (type.IsNullOrEmpty()) 2075 { 2076 type = "article"; 2077 } 2078 if (imageAlt.IsNullOrEmpty()) 2079 { 2080 imageAlt = title; 2081 } 2082 2083 @SnippetStart("OGMeta") 2084 <meta property="og:title" content="@HttpUtility.HtmlEncode(title)"/> 2085 <meta property="og:image" content="@string.Concat(Helpers.GetCurrentUrl(true), image)"/> 2086 <meta property="og:image:width" content="600"/> 2087 <meta property="og:image:height" content="600"/> 2088 <meta property="og:image:alt" content="@HttpUtility.HtmlEncode(imageAlt)"/> 2089 <meta property="og:site_name" content="@Pageview.Area.Item["CompanyName"]"/> 2090 <meta property="og:url" content="@Helpers.GetCurrentUrl()"/> 2091 <meta property="og:description" content="@HttpUtility.HtmlEncode(teaser)"/> 2092 <meta property="og:type" content="@type"/> 2093 <meta property="og:locale" content="@culture"/> 2094 @SnippetEnd("OGMeta") 2095 } 2096 2097 @helper RenderSocialMedia(bool isEmailTemplate = false, bool isToShare = false) 2098 { 2099 var page = Dynamicweb.Extensibility.ServiceLocator.Current.GetPageService().GetPage(Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "GeneralSettings").ID); 2100 var generalSettings = Dynamicweb.Content.Items.Item.GetItemById(page.ItemType, page.ItemId); 2101 2102 if(generalSettings["SocialMedia"] != null) { 2103 var socialMedia = Dynamicweb.Content.Items.ItemList.GetItemListById(int.Parse(generalSettings["SocialMedia"].ToString())); 2104 2105 if(socialMedia.Relations.Any()) 2106 { 2107 if(!isEmailTemplate) 2108 { 2109 @:<ul class="socialMedia"> 2110 } 2111 foreach (var r in socialMedia.Relations) 2112 { 2113 var socialNetwork = Dynamicweb.Content.Items.Item.GetItemById("SocialLinks", r.Id); 2114 var className = (socialNetwork["Icon"] ?? "").ToString(); 2115 var socialName = (socialNetwork["Name"] ?? "").ToString(); 2116 var socialLink = (socialNetwork["Link"] ?? "").ToString(); 2117 var shareLink = (socialNetwork["ShareURL"] ?? "").ToString(); 2118 2119 if (isEmailTemplate) 2120 { 2121 @:&nbsp; 2122 <a title="@socialName" target="_blank" href="@socialLink">@socialName</a> 2123 @:&nbsp; 2124 } 2125 else if(!isToShare || shareLink.IsNotNullOrEmpty()) 2126 { 2127 <li> 2128 <a title="@socialName" class="@className fa" target="_blank" data-sharehref="@shareLink@Helpers.GetCurrentUrl()" href="@socialLink"><span class="hidden">@socialName</span></a> 2129 </li> 2130 } 2131 } 2132 if(!isEmailTemplate) 2133 { 2134 @:</ul> 2135 } 2136 } 2137 } 2138 } 2139 2140 @helper RenderNoResults(string wording, string title = "", bool hasWrapper = false, string wrapperClass = "col-xs-12 noPadding" ) 2141 { 2142 if (hasWrapper) 2143 { 2144 @:<div class="noResultsWrapper @wrapperClass"> 2145 } 2146 if (title.IsNotNullOrEmpty()) 2147 { 2148 <h2>@title</h2> 2149 } 2150 <p>@wording</p> 2151 if (hasWrapper) 2152 { 2153 @:</div> 2154 } 2155 } 2156 2157 @helper RenderImage(ImageSettings imageSettings) 2158 { 2159 var imageMarkup = new StringBuilder(); 2160 var widthAndHeight = GetWidthAndHeightFromQueryString(imageSettings.Source); 2161 var widthAndHeightForMobile = GetWidthAndHeightFromQueryString(imageSettings.SourceForMobile, true); 2162 var widthAndHeightForTablet = GetWidthAndHeightFromQueryString(imageSettings.SourceForTablet, true); 2163 2164 if (!imageSettings.Attributes.ContainsKey("width") && widthAndHeight.ContainsKey("width") && widthAndHeight["width"].IsNotNullOrEmpty()) 2165 { 2166 imageSettings.Attributes.Add("width", widthAndHeight["width"]); 2167 } 2168 if (!imageSettings.Attributes.ContainsKey("height") && widthAndHeight.ContainsKey("height") && widthAndHeight["height"].IsNotNullOrEmpty()) 2169 { 2170 imageSettings.Attributes.Add("height", widthAndHeight["height"]); 2171 } 2172 if (!imageSettings.Attributes.ContainsKey("class")) 2173 { 2174 imageSettings.Attributes.Add("class", "img-responsive " + imageSettings.CssClass); 2175 } 2176 if (!imageSettings.Attributes.ContainsKey("src")) 2177 { 2178 imageSettings.Attributes.Add("src", imageSettings.Source); 2179 } 2180 if (!imageSettings.Attributes.ContainsKey("alt")) 2181 { 2182 imageSettings.Attributes.Add("alt", imageSettings.AltText); 2183 } 2184 if (!imageSettings.Attributes.ContainsKey("title")) 2185 { 2186 imageSettings.Attributes.Add("title", imageSettings.Title); 2187 } 2188 2189 if (imageSettings.IncludeWrapper) 2190 { 2191 var wrapperAttributes = new Dictionary<string, string>(); 2192 if (imageSettings.WrapperCssClass.IsNotNullOrEmpty()) 2193 { 2194 wrapperAttributes.Add("class", imageSettings.WrapperCssClass); 2195 } 2196 2197 imageMarkup.Append(GetHtmlElement(imageSettings.WrapperElement, wrapperAttributes)); 2198 } 2199 2200 if (imageSettings.Href.IsNotNullOrEmpty()) 2201 { 2202 var linkAttributes = new Dictionary<string, string> {{"href", imageSettings.Href}}; 2203 if (imageSettings.HrefCssClass.IsNotNullOrEmpty()) 2204 { 2205 linkAttributes.Add("class", imageSettings.HrefCssClass); 2206 } 2207 if (imageSettings.HrefTarget.IsNotNullOrEmpty()) 2208 { 2209 linkAttributes.Add("target", imageSettings.HrefTarget); 2210 } 2211 2212 imageMarkup.Append(GetHtmlElement("a", linkAttributes)); 2213 } 2214 2215 if (widthAndHeightForMobile.Any() || widthAndHeightForTablet.Any()) 2216 { 2217 imageMarkup.Append(GetHtmlElement("picture")); 2218 2219 imageMarkup.Append(GetHtmlElement("source")); 2220 2221 if (widthAndHeightForMobile.Any()) 2222 { 2223 imageMarkup.Append(GetHtmlElement("srcset", widthAndHeightForMobile)); 2224 } 2225 2226 if (widthAndHeightForTablet.Any()) 2227 { 2228 imageMarkup.Append(GetHtmlElement("srcset", widthAndHeightForTablet)); 2229 } 2230 2231 imageMarkup.Append(GetHtmlElement("source", true)); 2232 } 2233 2234 imageMarkup.Append(GetHtmlElement("img", imageSettings.Attributes, true)); 2235 2236 if (imageSettings.SourceForMobile.IsNotNullOrEmpty() || imageSettings.SourceForTablet.IsNotNullOrEmpty()) 2237 { 2238 imageMarkup.Append(GetHtmlElement("picture", true)); 2239 } 2240 2241 if (imageSettings.Href.IsNotNullOrEmpty()) 2242 { 2243 imageMarkup.Append(GetHtmlElement("a", true)); 2244 } 2245 2246 if (imageSettings.IncludeWrapper) 2247 { 2248 imageMarkup.Append(GetHtmlElement(imageSettings.WrapperElement, true)); 2249 } 2250 2251 @imageMarkup.ToString() 2252 } 2253 2254 @helper RenderHtmlElementBetweenEachString(List<string> listOfStrings, string htmlElement = "br" ) 2255 { 2256 foreach (var str in listOfStrings) 2257 { 2258 if (str.IsNullOrEmpty()){continue;} 2259 @(string.Concat(str, GetHtmlElement(htmlElement, true))) 2260 } 2261 } 2262 2263 @helper RenderProductPrice(string productPrice = "") 2264 { 2265 var showNoErpConnectionMessage = ShowNoErpConnectionMessage(); 2266 var isWebServiceConnectionAvailable = Dna.Ecommerce.LiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 2267 2268 if (!isWebServiceConnectionAvailable && showNoErpConnectionMessage) 2269 { 2270 if (productPrice.IsNullOrEmpty()) 2271 { 2272 @RenderNoErpConnectionMessage() 2273 } 2274 else 2275 { 2276 <span class="noErpConnection">@Translate("Unavailable")</span> 2277 } 2278 } 2279 else 2280 { 2281 @productPrice 2282 } 2283 } 2284 2285 @helper RenderNoErpConnectionMessage() 2286 { 2287 <div class="col-xs-12 warningBox"> 2288 <p>@Translate("Pricing and inventory are currently not available. Please check back soon")</p> 2289 </div> 2290 } 2291 } 2292 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 2293 @using Dynamicweb.Rendering 2294 @using Dynamicweb.Core 2295 @using Dna.Frontend.UI 2296 @using Dynamicweb.Frontend 2297 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 2298 @using Dynamicweb.Rendering 2299 @using Dynamicweb.Core 2300 @using System 2301 @using System.Text 2302 @using System.Text.RegularExpressions 2303 @using System.Web.WebPages 2304 @using Dna.Frontend 2305 @using Dna.Frontend.UI 2306 @using Dna.ImageProcessing 2307 @functions 2308 { 2309 public static string StripHtml(string source) 2310 { 2311 return Regex.Replace(source, "<.*?>", string.Empty); 2312 } 2313 } 2314 @{ 2315 @helper InternalRenderStandardParagraphImageTag(string imageUrl, string link, string imageAlt, string imageWidth, string widthMobile, string itemWidth, string imageStyle, string itemLayout, string itemTitle, bool openInANewWindow) 2316 { 2317 if (imageUrl.IsNotNullOrEmpty()) 2318 { 2319 if (link.IsNullOrEmpty()) 2320 { 2321 @InternalRenderStandardParagraphImageWrapper(imageUrl, imageAlt, imageWidth, widthMobile, itemWidth, imageStyle, itemLayout, itemTitle) 2322 } 2323 else 2324 { 2325 var target = openInANewWindow ? "target='_blank'" : string.Empty; 2326 <a href="@link" @target> 2327 @InternalRenderStandardParagraphImageWrapper(imageUrl, imageAlt, imageWidth, widthMobile, itemWidth, imageStyle, itemLayout, itemTitle) 2328 </a> 2329 } 2330 } 2331 } 2332 2333 @helper InternalRenderStandardParagraphImageWrapper(string url, string alt, string width, string widthMobile, string itemWidth, string imageCssClass, string itemLayout, string itemTitle) 2334 { 2335 const int containerColumns = 12; 2336 var containerPixelWidth = Dynamicweb.Frontend.PageView.Current().Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile ? 480 : 1280; 2337 var imageAlt = alt.IsNotNullOrEmpty() ? alt : itemTitle; 2338 var figureCssClass = new StringBuilder("col-xs-" + width); 2339 var figureClass = imageCssClass; 2340 var itemSizeRatio = itemWidth.IsEmpty() ? 1 : Convert.ToDouble(itemWidth) / containerColumns; 2341 var imageSizeRatio = width.IsEmpty() || width == containerColumns.ToString() ? 1 : Convert.ToDouble(width) / containerColumns; 2342 2343 if (Dynamicweb.Frontend.PageView.Current().Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile && widthMobile.IsNotNullOrEmpty()) 2344 { 2345 imageSizeRatio = Convert.ToDouble(widthMobile) / containerColumns; 2346 } 2347 2348 @* Note - Optimized image width does not take into account paddings or margins the parent containers may have be affected on *@ 2349 var optimizedWidth = (int) (containerPixelWidth * itemSizeRatio * imageSizeRatio); 2350 var imageUrl = Images.GetImage(new ImageProcessorSettings {ImageUrl = url, Width = optimizedWidth}); 2351 2352 switch (itemLayout) 2353 { 2354 case "image-left": 2355 case "image-left-column": 2356 figureCssClass.Append(" pull-left noPaddingLeft"); 2357 break; 2358 case "image-right": 2359 figureCssClass.Append(" pull-right noPaddingRight"); 2360 break; 2361 case "image-right-column": 2362 figureCssClass.Append(" pull-right noPaddingRight"); 2363 break; 2364 case "image-top": 2365 figureCssClass.Append(" image-top noPadding"); 2366 if (Convert.ToInt32(width) < 12) 2367 { 2368 var offset = (12 - Convert.ToDouble(width)) / 2; 2369 figureCssClass.Append(" col-md-offset-" + Math.Floor(offset)); 2370 figureCssClass.Append(" col-md-offset-right-" + Math.Ceiling(offset)); 2371 } 2372 break; 2373 default: 2374 throw new NotSupportedException(string.Format("Unsupported item layout: {0}.", itemLayout)); 2375 2376 } 2377 figureClass = figureClass.Contains("none") ? figureClass.Replace("none", "") : " " + figureClass; 2378 2379 @RenderImage(new ImageSettings { WrapperCssClass = string.Concat(figureClass, figureCssClass), IncludeWrapper = true, Source = imageUrl, AltText = imageAlt }) 2380 } 2381 } 2382 @{ 2383 2384 @helper RenderStandardParagraphHeading() 2385 { 2386 @RenderStandardParagraphHeading(GetBoolean("Item.ShowTitle"), GetString("Item.TitleOrder"), GetString("Item.Title"), GetString("Item.HeadingType"), GetString("Item.TitleAlignment")) 2387 } 2388 2389 @helper RenderStandardParagraphHeading(bool showTitle, string titlePosition, string title, string headingTypeItem, string subtitle = "") 2390 { 2391 if (showTitle && titlePosition == "title-first") 2392 { 2393 @RenderStandardParagraphHeadingHtml(title, headingTypeItem, subtitle) 2394 } 2395 } 2396 2397 @helper RenderStandardParagraphHeadingHtml(string title, string headingTypeItem, string subtitle = "") 2398 { 2399 if (title.IsNotNullOrEmpty()) 2400 { 2401 var headingType = headingTypeItem.IsNullOrEmpty() || PageView.Current().Layout.File.Name.ToLower().Contains("standarddetail") ? "h1" : headingTypeItem; 2402 <header class="paragraphHeader"> 2403 @string.Format("<{0}>{1}</{0}>", headingType, title) 2404 @if (subtitle.IsNotNullOrEmpty()) 2405 { 2406 <span class="subtitle">@subtitle</span> 2407 } 2408 </header> 2409 } 2410 } 2411 2412 @helper RenderStandardParagraphText() 2413 { 2414 @RenderStandardParagraphText( 2415 GetBoolean("Item.ShowTitle"), 2416 GetString("Item.TitleOrder"), 2417 GetString("Item.Title"), 2418 GetString("Item.Order"), 2419 GetString("Item.Text"), 2420 GetString("Item.Image"), 2421 GetString("Item.Link"), 2422 GetString("Item.ImageTitle"), 2423 GetString("Item.ImageWidth"), 2424 GetString("ParagraphColumnSmall"), 2425 GetString("ParagraphColumnLarge"), 2426 GetString("Item.ImageStyle"), 2427 GetString("Item.HeadingType"), 2428 string.Empty, 2429 true) 2430 } 2431 2432 @helper RenderStandardParagraphText(bool showTitle, string titlePosition, string title, string itemLayout, string itemText, string imagePath, string link, string imageAlt, string imageWidth, string widthMobile, string itemWidth, string imageCssClass, string headingType, string subtitle = "", bool isParagraphItem = false, bool openInANewWindow = false, bool renderParagraphButton = true, string detailUrl = "") 2433 { 2434 if (itemLayout == "image-left" || itemLayout == "image-right") 2435 { 2436 @InternalRenderStandardParagraphImageTag(imagePath, link, imageAlt, imageWidth, widthMobile, itemWidth, imageCssClass, itemLayout, title, openInANewWindow) 2437 } 2438 2439 if (showTitle && titlePosition == "title-with-text") 2440 { 2441 @RenderStandardParagraphHeadingHtml(title, headingType, subtitle) 2442 } 2443 2444 @RenderStandardParagraphTextHtml(itemText, itemLayout, imageWidth, isParagraphItem, renderParagraphButton, detailUrl) 2445 } 2446 2447 @helper RenderStandardParagraphTextHtml(string itemText, string itemLayout = "", string imageWidth = "", bool isParagraphItem = false, bool renderParagraphButton = true, string detailUrl = "") 2448 { 2449 const int crop = 300; 2450 var paragraphTextClass = "paragraphText"; 2451 2452 if ((itemLayout == "image-left-column" || itemLayout == "image-right-column") && imageWidth != "12") 2453 { 2454 paragraphTextClass += " noPadding col-xs-" + (12 - int.Parse(imageWidth)); 2455 } 2456 2457 if (itemText.IsNotNullOrEmpty() || GetBoolean("Item.ShowReadMoreButton") && GetString("Item.Link").IsNotNullOrEmpty()) 2458 { 2459 2460 <div class="@paragraphTextClass"> 2461 @itemText 2462 @if (renderParagraphButton) 2463 { 2464 @RenderStandardParagraphButton(GetString("Item.LinkText"), GetString("Item.Link"), GetBoolean("Item.ShowReadMoreButton"), GetBoolean("Item.OpenInANewWindow"), detailUrl) 2465 } 2466 </div> 2467 } 2468 } 2469 2470 @helper RenderStandardParagraphModule() 2471 { @GetString("ParagraphModule") } 2472 2473 @helper RenderStandardParagraphImage() 2474 { 2475 @RenderStandardParagraphImage( 2476 GetString("Item.Order"), 2477 GetString("Item.Image"), 2478 GetString("Item.Link"), 2479 GetString("Item.ImageTitle"), 2480 GetString("Item.ImageWidth"), 2481 GetString("ParagraphColumnSmall"), 2482 GetString("ParagraphColumnLarge"), 2483 GetString("Item.ImageStyle"), 2484 GetString("Item.Title"), 2485 GetBoolean("Item.OpenInANewWindow"), 2486 GetString("Item.Video") 2487 ) 2488 } 2489 2490 @helper RenderStandardParagraphImage(string itemLayout, string imagePath, string link, string title, string imageWidth, string widthMobile, string itemWidth, string imageCssClass, string itemTitle, bool openInANewWindow, string videoPath) 2491 { 2492 if (videoPath.IsNotNullOrEmpty()) 2493 { 2494 var videoId = videoPath.Substring(videoPath.LastIndexOf('/') + 1); 2495 imagePath = imagePath.IsNotNullOrEmpty() ? imagePath : string.Concat("https://img.youtube.com/vi/",videoId,"/0.jpg"); 2496 imageCssClass += "fancybox "; 2497 @InternalRenderStandardParagraphImageTag(imagePath, videoPath, title, imageWidth, widthMobile, itemWidth, imageCssClass, itemLayout, itemTitle, openInANewWindow) 2498 } 2499 else if (itemLayout == "image-left-column" || itemLayout == "image-right-column" || itemLayout == "image-top" || itemLayout.IsNullOrEmpty()) 2500 { 2501 @InternalRenderStandardParagraphImageTag(imagePath, link, title, imageWidth, widthMobile, itemWidth, imageCssClass, itemLayout, itemTitle, openInANewWindow) 2502 } 2503 } 2504 2505 @helper RenderStandardParagraphButton() 2506 { @RenderStandardParagraphButton(GetString("Item.LinkText"), GetString("Item.Link"), GetBoolean("Item.ShowReadMoreButton"), GetBoolean("Item.OpenInANewWindow")) } 2507 2508 @helper RenderStandardParagraphButton(string label, string link, bool showReadMoreButton, bool openInANewWindow, string detailUrl = "") 2509 { 2510 var href = link.IsNotNullOrEmpty() ? link : detailUrl; 2511 2512 label = label.IsNotNullOrEmpty() ? label : Translate("Read more"); 2513 2514 if (showReadMoreButton && href.IsNotNullOrEmpty()) 2515 { 2516 <p class="paragraphButton"> 2517 @RenderBootstrapButton(new BootstrapButtonSettings {Label = label, Href = href, Target = openInANewWindow ? "_blank" : string.Empty}) 2518 </p> 2519 } 2520 } 2521 } 2522 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 2523 @using Dynamicweb.Rendering 2524 @using System.Linq 2525 2526 @functions 2527 { 2528 public bool IsB2B() 2529 { 2530 var customerType = GetCustomerType(Pageview.User); 2531 return (customerType != null && (customerType == "B2B" || customerType == "B2BLegEligible" || customerType == "GLMP")); 2532 } 2533 2534 public string GetCustomerType(User user) 2535 { 2536 return (user != null) ? user.CustomFieldValues.First(fv => fv.CustomField.SystemName == "AccessUser_CustomerType").Value.ToString() : ""; 2537 } 2538 2539 public int GetParagraphIdFromCc() 2540 { 2541 var sendOrderPageId = GetPageIdByNavigationTag("SendOrder"); 2542 var paragraphCollection = Dynamicweb.Services.Paragraphs.GetParagraphsByPageId(sendOrderPageId); 2543 var paragraphId = paragraphCollection != null ? paragraphCollection.Where(p => p.ModuleSystemName == "eCom_CustomerCenter" && p.ShowParagraph).Select(p => p.ID).FirstOrDefault() : 0; 2544 2545 return paragraphId; 2546 } 2547 } 2548 2549 @helper RenderIFrameContent() 2550 { 2551 @GetString("Item.IFrame") 2552 } 2553 @{ 2554 var backgroundColor =""; 2555 var fullWidthClass = ""; 2556 var titleTextColor = ""; 2557 var articleClasses = string.Empty; 2558 var cssClasses = new List<string>(); 2559 2560 if (GetString("Item.BackgroundColor.Value").IsNotNullOrEmpty() && !GetString("Item.BackgroundColor.Value").ToLower().Equals("#ffffff")) 2561 { 2562 backgroundColor = GetString("Item.BackgroundColor.Value"); 2563 fullWidthClass = "fullWidthClass"; 2564 } 2565 if (GetBoolean("Item.AddExtraTopBottomPadding")) 2566 { 2567 cssClasses.Add("addExtraTopBottomPadding"); 2568 } 2569 if (GetString("Item.TitleTextColor.Value").IsNotNullOrEmpty()) 2570 { 2571 titleTextColor = GetString("Item.TitleTextColor.Value"); 2572 } 2573 2574 if (GetBoolean("Item.CenterTitle")) 2575 { 2576 cssClasses.Add("centerTitle"); 2577 } 2578 2579 if (GetBoolean("Item.HideParagraph")) 2580 { 2581 cssClasses.Add("hiddenParagraph"); 2582 } 2583 2584 if (GetBoolean("Item.ToggleContentControl")) 2585 { 2586 cssClasses.Add("toggleContentControl"); 2587 } 2588 2589 if (GetBoolean("Item.CenterButton")) 2590 { 2591 cssClasses.Add("centerButton"); 2592 } 2593 2594 if (GetBoolean("Item.LoginImage")) 2595 { 2596 cssClasses.Add("loginImage"); 2597 } 2598 2599 articleClasses = cssClasses.Any() ? string.Join(" ", cssClasses) : articleClasses; 2600 } 2601 2602 <article class="container-fluid @fullWidthClass @articleClasses" data-bgcolor="@backgroundColor" data-titleTextColor="@titleTextColor"> 2603 @RenderStandardParagraphHeading()@RenderStandardParagraphImage()@RenderStandardParagraphText()@RenderIFrameContent()@RenderStandardParagraphModule() 2604 </article>