/wheels/controller/layouts.cfm

http://raihan.googlecode.com/ · ColdFusion · 135 lines · 120 code · 4 blank · 11 comment · 20 complexity · fb523ac3c6dec592365318cec445ce28 MD5 · raw file

  1. <cffunction name="usesLayout" access="public" returntype="void" output="false" hint="Used within a controller's `init()` method to specify controller- or action-specific layouts."
  2. examples=
  3. '
  4. <!---
  5. Example 1: We want this layout to be used as the default throughout the entire
  6. controller, except for the myajax action
  7. --->
  8. <cffunction name="init">
  9. <cfset usesLayout(template="myLayout", except="myajax")>
  10. </cffunction>
  11. <!---
  12. Example 2: Use a custom layout for these actions but use the default layout.cfm
  13. for the rest
  14. --->
  15. <cffunction name="init">
  16. <cfset usesLayout(template="myLayout", only="termsOfService,shippingPolicy")>
  17. </cffunction>
  18. <!--- Example 3: Define a custom method to decide which layout to display --->
  19. <cffunction name="init">
  20. <cfset usesLayout("setLayout")>
  21. </cffunction>
  22. <cffunction name="setLayout">
  23. <!--- Use holiday theme for the month of December --->
  24. <cfif Month(Now()) eq 12>
  25. <cfreturn "holiday">
  26. <!--- Otherwise, use default layout by returning `true` --->
  27. <cfelse>
  28. <cfreturn true>
  29. </cfif>
  30. </cffunction>
  31. '
  32. categories="controller-initialization,rendering" chapters="rendering-layout" functions="renderPage">
  33. <cfargument name="template" required="true" type="string" hint="Name of the layout template or method name you want to use">
  34. <cfargument name="ajax" required="false" type="string" default="" hint="Name of the layout template you want to use for AJAX requests">
  35. <cfargument name="except" type="string" required="false" hint="List of actions that SHOULD NOT get the layout">
  36. <cfargument name="only" type="string" required="false" hint="List of action that SHOULD ONLY get the layout">
  37. <cfargument name="useDefault" type="boolean" required="false" default="true" hint="When specifying conditions or a method, pass `true` to use the default `layout.cfm` if none of the conditions are met">
  38. <cfscript>
  39. // when the layout is a method, the method itself should handle all the logic
  40. if ((StructKeyExists(this, arguments.template) && IsCustomFunction(this[arguments.template])) || IsCustomFunction(arguments.template))
  41. {
  42. StructDelete(arguments, "except", false);
  43. StructDelete(arguments, "only", false);
  44. }
  45. if (StructKeyExists(arguments, "except"))
  46. arguments.except = $listClean(arguments.except);
  47. if (StructKeyExists(arguments, "only"))
  48. arguments.only = $listClean(arguments.only);
  49. variables.$class.layout = arguments;
  50. </cfscript>
  51. </cffunction>
  52. <cffunction name="$useLayout" access="public" returntype="any" output="false">
  53. <cfargument name="$action" type="string" required="true">
  54. <cfscript>
  55. var loc = {};
  56. loc.returnValue = true;
  57. loc.layoutType = "template";
  58. if (isAjax() && StructKeyExists(variables.$class.layout, "ajax") && Len(variables.$class.layout.ajax))
  59. loc.layoutType = "ajax";
  60. if (!StructIsEmpty(variables.$class.layout))
  61. {
  62. loc.returnValue = variables.$class.layout.useDefault;
  63. if ((StructKeyExists(this, variables.$class.layout[loc.layoutType]) && IsCustomFunction(this[variables.$class.layout[loc.layoutType]])) || IsCustomFunction(variables.$class.layout[loc.layoutType]))
  64. {
  65. // if the developer doesn't return anything from the method or if they return a blank string it should use the default layout still
  66. loc.invokeArgs = {};
  67. loc.invokeArgs.action = arguments.$action;
  68. loc.temp = $invoke(method=variables.$class.layout[loc.layoutType], invokeArgs=loc.invokeArgs);
  69. if (StructKeyExists(loc, "temp"))
  70. loc.returnValue = loc.temp;
  71. }
  72. else if ((!StructKeyExists(variables.$class.layout, "except") || !ListFindNoCase(variables.$class.layout.except, arguments.$action)) && (!StructKeyExists(variables.$class.layout, "only") || ListFindNoCase(variables.$class.layout.only, arguments.$action)))
  73. {
  74. loc.returnValue = variables.$class.layout[loc.layoutType];
  75. }
  76. }
  77. return loc.returnValue;
  78. </cfscript>
  79. </cffunction>
  80. <cffunction name="$renderLayout" returntype="string" access="public" output="false">
  81. <cfargument name="$content" type="string" required="true">
  82. <cfargument name="$layout" type="any" required="true">
  83. <cfscript>
  84. var loc = {};
  85. if ((IsBoolean(arguments.$layout) && arguments.$layout) || (!IsBoolean(arguments.$layout) && Len(arguments.$layout)))
  86. {
  87. // store the content in a variable in the request scope so it can be accessed
  88. // by the includeContent function that the developer uses in layout files
  89. // this is done so we avoid passing data to/from it since it would complicate things for the developer
  90. contentFor(body=arguments.$content, overwrite=true);
  91. loc.include = application.wheels.viewPath;
  92. if (IsBoolean(arguments.$layout))
  93. {
  94. loc.layoutFileExists = false;
  95. if (!ListFindNoCase(application.wheels.existingLayoutFiles, variables.params.controller) && !ListFindNoCase(application.wheels.nonExistingLayoutFiles, variables.params.controller))
  96. {
  97. if (FileExists(ExpandPath("#application.wheels.viewPath#/#LCase(variables.params.controller)#/layout.cfm")))
  98. loc.layoutFileExists = true;
  99. if (application.wheels.cacheFileChecking)
  100. {
  101. if (loc.layoutFileExists)
  102. application.wheels.existingLayoutFiles = ListAppend(application.wheels.existingLayoutFiles, variables.params.controller);
  103. else
  104. application.wheels.nonExistingLayoutFiles = ListAppend(application.wheels.nonExistingLayoutFiles, variables.params.controller);
  105. }
  106. }
  107. if (ListFindNoCase(application.wheels.existingLayoutFiles, variables.params.controller) || loc.layoutFileExists)
  108. {
  109. loc.include = loc.include & "/" & variables.params.controller & "/" & "layout.cfm";
  110. }
  111. else
  112. {
  113. loc.include = loc.include & "/" & "layout.cfm";
  114. }
  115. loc.returnValue = $includeAndReturnOutput($template=loc.include);
  116. }
  117. else
  118. {
  119. arguments.$name = arguments.$layout;
  120. arguments.$template = $generateIncludeTemplatePath(argumentCollection=arguments);
  121. loc.returnValue = $includeFile(argumentCollection=arguments);
  122. }
  123. }
  124. else
  125. {
  126. loc.returnValue = arguments.$content;
  127. }
  128. return loc.returnValue;
  129. </cfscript>
  130. </cffunction>