├── .editorconfig ├── .gitignore ├── Cofoundry.Samples.SimpleSite.sln ├── InitData ├── Images │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ └── 5.jpg └── Init.sql ├── LICENSE ├── README.md ├── readme ├── AdminPages.png └── WebSolution.png └── src └── Cofoundry.Samples.SimpleSite ├── Cofoundry.Samples.SimpleSite.csproj ├── Cofoundry ├── CustomEntities │ ├── Authors │ │ ├── AuthorCustomEntityDefinition.cs │ │ └── AuthorDataModel.cs │ ├── BlogPosts │ │ ├── BlogPostCustomEntityDefinition.cs │ │ ├── BlogPostDataModel.cs │ │ ├── BlogPostDisplayModel.cs │ │ └── BlogPostDisplayModelMapper.cs │ └── Categories │ │ ├── CategoryCustomEntityDefinition.cs │ │ └── CategoryDataModel.cs ├── PageBlockTypes │ ├── ContentSection │ │ ├── ContentSection.cshtml │ │ ├── ContentSectionDataModel.cs │ │ ├── ContentSectionDisplayModel.cs │ │ └── ContentSectionDisplayModelMapper.cs │ └── ContentSplitSection │ │ ├── ContentSplitSection.cshtml │ │ ├── ContentSplitSectionDataModel.cs │ │ ├── ContentSplitSectionDisplayModel.cs │ │ ├── ContentSplitSectionDisplayModelMapper.cs │ │ └── Templates │ │ └── ContentSplitSectionReverse.cshtml ├── PageTemplates │ ├── _BlogPostDetails.cshtml │ ├── _BlogPostList.cshtml │ ├── _Contact.cshtml │ ├── _General.cshtml │ ├── _Home.cshtml │ └── _ViewStart.cshtml └── _ViewImports.cshtml ├── Models ├── Authors │ └── AuthorDetails.cs ├── BlogPost │ ├── BlogPostSummary.cs │ └── SearchBlogPostsQuery.cs ├── Categories │ └── CategorySummary.cs ├── Contact │ └── ContactRequest.cs ├── EmailTemplates │ └── ContactRequestMailTemplate.cs └── Settings │ └── SimpleSiteSettings.cs ├── Program.cs ├── Properties └── launchSettings.json ├── Usings.cs ├── ViewComponents ├── BlogPostListViewComponent.cs ├── ContactRequestFormViewComponent.cs ├── HomepageBlogPostsViewComponent.cs └── SidebarCategoriesViewComponent.cs ├── Views ├── EmailTemplates │ ├── ContactRequest_html.cshtml │ └── ContactRequest_text.cshtml ├── Shared │ ├── Components │ │ ├── BlogPostList │ │ │ └── Default.cshtml │ │ ├── ContactRequestForm │ │ │ ├── ContactSuccess.cshtml │ │ │ └── Default.cshtml │ │ ├── HomepageBlogPosts │ │ │ └── Default.cshtml │ │ └── SidebarCategories │ │ │ └── Default.cshtml │ ├── Error.cshtml │ ├── NotFound.cshtml │ └── _Layout.cshtml ├── _ViewImports.cshtml └── _ViewStart.cshtml ├── appsettings.Development.json ├── appsettings.json └── wwwroot ├── css ├── bootstrap.min.css └── style.css ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff └── glyphicons-halflings-regular.woff2 ├── images └── hero-banner-bg.jpg └── js └── bootstrap.min.js /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | charset = utf-8 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | 7 | [*.cs] 8 | indent_size = 4 9 | dotnet_sort_system_directives_first = true 10 | 11 | # Don't use this. qualifier 12 | dotnet_style_qualification_for_field = false:suggestion 13 | dotnet_style_qualification_for_property = false:suggestion 14 | 15 | # use int x = .. over Int32 16 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 17 | 18 | # use int.MaxValue over Int32.MaxValue 19 | dotnet_style_predefined_type_for_member_access = true:suggestion 20 | 21 | # Require var all the time. 22 | csharp_style_var_for_built_in_types = true:suggestion 23 | csharp_style_var_when_type_is_apparent = true:suggestion 24 | csharp_style_var_elsewhere = true:suggestion 25 | 26 | # Disallow throw expressions. 27 | csharp_style_throw_expression = false:suggestion 28 | 29 | # Newline settings 30 | csharp_new_line_before_open_brace = all 31 | csharp_new_line_before_else = true 32 | csharp_new_line_before_catch = true 33 | csharp_new_line_before_finally = true 34 | csharp_new_line_before_members_in_object_initializers = true 35 | csharp_new_line_before_members_in_anonymous_types = true 36 | 37 | # Namespace settings 38 | csharp_style_namespace_declarations = file_scoped 39 | 40 | # Brace settings 41 | csharp_prefer_braces = true # Prefer curly braces even for one line of code 42 | 43 | # name all constant fields using PascalCase 44 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion 45 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields 46 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style 47 | dotnet_naming_symbols.constant_fields.applicable_kinds = field 48 | dotnet_naming_symbols.constant_fields.required_modifiers = const 49 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case 50 | 51 | # internal and private fields should be _camelCase 52 | dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion 53 | dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields 54 | dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style 55 | dotnet_naming_symbols.private_internal_fields.applicable_kinds = field 56 | dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal 57 | dotnet_naming_style.camel_case_underscore_style.required_prefix = _ 58 | dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case 59 | 60 | [*.{xml,config,*proj,nuspec,props,resx,targets,yml,tasks}] 61 | indent_size = 2 62 | 63 | # Xml config files 64 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] 65 | indent_size = 2 66 | 67 | [*.json] 68 | indent_size = 2 69 | 70 | [*.{ps1,psm1}] 71 | indent_size = 4 72 | 73 | [*.sh] 74 | indent_size = 4 75 | end_of_line = lf 76 | 77 | [*.{razor,cshtml}] 78 | charset = utf-8-bom 79 | 80 | [*.{cs,vb}] 81 | 82 | # SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time 83 | dotnet_diagnostic.SYSLIB1054.severity = warning 84 | 85 | # CA1018: Mark attributes with AttributeUsageAttribute 86 | dotnet_diagnostic.CA1018.severity = warning 87 | 88 | # CA1047: Do not declare protected member in sealed type 89 | dotnet_diagnostic.CA1047.severity = warning 90 | 91 | # CA1305: Specify IFormatProvider 92 | dotnet_diagnostic.CA1305.severity = warning 93 | 94 | # CA1507: Use nameof to express symbol names 95 | dotnet_diagnostic.CA1507.severity = warning 96 | 97 | # CA1510: Use ArgumentNullException throw helper 98 | dotnet_diagnostic.CA1510.severity = warning 99 | 100 | # CA1511: Use ArgumentException throw helper 101 | dotnet_diagnostic.CA1511.severity = warning 102 | 103 | # CA1512: Use ArgumentOutOfRangeException throw helper 104 | dotnet_diagnostic.CA1512.severity = warning 105 | 106 | # CA1513: Use ObjectDisposedException throw helper 107 | dotnet_diagnostic.CA1513.severity = warning 108 | 109 | # CA1725: Parameter names should match base declaration 110 | dotnet_diagnostic.CA1725.severity = suggestion 111 | 112 | # CA1802: Use literals where appropriate 113 | dotnet_diagnostic.CA1802.severity = warning 114 | 115 | # CA1805: Do not initialize unnecessarily 116 | dotnet_diagnostic.CA1805.severity = warning 117 | 118 | # CA1810: Do not initialize unnecessarily 119 | dotnet_diagnostic.CA1810.severity = warning 120 | 121 | # CA1821: Remove empty Finalizers 122 | dotnet_diagnostic.CA1821.severity = warning 123 | 124 | # CA1822: Make member static 125 | dotnet_diagnostic.CA1822.severity = warning 126 | dotnet_code_quality.CA1822.api_surface = private, internal 127 | 128 | # CA1823: Avoid unused private fields 129 | dotnet_diagnostic.CA1823.severity = warning 130 | 131 | # CA1825: Avoid zero-length array allocations 132 | dotnet_diagnostic.CA1825.severity = warning 133 | 134 | # CA1826: Do not use Enumerable methods on indexable collections. Instead use the collection directly 135 | dotnet_diagnostic.CA1826.severity = warning 136 | 137 | # CA1827: Do not use Count() or LongCount() when Any() can be used 138 | dotnet_diagnostic.CA1827.severity = warning 139 | 140 | # CA1828: Do not use CountAsync() or LongCountAsync() when AnyAsync() can be used 141 | dotnet_diagnostic.CA1828.severity = warning 142 | 143 | # CA1829: Use Length/Count property instead of Count() when available 144 | dotnet_diagnostic.CA1829.severity = warning 145 | 146 | # CA1830: Prefer strongly-typed Append and Insert method overloads on StringBuilder 147 | dotnet_diagnostic.CA1830.severity = warning 148 | 149 | # CA1831: Use AsSpan or AsMemory instead of Range-based indexers when appropriate 150 | dotnet_diagnostic.CA1831.severity = warning 151 | 152 | # CA1832: Use AsSpan or AsMemory instead of Range-based indexers when appropriate 153 | dotnet_diagnostic.CA1832.severity = warning 154 | 155 | # CA1833: Use AsSpan or AsMemory instead of Range-based indexers when appropriate 156 | dotnet_diagnostic.CA1833.severity = warning 157 | 158 | # CA1834: Consider using 'StringBuilder.Append(char)' when applicable 159 | dotnet_diagnostic.CA1834.severity = warning 160 | 161 | # CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' 162 | dotnet_diagnostic.CA1835.severity = warning 163 | 164 | # CA1836: Prefer IsEmpty over Count 165 | dotnet_diagnostic.CA1836.severity = warning 166 | 167 | # CA1837: Use 'Environment.ProcessId' 168 | dotnet_diagnostic.CA1837.severity = warning 169 | 170 | # CA1838: Avoid 'StringBuilder' parameters for P/Invokes 171 | dotnet_diagnostic.CA1838.severity = warning 172 | 173 | # CA1839: Use 'Environment.ProcessPath' 174 | dotnet_diagnostic.CA1839.severity = warning 175 | 176 | # CA1840: Use 'Environment.CurrentManagedThreadId' 177 | dotnet_diagnostic.CA1840.severity = warning 178 | 179 | # CA1841: Prefer Dictionary.Contains methods 180 | dotnet_diagnostic.CA1841.severity = warning 181 | 182 | # CA1842: Do not use 'WhenAll' with a single task 183 | dotnet_diagnostic.CA1842.severity = warning 184 | 185 | # CA1843: Do not use 'WaitAll' with a single task 186 | dotnet_diagnostic.CA1843.severity = warning 187 | 188 | # CA1844: Provide memory-based overrides of async methods when subclassing 'Stream' 189 | dotnet_diagnostic.CA1844.severity = warning 190 | 191 | # CA1845: Use span-based 'string.Concat' 192 | dotnet_diagnostic.CA1845.severity = warning 193 | 194 | # CA1846: Prefer AsSpan over Substring 195 | dotnet_diagnostic.CA1846.severity = warning 196 | 197 | # CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters 198 | dotnet_diagnostic.CA1847.severity = warning 199 | 200 | # CA1854: Prefer the IDictionary.TryGetValue(TKey, out TValue) method 201 | dotnet_diagnostic.CA1854.severity = warning 202 | 203 | # CA1855: Prefer 'Clear' over 'Fill' 204 | dotnet_diagnostic.CA1855.severity = warning 205 | 206 | # CA1856: Incorrect usage of ConstantExpected attribute 207 | dotnet_diagnostic.CA1856.severity = error 208 | 209 | # CA1857: A constant is expected for the parameter 210 | dotnet_diagnostic.CA1857.severity = warning 211 | 212 | # CA1858: Use 'StartsWith' instead of 'IndexOf' 213 | dotnet_diagnostic.CA1858.severity = warning 214 | 215 | # CA2008: Do not create tasks without passing a TaskScheduler 216 | dotnet_diagnostic.CA2008.severity = warning 217 | 218 | # CA2009: Do not call ToImmutableCollection on an ImmutableCollection value 219 | dotnet_diagnostic.CA2009.severity = warning 220 | 221 | # CA2011: Avoid infinite recursion 222 | dotnet_diagnostic.CA2011.severity = warning 223 | 224 | # CA2012: Use ValueTask correctly 225 | dotnet_diagnostic.CA2012.severity = warning 226 | 227 | # CA2013: Do not use ReferenceEquals with value types 228 | dotnet_diagnostic.CA2013.severity = warning 229 | 230 | # CA2014: Do not use stackalloc in loops. 231 | dotnet_diagnostic.CA2014.severity = warning 232 | 233 | # CA2016: Forward the 'CancellationToken' parameter to methods that take one 234 | dotnet_diagnostic.CA2016.severity = warning 235 | 236 | # CA2200: Rethrow to preserve stack details 237 | dotnet_diagnostic.CA2200.severity = warning 238 | 239 | # CA2208: Instantiate argument exceptions correctly 240 | dotnet_diagnostic.CA2208.severity = warning 241 | 242 | # CA2245: Do not assign a property to itself 243 | dotnet_diagnostic.CA2245.severity = warning 244 | 245 | # CA2246: Assigning symbol and its member in the same statement 246 | dotnet_diagnostic.CA2246.severity = warning 247 | 248 | # CA2249: Use string.Contains instead of string.IndexOf to improve readability. 249 | dotnet_diagnostic.CA2249.severity = warning 250 | 251 | # IDE0005: Remove unnecessary usings 252 | dotnet_diagnostic.IDE0005.severity = warning 253 | 254 | # IDE0011: Curly braces to surround blocks of code 255 | dotnet_diagnostic.IDE0011.severity = warning 256 | 257 | # IDE0020: Use pattern matching to avoid is check followed by a cast (with variable) 258 | dotnet_diagnostic.IDE0020.severity = warning 259 | 260 | # IDE0029: Use coalesce expression (non-nullable types) 261 | dotnet_diagnostic.IDE0029.severity = warning 262 | 263 | # IDE0030: Use coalesce expression (nullable types) 264 | dotnet_diagnostic.IDE0030.severity = warning 265 | 266 | # IDE0031: Use null propagation 267 | dotnet_diagnostic.IDE0031.severity = warning 268 | 269 | # IDE0035: Remove unreachable code 270 | dotnet_diagnostic.IDE0035.severity = warning 271 | 272 | # IDE0036: Order modifiers 273 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion 274 | dotnet_diagnostic.IDE0036.severity = warning 275 | 276 | # IDE0038: Use pattern matching to avoid is check followed by a cast (without variable) 277 | dotnet_diagnostic.IDE0038.severity = warning 278 | 279 | # IDE0043: Format string contains invalid placeholder 280 | dotnet_diagnostic.IDE0043.severity = warning 281 | 282 | # IDE0044: Make field readonly 283 | dotnet_diagnostic.IDE0044.severity = warning 284 | 285 | # IDE0051: Remove unused private members 286 | dotnet_diagnostic.IDE0051.severity = warning 287 | 288 | # IDE0055: All formatting rules 289 | dotnet_diagnostic.IDE0055.severity = suggestion 290 | 291 | # IDE0059: Unnecessary assignment to a value 292 | dotnet_diagnostic.IDE0059.severity = warning 293 | 294 | # IDE0060: Remove unused parameter 295 | dotnet_code_quality_unused_parameters = non_public 296 | dotnet_diagnostic.IDE0060.severity = warning 297 | 298 | # IDE0062: Make local function static 299 | dotnet_diagnostic.IDE0062.severity = warning 300 | 301 | # IDE0161: Convert to file-scoped namespace 302 | dotnet_diagnostic.IDE0161.severity = warning 303 | 304 | # IDE0200: Lambda expression can be removed 305 | dotnet_diagnostic.IDE0200.severity = warning 306 | 307 | # IDE2000: Disallow multiple blank lines 308 | dotnet_style_allow_multiple_blank_lines_experimental = false 309 | dotnet_diagnostic.IDE2000.severity = warning 310 | 311 | # IDE0063: Use simple 'using' statement 312 | dotnet_diagnostic.IDE0063.severity = silent 313 | 314 | # IDE0270: Use coalesce expression 315 | dotnet_diagnostic.IDE0270.severity = silent 316 | 317 | # IDE0290: Use primary constructor 318 | dotnet_diagnostic.IDE0290.severity = silent -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | [Bb]in/ 15 | [Oo]bj/ 16 | 17 | *_i.c 18 | *_p.c 19 | *.ilk 20 | *.meta 21 | *.obj 22 | *.pch 23 | *.pdb 24 | *.pgc 25 | *.pgd 26 | *.rsp 27 | *.sbr 28 | *.tlb 29 | *.tli 30 | *.tlh 31 | *.tmp 32 | *.tmp_proj 33 | *.log 34 | *.vspscc 35 | *.vssscc 36 | .builds 37 | *.pidb 38 | *.log 39 | *.scc 40 | 41 | # ReSharper is a .NET coding add-in 42 | _ReSharper*/ 43 | *.[Rr]e[Ss]harper 44 | 45 | # Click-Once directory 46 | publish/ 47 | 48 | # Publish Web Output 49 | *.Publish.xml 50 | *.pubxml 51 | 52 | # NuGet Packages Directory 53 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 54 | packages/ 55 | 56 | # Others 57 | [Ss]tyle[Cc]op.* 58 | ~$* 59 | *~ 60 | *.dbmdl 61 | *.[Pp]ublish.xml 62 | *.pfx 63 | *.publishsettings 64 | 65 | # SQL Server files 66 | App_Data/*.mdf 67 | App_Data/*.ldf 68 | 69 | # ========================= 70 | # Windows detritus 71 | # ========================= 72 | 73 | # Windows image file caches 74 | Thumbs.db 75 | ehthumbs.db 76 | 77 | # Mac crap 78 | .DS_Store 79 | 80 | # Cake Build 81 | /tools 82 | /artifacts 83 | 84 | 85 | .vs 86 | node_modules/ 87 | appsettings.local.json 88 | .vscode 89 | 90 | **/App_Data/Files/ 91 | **/App_Data/Emails/ -------------------------------------------------------------------------------- /Cofoundry.Samples.SimpleSite.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.13 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cofoundry.Samples.SimpleSite", "src\Cofoundry.Samples.SimpleSite\Cofoundry.Samples.SimpleSite.csproj", "{3A77B4AF-4EB7-43CC-A1CD-4E693C72DCBD}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3A77B4AF-4EB7-43CC-A1CD-4E693C72DCBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3A77B4AF-4EB7-43CC-A1CD-4E693C72DCBD}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3A77B4AF-4EB7-43CC-A1CD-4E693C72DCBD}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3A77B4AF-4EB7-43CC-A1CD-4E693C72DCBD}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /InitData/Images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/InitData/Images/1.jpg -------------------------------------------------------------------------------- /InitData/Images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/InitData/Images/2.jpg -------------------------------------------------------------------------------- /InitData/Images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/InitData/Images/3.jpg -------------------------------------------------------------------------------- /InitData/Images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/InitData/Images/4.jpg -------------------------------------------------------------------------------- /InitData/Images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/InitData/Images/5.jpg -------------------------------------------------------------------------------- /InitData/Init.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Use this script to add some initial data to the simple site. The script uses Identity Insert, so it needs to 3 | be run before any other data is added. 4 | 5 | The data references images which can be found in "\InitData\Images" and needs to be copied to "\src\Cofoundry.Samples.SimpleSite\App_Data\Files\Images" 6 | */ 7 | 8 | /* ENTITY DEFINITIONS */ 9 | 10 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFCEV')) 11 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFCEV', N'Custom Entity Version') 12 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFCEB')) 13 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFCEB', N'Custom Entity Version Page Block') 14 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFDOC')) 15 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFDOC', N'Document') 16 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFIMG')) 17 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFIMG', N'Image') 18 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFPGE')) 19 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFPGE', N'Page') 20 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFPTL')) 21 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFPTL', N'Page Template') 22 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFPGB')) 23 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFPGB', N'Page Version Block') 24 | 25 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFRWR')) 26 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFRWR', N'Rewrite Rule') 27 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFROL')) 28 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFCEV', N'Role') 29 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFSET')) 30 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFSET', N'Settings') 31 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFUSR')) 32 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFUSR', N'User (Cofoundry)') 33 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFCUR')) 34 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFCUR', N'User (Current)') 35 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFUSN')) 36 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFUSN', N'User (Non Cofoundry)') 37 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'COFDIR')) 38 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'COFDIR', N'Web Directory') 39 | 40 | /* CUSTOM ENTITY DEFINITIONS */ 41 | 42 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'SIMBLP')) 43 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'SIMBLP', N'Blog Post') 44 | if (not exists (select * from Cofoundry.[CustomEntityDefinition] where [CustomEntityDefinitionCode] = 'SIMBLP')) 45 | INSERT [Cofoundry].[CustomEntityDefinition] ([CustomEntityDefinitionCode], [ForceUrlSlugUniqueness], [IsOrderable], [HasLocale]) VALUES (N'SIMBLP', 0, 0, 0) 46 | 47 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'SIMCAT')) 48 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'SIMCAT', N'Category') 49 | if (not exists (select * from Cofoundry.[CustomEntityDefinition] where [CustomEntityDefinitionCode] = 'SIMCAT')) 50 | INSERT [Cofoundry].[CustomEntityDefinition] ([CustomEntityDefinitionCode], [ForceUrlSlugUniqueness], [IsOrderable], [HasLocale]) VALUES (N'SIMCAT', 1, 0, 0) 51 | 52 | if (not exists (select * from Cofoundry.EntityDefinition where EntityDefinitionCode = 'SIMAUT')) 53 | INSERT [Cofoundry].[EntityDefinition] ([EntityDefinitionCode], [Name]) VALUES (N'SIMAUT', N'Author') 54 | if (not exists (select * from Cofoundry.[CustomEntityDefinition] where [CustomEntityDefinitionCode] = 'SIMAUT')) 55 | INSERT [Cofoundry].[CustomEntityDefinition] ([CustomEntityDefinitionCode], [ForceUrlSlugUniqueness], [IsOrderable], [HasLocale]) VALUES (N'SIMAUT', 1, 0, 0) 56 | 57 | go 58 | 59 | 60 | /* IMAGES */ 61 | 62 | SET IDENTITY_INSERT [Cofoundry].[ImageAsset] ON 63 | 64 | GO 65 | INSERT [Cofoundry].[ImageAsset] ([ImageAssetId], [FileName], [Title], [WidthInPixels], [HeightInPixels], [FileExtension], [FileSizeInBytes], [CreateDate], [CreatorId], [UpdateDate], [ImageCropAnchorLocationId], [UpdaterId], [FileUpdateDate], [FileNameOnDisk], [VerificationToken]) VALUES (1, N'blog-image', N'Blog image', 1663, 1124, N'jpg', 387442, CAST(N'2018-10-18 09:18:28' AS DateTime2), 1, CAST(N'2018-10-18 09:18:28' AS DateTime2), NULL, 1, CAST(N'2018-10-18 09:18:28' AS DateTime2), '1', '82AE1B') 66 | INSERT [Cofoundry].[ImageAsset] ([ImageAssetId], [FileName], [Title], [WidthInPixels], [HeightInPixels], [FileExtension], [FileSizeInBytes], [CreateDate], [CreatorId], [UpdateDate], [ImageCropAnchorLocationId], [UpdaterId], [FileUpdateDate], [FileNameOnDisk], [VerificationToken]) VALUES (2, N'smoky-mountains-sunrise', N'Smoky Mountains Sunrise', 2000, 1500, N'jpg', 291964, CAST(N'2018-10-18 09:23:22' AS DateTime2), 1, CAST(N'2018-10-18 09:23:22' AS DateTime2), NULL, 1, CAST(N'2018-10-18 09:23:22' AS DateTime2), '2', '245F22') 67 | INSERT [Cofoundry].[ImageAsset] ([ImageAssetId], [FileName], [Title], [WidthInPixels], [HeightInPixels], [FileExtension], [FileSizeInBytes], [CreateDate], [CreatorId], [UpdateDate], [ImageCropAnchorLocationId], [UpdaterId], [FileUpdateDate], [FileNameOnDisk], [VerificationToken]) VALUES (3, N'snow-landscape', N'Snow landscape', 1500, 2000, N'jpg', 752661, CAST(N'2018-10-18 09:23:42' AS DateTime2), 1, CAST(N'2018-10-18 09:23:42' AS DateTime2), NULL, 1, CAST(N'2018-10-18 09:23:42' AS DateTime2), '3', '0FD9BB') 68 | INSERT [Cofoundry].[ImageAsset] ([ImageAssetId], [FileName], [Title], [WidthInPixels], [HeightInPixels], [FileExtension], [FileSizeInBytes], [CreateDate], [CreatorId], [UpdateDate], [ImageCropAnchorLocationId], [UpdaterId], [FileUpdateDate], [FileNameOnDisk], [VerificationToken]) VALUES (4, N'icy-mountain', N'Icy Mountain', 2189, 2918, N'jpg', 746557, CAST(N'2018-10-18 09:26:45' AS DateTime2), 1, CAST(N'2018-10-18 09:26:45' AS DateTime2), NULL, 1, CAST(N'2018-10-18 09:26:45' AS DateTime2), '4', '05C4FB') 69 | INSERT [Cofoundry].[ImageAsset] ([ImageAssetId], [FileName], [Title], [WidthInPixels], [HeightInPixels], [FileExtension], [FileSizeInBytes], [CreateDate], [CreatorId], [UpdateDate], [ImageCropAnchorLocationId], [UpdaterId], [FileUpdateDate], [FileNameOnDisk], [VerificationToken]) VALUES (5, N'manny-profile', N'Manny Profile', 300, 300, N'jpg', 18985, CAST(N'2018-10-19 10:29:21' AS DateTime2), 1, CAST(N'2018-10-19 10:29:21' AS DateTime2), NULL, 1, CAST(N'2018-10-19 10:29:21' AS DateTime2), '5', '5AF06B') 70 | GO 71 | SET IDENTITY_INSERT [Cofoundry].[ImageAsset] OFF 72 | GO 73 | 74 | 75 | SET IDENTITY_INSERT [Cofoundry].[PageDirectory] ON 76 | 77 | GO 78 | 79 | /* WEB DIRECTORY */ 80 | 81 | declare @RootPageDirectoryId int 82 | select @RootPageDirectoryId = PageDirectoryId from Cofoundry.PageDirectory where UrlPath = '' 83 | 84 | INSERT [Cofoundry].[PageDirectory] ([PageDirectoryId], [ParentPageDirectoryId], [Name], [UrlPath], [CreateDate], [CreatorId], AccessRuleViolationActionId) VALUES (2, @RootPageDirectoryId, N'Blog', N'blog', CAST(N'2018-10-11 16:37:14' AS DateTime2), 1, 0) 85 | GO 86 | SET IDENTITY_INSERT [Cofoundry].[PageDirectory] OFF 87 | GO 88 | 89 | /* PAGE */ 90 | 91 | SET IDENTITY_INSERT [Cofoundry].[Page] ON 92 | 93 | GO 94 | INSERT [Cofoundry].[Page] ([PageId], [PageDirectoryId], [LocaleId], [UrlPath], [PageTypeId], [CreateDate], [CreatorId], [CustomEntityDefinitionCode], PublishStatusCode, PublishDate, AccessRuleViolationActionId) VALUES (1, 2, NULL, N'', 1, CAST(N'2018-10-11 16:35:25' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-11 16:35:25' AS DateTime2), 0) 95 | INSERT [Cofoundry].[Page] ([PageId], [PageDirectoryId], [LocaleId], [UrlPath], [PageTypeId], [CreateDate], [CreatorId], [CustomEntityDefinitionCode], PublishStatusCode, PublishDate, AccessRuleViolationActionId) VALUES (2, 1, NULL, N'', 1, CAST(N'2018-10-11 16:39:21' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-11 16:39:21' AS DateTime2), 0) 96 | INSERT [Cofoundry].[Page] ([PageId], [PageDirectoryId], [LocaleId], [UrlPath], [PageTypeId], [CreateDate], [CreatorId], [CustomEntityDefinitionCode], PublishStatusCode, PublishDate, AccessRuleViolationActionId) VALUES (3, 2, NULL, N'{Id}/{UrlSlug}', 2, CAST(N'2018-10-11 16:41:35' AS DateTime2), 1, N'SIMBLP', 'P', CAST(N'2018-10-11 16:41:35' AS DateTime2), 0) 97 | INSERT [Cofoundry].[Page] ([PageId], [PageDirectoryId], [LocaleId], [UrlPath], [PageTypeId], [CreateDate], [CreatorId], [CustomEntityDefinitionCode], PublishStatusCode, PublishDate, AccessRuleViolationActionId) VALUES (4, 1, NULL, N'contact', 1, CAST(N'2018-10-18 16:56:38' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-18 16:56:38' AS DateTime2), 0) 98 | INSERT [Cofoundry].[Page] ([PageId], [PageDirectoryId], [LocaleId], [UrlPath], [PageTypeId], [CreateDate], [CreatorId], [CustomEntityDefinitionCode], PublishStatusCode, PublishDate, AccessRuleViolationActionId) VALUES (5, 1, NULL, N'about', 1, CAST(N'2018-10-18 16:57:38' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-18 16:57:38' AS DateTime2), 0) 99 | GO 100 | SET IDENTITY_INSERT [Cofoundry].[Page] OFF 101 | GO 102 | 103 | /* PAGE VERSION */ 104 | 105 | SET IDENTITY_INSERT [Cofoundry].[PageVersion] ON 106 | 107 | GO 108 | declare @PageTemplateId int 109 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'BlogPostList' 110 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (1, 1, @PageTemplateId, N'Blog', N'Somethign about Blog', 4, CAST(N'2018-10-11 16:35:25' AS DateTime2), 1, 0, NULL, NULL, NULL, 1) 111 | 112 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'Home' 113 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (2, 2, @PageTemplateId, N'Home', N'Simple site homepage', 4, CAST(N'2018-10-11 16:39:21' AS DateTime2), 1, 0, NULL, NULL, NULL, 1) 114 | 115 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'BlogPostDetails' 116 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (3, 3, @PageTemplateId, N'Blog Post', N'Blog post', 4, CAST(N'2018-10-11 16:41:35' AS DateTime2), 1, 0, NULL, NULL, NULL, 1) 117 | 118 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'Contact' 119 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (4, 4, @PageTemplateId, N'Contact Us', N'Get in touch!', 4, CAST(N'2018-10-18 16:56:38' AS DateTime2), 1, 0, NULL, NULL, NULL, 1) 120 | 121 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'General' 122 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (5, 5, @PageTemplateId, N'About Example Inc.', N'Find out what we''re all about', 4, CAST(N'2018-10-18 16:57:38' AS DateTime2), 1, 0, NULL, NULL, NULL, 1) 123 | 124 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'Home' 125 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (6, 2, @PageTemplateId, N'Home', N'Simple site homepage', 4, CAST(N'2018-10-19 09:34:40' AS DateTime2), 1, 0, NULL, NULL, NULL, 2) 126 | 127 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'General' 128 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (7, 5, @PageTemplateId, N'About Example Inc.', N'Find out what we''re all about', 4, CAST(N'2018-10-19 14:58:28' AS DateTime2), 1, 0, NULL, NULL, NULL, 2) 129 | 130 | select @PageTemplateId = PageTemplateId from Cofoundry.PageTemplate where [FileName] = 'Contact' 131 | INSERT [Cofoundry].[PageVersion] ([PageVersionId], [PageId], [PageTemplateId], [Title], [MetaDescription], [WorkFlowStatusId], [CreateDate], [CreatorId], [ExcludeFromSitemap], [OpenGraphTitle], [OpenGraphDescription], [OpenGraphImageId], DisplayVersion) VALUES (8, 4, @PageTemplateId, N'Contact Us', N'Get in touch!', 4, CAST(N'2018-10-19 15:43:29' AS DateTime2), 1, 0, NULL, NULL, NULL, 2) 132 | 133 | GO 134 | SET IDENTITY_INSERT [Cofoundry].[PageVersion] OFF 135 | GO 136 | 137 | /* PAGE VERSION BLOCK */ 138 | 139 | SET IDENTITY_INSERT [Cofoundry].[PageVersionBlock] ON 140 | 141 | GO 142 | declare @PageBlockTypeId int 143 | declare @PageTemplateRegionId int 144 | 145 | select @PageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'PlainText' 146 | select @PageTemplateRegionId = PageTemplateRegionId from Cofoundry.PageTemplateRegion s inner join Cofoundry.PageTemplate t on t.PageTemplateId = s.PageTemplateId where t.[FileName] = 'Home' and s.Name = 'Introduction Title' 147 | INSERT [Cofoundry].[PageVersionBlock] ([PageVersionBlockId], [PageVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [CreateDate], [CreatorId], [UpdateDate], [PageBlockTypeTemplateId]) VALUES (1, 6, @PageTemplateRegionId, @PageBlockTypeId, N'{"plainText":"Hello, world!"}', 1, CAST(N'2018-10-19 09:41:59' AS DateTime2), 1, CAST(N'2018-10-19 09:41:59' AS DateTime2), NULL) 148 | 149 | select @PageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'RichTextWithMedia' 150 | select @PageTemplateRegionId = PageTemplateRegionId from Cofoundry.PageTemplateRegion s inner join Cofoundry.PageTemplate t on t.PageTemplateId = s.PageTemplateId where t.[FileName] = 'Home' and s.Name = 'Introduction' 151 | INSERT [Cofoundry].[PageVersionBlock] ([PageVersionBlockId], [PageVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [CreateDate], [CreatorId], [UpdateDate], [PageBlockTypeTemplateId]) VALUES (2, 6, @PageTemplateRegionId, @PageBlockTypeId, N'{"rawHtml":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, CAST(N'2018-10-19 09:43:54' AS DateTime2), 1, CAST(N'2018-10-19 09:43:54' AS DateTime2), NULL) 152 | 153 | select @PageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'ContentSection' 154 | select @PageTemplateRegionId = PageTemplateRegionId from Cofoundry.PageTemplateRegion s inner join Cofoundry.PageTemplate t on t.PageTemplateId = s.PageTemplateId where t.[FileName] = 'General' and s.Name = 'Body' 155 | INSERT [Cofoundry].[PageVersionBlock] ([PageVersionBlockId], [PageVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [CreateDate], [CreatorId], [UpdateDate], [PageBlockTypeTemplateId]) VALUES (3, 7, @PageTemplateRegionId, @PageBlockTypeId, N'{"title":null,"htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, CAST(N'2018-10-19 15:10:24' AS DateTime2), 1, CAST(N'2018-10-19 15:10:24' AS DateTime2), NULL) 156 | 157 | select @PageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'ContentSplitSection' 158 | select @PageTemplateRegionId = PageTemplateRegionId from Cofoundry.PageTemplateRegion s inner join Cofoundry.PageTemplate t on t.PageTemplateId = s.PageTemplateId where t.[FileName] = 'General' and s.Name = 'Body' 159 | INSERT [Cofoundry].[PageVersionBlock] ([PageVersionBlockId], [PageVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [CreateDate], [CreatorId], [UpdateDate], [PageBlockTypeTemplateId]) VALUES (4, 7, @PageTemplateRegionId, @PageBlockTypeId, N'{"title":"Lorem ipsum dolor sit amet","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":1}', 2, CAST(N'2018-10-19 15:11:07' AS DateTime2), 1, CAST(N'2018-10-19 15:11:07' AS DateTime2), NULL) 160 | 161 | select @PageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'ContentSection' 162 | select @PageTemplateRegionId = PageTemplateRegionId from Cofoundry.PageTemplateRegion s inner join Cofoundry.PageTemplate t on t.PageTemplateId = s.PageTemplateId where t.[FileName] = 'General' and s.Name = 'Body' 163 | INSERT [Cofoundry].[PageVersionBlock] ([PageVersionBlockId], [PageVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [CreateDate], [CreatorId], [UpdateDate], [PageBlockTypeTemplateId]) VALUES (5, 7, @PageTemplateRegionId, @PageBlockTypeId, N'{"title":"Curabitur facilisis","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

"}', 3, CAST(N'2018-10-19 15:11:26' AS DateTime2), 1, CAST(N'2018-10-19 15:11:46' AS DateTime2), NULL) 164 | 165 | select @PageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'PlainText' 166 | select @PageTemplateRegionId = PageTemplateRegionId from Cofoundry.PageTemplateRegion s inner join Cofoundry.PageTemplate t on t.PageTemplateId = s.PageTemplateId where t.[FileName] = 'Contact' and s.Name = 'Introduction' 167 | INSERT [Cofoundry].[PageVersionBlock] ([PageVersionBlockId], [PageVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [CreateDate], [CreatorId], [UpdateDate], [PageBlockTypeTemplateId]) VALUES (6, 8, @PageTemplateRegionId, @PageBlockTypeId, N'{"plainText":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus."}', 1, CAST(N'2018-10-19 15:48:37' AS DateTime2), 1, CAST(N'2018-10-19 15:48:37' AS DateTime2), NULL) 168 | GO 169 | SET IDENTITY_INSERT [Cofoundry].[PageVersionBlock] OFF 170 | GO 171 | 172 | /* CUSTOM ENTITY */ 173 | 174 | SET IDENTITY_INSERT [Cofoundry].[CustomEntity] ON 175 | 176 | GO 177 | INSERT [Cofoundry].[CustomEntity] ([CustomEntityId], [CustomEntityDefinitionCode], [LocaleId], [UrlSlug], [CreateDate], [CreatorId], [Ordering], PublishStatusCode, PublishDate) VALUES (1, N'SIMBLP', NULL, N'first-blog-post', CAST(N'2018-08-06 15:24:26' AS DateTime2), 1, NULL, 'P', CAST(N'2018-08-06 15:24:26' AS DateTime2)) 178 | INSERT [Cofoundry].[CustomEntity] ([CustomEntityId], [CustomEntityDefinitionCode], [LocaleId], [UrlSlug], [CreateDate], [CreatorId], [Ordering], PublishStatusCode, PublishDate) VALUES (2, N'SIMBLP', NULL, N'second-blog-post', CAST(N'2018-09-12 09:50:03' AS DateTime2), 1, NULL, 'P', CAST(N'2018-09-12 09:50:03' AS DateTime2)) 179 | INSERT [Cofoundry].[CustomEntity] ([CustomEntityId], [CustomEntityDefinitionCode], [LocaleId], [UrlSlug], [CreateDate], [CreatorId], [Ordering], PublishStatusCode, PublishDate) VALUES (3, N'SIMBLP', NULL, N'third-blog-post', CAST(N'2018-10-18 10:27:04' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-18 10:27:04' AS DateTime2)) 180 | INSERT [Cofoundry].[CustomEntity] ([CustomEntityId], [CustomEntityDefinitionCode], [LocaleId], [UrlSlug], [CreateDate], [CreatorId], [Ordering], PublishStatusCode, PublishDate) VALUES (4, N'SIMCAT', NULL, N'snow', CAST(N'2018-10-19 13:36:08' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-19 13:36:08' AS DateTime2)) 181 | INSERT [Cofoundry].[CustomEntity] ([CustomEntityId], [CustomEntityDefinitionCode], [LocaleId], [UrlSlug], [CreateDate], [CreatorId], [Ordering], PublishStatusCode, PublishDate) VALUES (5, N'SIMCAT', NULL, N'sun', CAST(N'2018-10-19 13:50:36' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-19 13:50:36' AS DateTime2)) 182 | INSERT [Cofoundry].[CustomEntity] ([CustomEntityId], [CustomEntityDefinitionCode], [LocaleId], [UrlSlug], [CreateDate], [CreatorId], [Ordering], PublishStatusCode, PublishDate) VALUES (6, N'SIMCAT', NULL, N'mountains', CAST(N'2018-10-19 13:51:00' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-19 13:51:00' AS DateTime2)) 183 | INSERT [Cofoundry].[CustomEntity] ([CustomEntityId], [CustomEntityDefinitionCode], [LocaleId], [UrlSlug], [CreateDate], [CreatorId], [Ordering], PublishStatusCode, PublishDate) VALUES (7, N'SIMAUT', NULL, N'manny', CAST(N'2018-10-19 13:51:00' AS DateTime2), 1, NULL, 'P', CAST(N'2018-10-19 12:47:00' AS DateTime2)) 184 | GO 185 | SET IDENTITY_INSERT [Cofoundry].[CustomEntity] OFF 186 | GO 187 | 188 | /* CUSTOM ENTITY VERSION */ 189 | 190 | SET IDENTITY_INSERT [Cofoundry].[CustomEntityVersion] ON 191 | 192 | GO 193 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (1, 1, N'First Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":3}', CAST(N'2018-08-06 15:24:26' AS DateTime2), 1, 1) 194 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (2, 2, N'Second Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":1}', CAST(N'2018-09-12 09:50:03' AS DateTime2), 1, 1) 195 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (3, 3, N'Third Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":4}', CAST(N'2018-10-18 10:27:04' AS DateTime2), 1, 1) 196 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (4, 3, N'Third Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":4}', CAST(N'2018-10-19 11:18:49' AS DateTime2), 1, 2) 197 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (5, 2, N'Second Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":1}', CAST(N'2018-09-12 13:55:04' AS DateTime2), 1, 2) 198 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (6, 1, N'First Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":3}', CAST(N'2018-08-06 16:06:59' AS DateTime2), 1, 2) 199 | 200 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (7, 4, N'News', 4, N'{"shortDescription":"Latest news and information"}', CAST(N'2018-10-19 13:36:08' AS DateTime2), 1, 1) 201 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (8, 5, N'Feature', 4, N'{"shortDescription":"A feature article on a specific topic"}', CAST(N'2018-10-19 13:50:36' AS DateTime2), 1, 1) 202 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (9, 6, N'Interviews', 4, N'{"shortDescription":"Interviews with key industry figures"}', CAST(N'2018-10-19 13:51:00' AS DateTime2), 1, 1) 203 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (13, 5, N'Sun', 4, N'{"shortDescription":"Articles about sunny landscapes"}', CAST(N'2018-10-19 14:00:37' AS DateTime2), 1, 2) 204 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (14, 6, N'Mountains', 4, N'{"shortDescription":"Articles about mountains"}', CAST(N'2018-10-19 14:00:51' AS DateTime2), 1, 2) 205 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (15, 4, N'Snow', 4, N'{"shortDescription":"Articles about snowy things"}', CAST(N'2018-10-19 14:01:05' AS DateTime2), 1, 2) 206 | 207 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (10, 1, N'First Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":3,"categoryIds":[5]}', CAST(N'2018-10-19 13:55:42' AS DateTime2), 1, 3) 208 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (11, 2, N'Second Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":1,"categoryIds":[6,4]}', CAST(N'2018-10-19 13:56:30' AS DateTime2), 1, 3) 209 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (12, 3, N'Third Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":4,"categoryIds":[4,5]}', CAST(N'2018-10-19 13:56:43' AS DateTime2), 1, 3) 210 | 211 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (16, 1, N'First Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":3,"authorId":7,"categoryIds":[4,6]}', CAST(N'2018-10-19 14:01:30' AS DateTime2), 1, 4) 212 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (17, 2, N'Second Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":1,"authorId":7,"categoryIds":[6]}', CAST(N'2018-10-19 14:01:45' AS DateTime2), 1, 4) 213 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (18, 3, N'Third Blog Post', 4, N'{"shortDescription":"Aenean aliquet, leo sit amet facilisis accumsan, elit tortor dapibus ex, sit amet pellentesque nunc nulla at nulla. Phasellus ac velit non sem placerat mattis vel sit amet magna. Nullam at ipsum aliquam, lacinia elit venenatis, mollis dui.","thumbnailImageAssetId":4,"authorId":7,"categoryIds":[5,6]}', CAST(N'2018-10-19 14:01:56' AS DateTime2), 1, 4) 214 | 215 | INSERT [Cofoundry].[CustomEntityVersion] ([CustomEntityVersionId], [CustomEntityId], [Title], [WorkFlowStatusId], [SerializedData], [CreateDate], [CreatorId], DisplayVersion) VALUES (19, 7, N'Manny', 4, N'{"profileImageAssetId":5,"biography":"Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. \n\nQuisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis."}', CAST(N'2018-10-19 18:14:09' AS DateTime2), 1, 1) 216 | 217 | GO 218 | SET IDENTITY_INSERT [Cofoundry].[CustomEntityVersion] OFF 219 | 220 | /* CUSTOM ENTITY VERSION PAGE BLOCK */ 221 | 222 | SET IDENTITY_INSERT [Cofoundry].[CustomEntityVersionPageBlock] ON 223 | 224 | GO 225 | declare @ContentPageBlockTypeId int 226 | declare @SplitPageBlockTypeId int 227 | declare @PageTemplateRegionId int 228 | select @PageTemplateRegionId = PageTemplateRegionId from Cofoundry.PageTemplateRegion s inner join Cofoundry.PageTemplate t on t.PageTemplateId = s.PageTemplateId where t.[FileName] = 'BlogPostDetails' and s.Name = 'Body' 229 | 230 | select @ContentPageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'ContentSection' 231 | select @SplitPageBlockTypeId = PageBlockTypeId from Cofoundry.PageBlockType where [FileName] = 'ContentSplitSection' 232 | 233 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (1, 4, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":"What a blog post this is!","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, NULL, 3) 234 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (2, 4, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Lorem ipsum dolor sit amet","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":4}', 2, NULL, 3) 235 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (3, 4, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Lorem ipsum dolor sit amet","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":3}', 3, 1, 3) 236 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (4, 5, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":null,"htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, NULL, 3) 237 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (5, 5, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":null,"htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":3}', 2, 1, 3) 238 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (6, 5, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Aliquam erat volutpat","htmlText":"

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":1}', 3, NULL, 3) 239 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (7, 6, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":"Integer eget ipsum sollicitudin","htmlText":"


Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.


"}', 1, NULL, 3) 240 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (8, 6, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Id pellentesque sapien imperdiet vel","htmlText":"

Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

","imageAssetId":4}', 2, NULL, 3) 241 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (9, 6, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Fringilla consectetur","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis.

Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.



","imageAssetId":2}', 3, 1, 3) 242 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (10, 10, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":"Integer eget ipsum sollicitudin","htmlText":"


Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.


"}', 1, NULL, 3) 243 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (11, 10, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Id pellentesque sapien imperdiet vel","htmlText":"

Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

","imageAssetId":4}', 2, NULL, 3) 244 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (12, 10, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Fringilla consectetur","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis.

Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.



","imageAssetId":2}', 3, 1, 3) 245 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (13, 11, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":null,"htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, NULL, 3) 246 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (14, 11, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":null,"htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":3}', 2, 1, 3) 247 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (15, 11, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Aliquam erat volutpat","htmlText":"

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":1}', 3, NULL, 3) 248 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (16, 12, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":"What a blog post this is!","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, NULL, 3) 249 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (17, 12, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Lorem ipsum dolor sit amet","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":4}', 2, NULL, 3) 250 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (18, 12, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Lorem ipsum dolor sit amet","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":3}', 3, 1, 3) 251 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (19, 16, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":"Integer eget ipsum sollicitudin","htmlText":"


Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.


"}', 1, NULL, 3) 252 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (20, 16, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Id pellentesque sapien imperdiet vel","htmlText":"

Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

","imageAssetId":4}', 2, NULL, 3) 253 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (21, 16, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Fringilla consectetur","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis.

Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.



","imageAssetId":2}', 3, 1, 3) 254 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (22, 17, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":null,"htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, NULL, 3) 255 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (23, 17, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":null,"htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":3}', 2, 1, 3) 256 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (24, 17, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Aliquam erat volutpat","htmlText":"

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":1}', 3, NULL, 3) 257 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (25, 18, @PageTemplateRegionId, @ContentPageBlockTypeId, N'{"title":"What a blog post this is!","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque. Phasellus sodales mauris nunc, quis tempor dui blandit vitae. Nullam ornare efficitur felis, eu tristique risus lacinia quis. Quisque tempor, magna id fringilla consectetur, nulla augue venenatis turpis, consequat congue justo eros semper turpis. Integer eget ipsum sollicitudin, vulputate risus a, laoreet lectus. Quisque ornare feugiat neque, id pellentesque sapien imperdiet vel.

"}', 1, NULL, 3) 258 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (26, 18, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Lorem ipsum dolor sit amet","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":4}', 2, NULL, 3) 259 | INSERT [Cofoundry].[CustomEntityVersionPageBlock] ([CustomEntityVersionPageBlockId], [CustomEntityVersionId], [PageTemplateRegionId], [PageBlockTypeId], [SerializedData], [Ordering], [PageBlockTypeTemplateId], PageId) VALUES (27, 18, @PageTemplateRegionId, @SplitPageBlockTypeId, N'{"title":"Lorem ipsum dolor sit amet","htmlText":"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eu enim id odio pretium faucibus vel id risus. Duis auctor lobortis tortor quis vehicula. Maecenas consequat felis augue, vel bibendum velit vulputate ac. Donec laoreet nunc sed turpis iaculis rhoncus. Fusce sit amet tempor nisl, eu rhoncus dolor. Morbi vestibulum at arcu a accumsan. Praesent eget dui dictum, facilisis ante eu, sagittis purus. Donec sit amet euismod felis, ut vestibulum purus. Donec gravida scelerisque ex ac scelerisque.

Vivamus id turpis et purus semper viverra id ut purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vulputate tincidunt ex, ac lobortis erat molestie a. Nulla facilisi. Donec egestas quis sem in bibendum. Curabitur pellentesque accumsan lorem, id ultrices orci scelerisque vitae. Praesent condimentum lorem sed sapien lobortis facilisis. Sed posuere purus quis augue varius commodo. Donec leo tellus, suscipit eu est efficitur, auctor dignissim dolor. Curabitur facilisis sollicitudin ultricies. Sed eget aliquet lorem. Aliquam erat volutpat. Morbi auctor, nulla eu efficitur pharetra, lorem leo lobortis turpis, in elementum enim nibh vel velit.

","imageAssetId":3}', 3, 1, 3) 260 | 261 | GO 262 | SET IDENTITY_INSERT [Cofoundry].[CustomEntityVersionPageBlock] OFF 263 | 264 | /* UNSTRUCTURED DATA DEPENDENCY */ 265 | 266 | GO 267 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 2, N'COFIMG', 4, 1) 268 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 3, N'COFIMG', 3, 1) 269 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 5, N'COFIMG', 3, 1) 270 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 6, N'COFIMG', 1, 1) 271 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 8, N'COFIMG', 4, 1) 272 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 9, N'COFIMG', 2, 1) 273 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 11, N'COFIMG', 4, 1) 274 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 12, N'COFIMG', 2, 1) 275 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 14, N'COFIMG', 3, 1) 276 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 15, N'COFIMG', 1, 1) 277 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 17, N'COFIMG', 4, 1) 278 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 18, N'COFIMG', 3, 1) 279 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 20, N'COFIMG', 4, 1) 280 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 21, N'COFIMG', 2, 1) 281 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 23, N'COFIMG', 3, 1) 282 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 24, N'COFIMG', 1, 1) 283 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 26, N'COFIMG', 4, 1) 284 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEB', 27, N'COFIMG', 3, 1) 285 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 1, N'COFIMG', 3, 1) 286 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 2, N'COFIMG', 1, 1) 287 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 3, N'COFIMG', 4, 1) 288 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 4, N'COFIMG', 4, 1) 289 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 5, N'COFIMG', 1, 1) 290 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 6, N'COFIMG', 3, 1) 291 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 10, N'COFIMG', 3, 1) 292 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 10, N'SIMCAT', 5, 2) 293 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 11, N'COFIMG', 1, 1) 294 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 11, N'SIMCAT', 4, 2) 295 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 11, N'SIMCAT', 6, 2) 296 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 12, N'COFIMG', 4, 1) 297 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 12, N'SIMCAT', 4, 2) 298 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 12, N'SIMCAT', 5, 2) 299 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 16, N'COFIMG', 3, 1) 300 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 16, N'SIMCAT', 4, 2) 301 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 16, N'SIMCAT', 6, 2) 302 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 17, N'COFIMG', 1, 1) 303 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 17, N'SIMCAT', 6, 2) 304 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 18, N'COFIMG', 4, 1) 305 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 18, N'SIMCAT', 5, 2) 306 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFCEV', 18, N'SIMCAT', 6, 2) 307 | INSERT [Cofoundry].[UnstructuredDataDependency] ([RootEntityDefinitionCode], [RootEntityId], [RelatedEntityDefinitionCode], [RelatedEntityId], [RelatedEntityCascadeActionId]) VALUES (N'COFPGB', 4, N'COFIMG', 1, 1) 308 | GO 309 | 310 | /* TAG */ 311 | 312 | SET IDENTITY_INSERT [Cofoundry].[Tag] ON 313 | 314 | GO 315 | INSERT [Cofoundry].[Tag] ([TagId], [TagText], [CreateDate]) VALUES (1, N'Blog', CAST(N'2018-10-18 09:18:28' AS DateTime2)) 316 | INSERT [Cofoundry].[Tag] ([TagId], [TagText], [CreateDate]) VALUES (2, N'Blogimage', CAST(N'2018-10-18 09:18:28' AS DateTime2)) 317 | INSERT [Cofoundry].[Tag] ([TagId], [TagText], [CreateDate]) VALUES (3, N'Mountain Sunrise', CAST(N'2018-10-18 09:23:22' AS DateTime2)) 318 | INSERT [Cofoundry].[Tag] ([TagId], [TagText], [CreateDate]) VALUES (4, N'Snow Landscape', CAST(N'2018-10-18 09:23:42' AS DateTime2)) 319 | INSERT [Cofoundry].[Tag] ([TagId], [TagText], [CreateDate]) VALUES (5, N'Mountains', CAST(N'2018-10-18 09:23:42' AS DateTime2)) 320 | INSERT [Cofoundry].[Tag] ([TagId], [TagText], [CreateDate]) VALUES (6, N'Sunset', CAST(N'2018-10-18 09:26:45' AS DateTime2)) 321 | INSERT [Cofoundry].[Tag] ([TagId], [TagText], [CreateDate]) VALUES (7, N'Profile', CAST(N'2018-10-19 09:44:39' AS DateTime2)) 322 | GO 323 | SET IDENTITY_INSERT [Cofoundry].[Tag] OFF 324 | 325 | /* IMAGE TAG */ 326 | 327 | GO 328 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (1, 1, CAST(N'2018-10-18 09:18:28' AS DateTime2), 1) 329 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (1, 2, CAST(N'2018-10-18 09:18:28' AS DateTime2), 1) 330 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (2, 1, CAST(N'2018-10-18 09:23:22' AS DateTime2), 1) 331 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (2, 3, CAST(N'2018-10-18 09:23:22' AS DateTime2), 1) 332 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (3, 4, CAST(N'2018-10-18 09:23:42' AS DateTime2), 1) 333 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (3, 5, CAST(N'2018-10-18 09:23:42' AS DateTime2), 1) 334 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (4, 1, CAST(N'2018-10-18 09:26:45' AS DateTime2), 1) 335 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (4, 6, CAST(N'2018-10-18 09:26:45' AS DateTime2), 1) 336 | INSERT [Cofoundry].[ImageAssetTag] ([ImageAssetId], [TagId], [CreateDate], [CreatorId]) VALUES (5, 7, CAST(N'2018-10-19 09:44:39' AS DateTime2), 1) 337 | GO 338 | 339 | 340 | /* Update calculated tables */ 341 | 342 | exec Cofoundry.CustomEntityPublishStatusQuery_Update @CustomEntityId = 1 343 | exec Cofoundry.CustomEntityPublishStatusQuery_Update @CustomEntityId = 2 344 | exec Cofoundry.CustomEntityPublishStatusQuery_Update @CustomEntityId = 3 345 | exec Cofoundry.CustomEntityPublishStatusQuery_Update @CustomEntityId = 4 346 | exec Cofoundry.CustomEntityPublishStatusQuery_Update @CustomEntityId = 5 347 | exec Cofoundry.CustomEntityPublishStatusQuery_Update @CustomEntityId = 6 348 | exec Cofoundry.CustomEntityPublishStatusQuery_Update @CustomEntityId = 7 349 | 350 | exec Cofoundry.PagePublishStatusQuery_Update @PageId = 1 351 | exec Cofoundry.PagePublishStatusQuery_Update @PageId = 2 352 | exec Cofoundry.PagePublishStatusQuery_Update @PageId = 3 353 | exec Cofoundry.PagePublishStatusQuery_Update @PageId = 4 354 | exec Cofoundry.PagePublishStatusQuery_Update @PageId = 5 355 | 356 | exec Cofoundry.PageDirectoryClosure_Update -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Bufftail Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cofoundry.Samples.SimpleSite 2 | 3 | A simple website implementing content management and some framework features including: 4 | 5 | - Startup registration 6 | - Page templates 7 | - Custom page blocks 8 | - Image content 9 | - Three custom entities - blog post, authors and category 10 | - Querying and display a list of blog posts 11 | - A blog post custom entity details page 12 | - A simple contact form 13 | - Email notifications & email templating 14 | - Custom error pages 15 | - Configuration Settings 16 | 17 | #### To get started: 18 | 19 | 1. Create a database named 'Cofoundry.Samples.SimpleSite' and check the Cofoundry connection string in the appsettings.json file is correct for you SQL Server instance 20 | 2. Run the website and navigate to *"/admin"*, which will display the setup screen 21 | 3. Enter an application name and setup your user account. Submit the form to complete the site setup. 22 | 4. Either log in and enter your own data or follow the steps below to import some test data 23 | 24 | #### Importing test data: 25 | 26 | To get you started we've put together some optional test data: 27 | 28 | 1. Run `InitData\Init.sql` script against your db to populate some initial pages and blog posts 29 | 2. Copy the images from *"\InitData\Images"* to *"\src\Cofoundry.Samples.SimpleSite\App_Data\Files\Images"* 30 | 3. Either restart the site, or go to the *settings* module in the admin panel and clear the cache. 31 | 32 | ## App Overview 33 | 34 | This is a simple company website that includes several content managed pages, a blog and a contact form. 35 | 36 | ### Managing Content 37 | 38 | Cofoundry has a back-office administration panel that is used to manage the majority of content and settings, but there is also an in-page *visual editor* that allows you to manage page content as you browse the site. 39 | 40 | #### Visual Editor 41 | 42 | If you've installed the test data and logged in, you will be able to navigate the site and see the *visual editor toolbar* at the bottom of the screen, which contains buttons that let you *edit*, *preview* and *publish* pages and blog posts as you browse the site. 43 | 44 | Click on the **Edit Draft** button to start editing. 45 | 46 | ![Visual Editor](https://github.com/cofoundry-cms/cofoundry/wiki/images/VisualEditor.png) 47 | 48 | When in edit mode, regions of the page are highlighted and become editable, allowing content to be added. These editable regions are declared in a *page template*, which is simply a razor .cshtml file placed in a specific location in your solution. 49 | 50 | For more information about pages take a look at the [pages](https://github.com/cofoundry-cms/cofoundry/wiki/Pages) and [page template](https://github.com/cofoundry-cms/cofoundry/wiki/Page-Templates) documentation. 51 | 52 | 53 | #### Admin Panel 54 | 55 | The visual editor is good for editing page content, but to manage the website structure and configure content and settings you'll need to sign into the admin panel, to do this navigate to **/admin**. 56 | 57 | The main parts of the admin panel we're interested in for this example are the *Pages* region and the *Blog Posts* region. 58 | 59 | ![Pages Region](readme/AdminPages.png) 60 | 61 | *Pages* allows us to manage the dynamic pages in the website site, while *Blog Posts* lets you manage article content. Blogging functionality isn't included by default in Cofoundry, instead we've used the flexible **Custom Entity** framework to create a *Blog Post* and *Category* type. 62 | 63 | *Custom Entities* are defined in code by writing a couple of class files. For more detailed information on this check out the [custom entities documentation](https://www.cofoundry.org/docs/content-management/custom-entities). 64 | 65 | ### Code 66 | 67 | In this example we've tried to keep things simple and have put all the code into a single project. For more complex applications you'll probably want to split out some of this logic and data access into one or more layers, [Cofoundry.Samples.SPASite](https://github.com/cofoundry-cms/Cofoundry.Samples.SPASite) is a more structured example that demonstrates one way you might choose do this. 68 | 69 | ![Website Solution](readme/WebSolution.png) 70 | 71 | - **Cofoundry:** In this example we put all Cofoundry templates, block types and custom entity definitions in a special Cofoundry folder to keep them separate, but the templates can also go in the Views folder if that feels more natural to you. The code files can be placed anywhere. 72 | - **Content:** This is where you'll find the css for the project. Styling has been kept to a minimum in this example to keep things simple. 73 | - **Models:** The models folder contains some basic view models and two examples of Cofoundry features. An email template model demonstrates the [Mail framework](https://www.cofoundry.org/docs/framework/mail) and a settings model demonstrates the [strongly typed settings feature](https://www.cofoundry.org/docs/framework/configuration-settings). 74 | - **ViewComponents:** Although the pages are dynamic, we use *ViewComponents* to include some functionality such as the blog post listing and the contact form action. These component files contain the server-side code for these features. 75 | - **Views:** In this project the page templates are defined in the *Cofoundry/PageTemplates* folder, but partials, layouts and view component views are still located in the normal views folder. 76 | - **Program.cs:** [Cofoundry startup and registration](https://www.cofoundry.org/docs/framework/website-startup) is handled in the Program.cs file. Page routing in this example is handled by Cofoundry, but you [can also specify ASP.NET routes](https://www.cofoundry.org/docs/content-management/routing) if you want. 77 | -------------------------------------------------------------------------------- /readme/AdminPages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/readme/AdminPages.png -------------------------------------------------------------------------------- /readme/WebSolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/readme/WebSolution.png -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry.Samples.SimpleSite.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | false 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/Authors/AuthorCustomEntityDefinition.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | /// 4 | /// Each custom entity requires a definition class which provides settings 5 | /// describing the entity and how it should behave. 6 | /// 7 | public class AuthorCustomEntityDefinition 8 | : ICustomEntityDefinition 9 | , ICustomizedTermCustomEntityDefinition 10 | { 11 | /// 12 | /// This constant is a convention that allows us to reference this definition code 13 | /// in other parts of the application (e.g. querying) 14 | /// 15 | public const string DefinitionCode = "SIMAUT"; 16 | 17 | /// 18 | /// Unique 6 letter code representing the entity (the convention is to use uppercase) 19 | /// 20 | public string CustomEntityDefinitionCode => DefinitionCode; 21 | 22 | /// 23 | /// Singlar name of the entity 24 | /// 25 | public string Name => "Author"; 26 | 27 | /// 28 | /// Plural name of the entity 29 | /// 30 | public string NamePlural => "Authors"; 31 | 32 | /// 33 | /// A short description that shows up as a tooltip for the admin 34 | /// module. 35 | /// 36 | public string Description => "An author for one or more blog posts."; 37 | 38 | /// 39 | /// Indicates whether the UrlSlug property should be treated 40 | /// as a unique property and be validated as such. 41 | /// 42 | public bool ForceUrlSlugUniqueness => true; 43 | 44 | /// 45 | /// Indicates whether the url slug should be autogenerated. If this 46 | /// is selected then the user will not be shown the UrlSlug property 47 | /// and it will be auto-generated based on the title. 48 | /// 49 | public bool AutoGenerateUrlSlug => true; 50 | 51 | /// 52 | /// Indicates whether this custom entity should always be published when 53 | /// saved, provided the user has permissions to do so. Useful if this isn't 54 | /// the sort of entity that needs a draft state workflow 55 | /// 56 | public bool AutoPublish => true; 57 | 58 | /// 59 | /// Indicates whether the entities are partitioned by locale 60 | /// 61 | public bool HasLocale => false; 62 | 63 | /// 64 | /// We're implementing ICustomizedTermCustomEntityDefinition here 65 | /// in order to change the term for "Title" to "Name", which makes 66 | /// more sense when creating authors in the admin panel. 67 | /// 68 | public Dictionary CustomTerms => new() 69 | { 70 | { CustomizableCustomEntityTermKeys.Title, "Name" } 71 | }; 72 | } 73 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/Authors/AuthorDataModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// This defines the custom data that gets stored with each author. Data 7 | /// is stored in an unstructured format (json) so simple data types are 8 | /// best. For associations, you just need to store the key of the relation. 9 | /// 10 | /// Attributes can be used to describe validations as well as hints to the 11 | /// content editor UI on how to render the data input controls. 12 | /// 13 | public class AuthorDataModel : ICustomEntityDataModel 14 | { 15 | [Image(MinWidth = 300, MinHeight = 300)] 16 | [Display(Name = "Profile Image", Description = "Square image that displays against the author bio.")] 17 | public int? ProfileImageAssetId { get; set; } 18 | 19 | [MaxLength(500)] 20 | [Display(Description = "A short bio that appears alongside the author.")] 21 | [MultiLineText] 22 | public string? Biography { get; set; } 23 | } 24 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostCustomEntityDefinition.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | /// 4 | /// Each custom entity requires a definition class which provides settings 5 | /// describing the entity and how it should behave. 6 | /// 7 | public class BlogPostCustomEntityDefinition 8 | : ICustomEntityDefinition 9 | , ISortedCustomEntityDefinition 10 | { 11 | /// 12 | /// This constant is a convention that allows us to reference this definition code 13 | /// in other parts of the application (e.g. querying) 14 | /// 15 | public const string DefinitionCode = "SIMBLP"; 16 | 17 | /// 18 | /// Unique 6 letter code representing the entity (the convention is to use uppercase) 19 | /// 20 | public string CustomEntityDefinitionCode => DefinitionCode; 21 | 22 | /// 23 | /// Singlar name of the entity. 24 | /// 25 | public string Name => "Blog Post"; 26 | 27 | /// 28 | /// Plural name of the entity. 29 | /// 30 | public string NamePlural => "Blog Posts"; 31 | 32 | /// 33 | /// A short description that shows up as a tooltip for the admin . 34 | /// module. 35 | /// 36 | public string Description => "Articles that appear in the blog section of the site."; 37 | 38 | /// 39 | /// Indicates whether the UrlSlug property should be treated 40 | /// as a unique property and be validated as such. 41 | /// 42 | public bool ForceUrlSlugUniqueness => false; 43 | 44 | /// 45 | /// Indicates whether the url slug should be autogenerated. If this 46 | /// is selected then the user will not be shown the UrlSlug property 47 | /// and it will be auto-generated based on the title. 48 | /// 49 | public bool AutoGenerateUrlSlug => true; 50 | 51 | /// 52 | /// Indicates whether this custom entity should always be published when 53 | /// saved, provided the user has permissions to do so. Useful if this isn't 54 | /// the sort of entity that needs a draft state workflow. 55 | /// 56 | public bool AutoPublish => false; 57 | 58 | /// 59 | /// Indicates whether the entities are partitioned by locale. 60 | /// 61 | public bool HasLocale => false; 62 | 63 | /// 64 | /// The sorting to apply by default when querying collections of custom 65 | /// entities of this type. A query can specify a sort type to override 66 | /// this value. 67 | /// 68 | public CustomEntityQuerySortType DefaultSortType => CustomEntityQuerySortType.PublishDate; 69 | 70 | /// 71 | /// The default sort direction to use when ordering with the 72 | /// default sort type. 73 | /// 74 | public SortDirection DefaultSortDirection => SortDirection.Default; 75 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostDataModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// This defines the custom data that gets stored with each blog post. Data 7 | /// is stored in an unstructured format (json) so simple data types are 8 | /// best. For associations, you just need to store the key of the relation. 9 | /// 10 | /// Attributes can be used to describe validations as well as hints to the 11 | /// content editor UI on how to render the data input controls. 12 | /// 13 | public class BlogPostDataModel : ICustomEntityDataModel 14 | { 15 | [MaxLength(1000)] 16 | [Required] 17 | [Display(Description = "A description for display in search results and in the details page meta description.")] 18 | [MultiLineText] 19 | public string ShortDescription { get; set; } = string.Empty; 20 | 21 | [Image(MinWidth = 460, MinHeight = 460)] 22 | [Display(Name = "Thumbnail Image", Description = "Square image that displays against the blog in the listing page.")] 23 | public int ThumbnailImageAssetId { get; set; } 24 | 25 | [Required] 26 | [Display(Name = "Author", Description = "The author to attribute the blog post to.")] 27 | [CustomEntity(AuthorCustomEntityDefinition.DefinitionCode)] 28 | public int AuthorId { get; set; } 29 | 30 | [Display(Name = "Categories", Description = "Drag and drop to customize the category ordering.")] 31 | [CustomEntityCollection(CategoryCustomEntityDefinition.DefinitionCode, IsOrderable = true)] 32 | public int[] CategoryIds { get; set; } = []; 33 | } 34 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModel.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | /// 4 | /// An ICustomEntityDetailsDisplayViewModel implementation is required if 5 | /// you want to use a page template to dynamically render a details view 6 | /// of a custom entity. This provides us with a strongly typed model to use 7 | /// in the template. 8 | /// 9 | public class BlogPostDisplayModel : ICustomEntityPageDisplayModel 10 | { 11 | public required string PageTitle { get; set; } 12 | 13 | public required string? MetaDescription { get; set; } 14 | 15 | public required string Title { get; set; } 16 | 17 | public required DateTime Date { get; set; } 18 | 19 | public required string FullPath { get; set; } 20 | 21 | public required AuthorDetails? Author { get; set; } 22 | 23 | public required IReadOnlyCollection Categories { get; set; } 24 | } 25 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | /// 4 | /// This mapper is required to map from the data returned from the database to 5 | /// a strongly typed model that we can use in the view template. This might seem 6 | /// a little verbose but this allows us to use a strongly typed model in the view 7 | /// and provides us with a lot of flexibility when mapping from unstructured data 8 | /// 9 | public class BlogPostDisplayModelMapper 10 | : ICustomEntityDisplayModelMapper 11 | { 12 | private readonly IContentRepository _contentRepository; 13 | 14 | public BlogPostDisplayModelMapper( 15 | IContentRepository contentRepository 16 | ) 17 | { 18 | _contentRepository = contentRepository; 19 | } 20 | 21 | /// 22 | /// Maps a raw custom entity data model to a display model that can be rendered out 23 | /// to a view template. 24 | /// 25 | /// 26 | /// The raw custom entity data pulled from the database. 27 | /// 28 | /// 29 | /// Typed model data to map from. This is the same model that's in the render 30 | /// details model, but is passed in as a typed model for easy access. 31 | /// 32 | /// 33 | /// The query type that should be used to query dependent entities. E.g. if the custom 34 | /// entity was queried with the Published status query, then any dependent entities should 35 | /// also be queried as Published. 36 | /// 37 | public async Task MapDisplayModelAsync( 38 | CustomEntityRenderDetails renderDetails, 39 | BlogPostDataModel dataModel, 40 | PublishStatusQuery publishStatusQuery 41 | ) 42 | { 43 | var categories = await MapCategories(dataModel, publishStatusQuery); 44 | var author = await MapAuthor(dataModel, publishStatusQuery); 45 | 46 | var displayModel = new BlogPostDisplayModel() 47 | { 48 | MetaDescription = dataModel.ShortDescription, 49 | PageTitle = renderDetails.Title, 50 | Title = renderDetails.Title, 51 | Date = renderDetails.CreateDate, 52 | FullPath = renderDetails.PageUrls.FirstOrDefault() ?? string.Empty, 53 | Categories = categories, 54 | Author = author 55 | }; 56 | 57 | return displayModel; 58 | } 59 | 60 | private async Task> MapCategories( 61 | BlogPostDataModel dataModel, 62 | PublishStatusQuery publishStatusQuery 63 | ) 64 | { 65 | if (EnumerableHelper.IsNullOrEmpty(dataModel.CategoryIds)) 66 | { 67 | return Array.Empty(); 68 | } 69 | 70 | // We manually query and map relations which gives us maximum flexibility when 71 | // mapping models. Cofoundry provides apis and extensions to make this easier. 72 | var results = await _contentRepository 73 | .CustomEntities() 74 | .GetByIdRange(dataModel.CategoryIds) 75 | .AsRenderSummaries(publishStatusQuery) 76 | .FilterAndOrderByKeys(dataModel.CategoryIds) 77 | .MapItem(MapCategory) 78 | .ExecuteAsync(); 79 | 80 | return results; 81 | } 82 | 83 | /// 84 | /// We could use AutoMapper here, but to keep it simple let's just do manual mapping. 85 | /// 86 | private CategorySummary MapCategory(CustomEntityRenderSummary renderSummary) 87 | { 88 | // A CustomEntityRenderSummary will always contain the data model for the custom entity 89 | var model = renderSummary.Model as CategoryDataModel; 90 | 91 | var category = new CategorySummary() 92 | { 93 | CategoryId = renderSummary.CustomEntityId, 94 | Title = renderSummary.Title, 95 | ShortDescription = model?.ShortDescription 96 | }; 97 | 98 | return category; 99 | } 100 | 101 | private async Task MapAuthor( 102 | BlogPostDataModel dataModel, 103 | PublishStatusQuery publishStatusQuery 104 | ) 105 | { 106 | if (dataModel.AuthorId < 1) 107 | { 108 | return null; 109 | } 110 | 111 | var dbAuthor = await _contentRepository 112 | .CustomEntities() 113 | .GetById(dataModel.AuthorId) 114 | .AsRenderSummary(publishStatusQuery) 115 | .ExecuteAsync(); 116 | 117 | if (dbAuthor?.Model is not AuthorDataModel model) 118 | { 119 | return null; 120 | } 121 | 122 | var author = new AuthorDetails() 123 | { 124 | Name = dbAuthor.Title, 125 | Biography = HtmlFormatter.ConvertToBasicHtml(model.Biography) 126 | }; 127 | 128 | if (!model.ProfileImageAssetId.HasValue) 129 | { 130 | return author; 131 | } 132 | 133 | author.ProfileImage = await _contentRepository 134 | .ImageAssets() 135 | .GetById(model.ProfileImageAssetId.Value) 136 | .AsRenderDetails() 137 | .ExecuteAsync(); 138 | 139 | return author; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/Categories/CategoryCustomEntityDefinition.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | /// 4 | /// Each custom entity requires a definition class which provides settings 5 | /// describing the entity and how it should behave. 6 | /// 7 | public class CategoryCustomEntityDefinition : ICustomEntityDefinition 8 | { 9 | /// 10 | /// This constant is a convention that allows us to reference this definition code 11 | /// in other parts of the application (e.g. querying) 12 | /// 13 | public const string DefinitionCode = "SIMCAT"; 14 | 15 | /// 16 | /// Unique 6 letter code representing the entity (the convention is to use uppercase) 17 | /// 18 | public string CustomEntityDefinitionCode => DefinitionCode; 19 | 20 | /// 21 | /// Singlar name of the entity 22 | /// 23 | public string Name => "Category"; 24 | 25 | /// 26 | /// Plural name of the entity 27 | /// 28 | public string NamePlural => "Categories"; 29 | 30 | /// 31 | /// A short description that shows up as a tooltip for the admin 32 | /// module. 33 | /// 34 | public string Description => "Used to categorize blog posts."; 35 | 36 | /// 37 | /// Indicates whether the UrlSlug property should be treated 38 | /// as a unique property and be validated as such. 39 | /// 40 | public bool ForceUrlSlugUniqueness => true; 41 | 42 | /// 43 | /// Indicates whether the url slug should be autogenerated. If this 44 | /// is selected then the user will not be shown the UrlSlug property 45 | /// and it will be auto-generated based on the title. 46 | /// 47 | public bool AutoGenerateUrlSlug => true; 48 | 49 | /// 50 | /// Indicates whether this custom entity should always be published when 51 | /// saved, provided the user has permissions to do so. Useful if this isn't 52 | /// the sort of entity that needs a draft state workflow 53 | /// 54 | public bool AutoPublish => true; 55 | 56 | /// 57 | /// Indicates whether the entities are partitioned by locale 58 | /// 59 | public bool HasLocale => false; 60 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/CustomEntities/Categories/CategoryDataModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// This defines the custom data that gets stored with each blog post. Data 7 | /// is stored in an unstructured format (json) so simple data types are 8 | /// best. For associations, you just need to store the key of the relation. 9 | /// 10 | /// Attributes can be used to describe validations as well as hints to the 11 | /// content editor UI on how to render the data input controls. 12 | /// 13 | public class CategoryDataModel : ICustomEntityDataModel 14 | { 15 | [MaxLength(500)] 16 | [Display(Description = "A short description that appears as a tooltip when hovering over the category.")] 17 | [MultiLineText] 18 | public string? ShortDescription { get; set; } 19 | } 20 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSection.cshtml: -------------------------------------------------------------------------------- 1 | @model ContentSectionDisplayModel 2 | @inject ICofoundryBlockTypeHelper Cofoundry 3 | 4 | @* 5 | Here we can use the Cofoundry helper to set the description that 6 | gets displayed against the module in the administration interface. 7 | 8 | This is optional and doesn't render anything into the template itself. 9 | *@ 10 | @Cofoundry.BlockType.UseDescription("This is a content row with a heading") 11 | 12 |
13 |
14 | @if (!string.IsNullOrWhiteSpace(Model.Title)) 15 | { 16 |

@Model.Title

17 | } 18 | @Model.HtmlText 19 |
20 |
21 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDataModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// Each block type should have a data model that implements IPageBlockTypeDataModel that 7 | /// describes the data to store in the database. Data is stored in an unstructured 8 | /// format (json) so simple serializable data types are best. 9 | /// 10 | /// Attributes can be used to describe validations as well as hints to the 11 | /// content editor UI on how to render the data input controls. 12 | /// 13 | /// See https://www.cofoundry.org/docs/content-management/page-block-types 14 | /// for more information 15 | /// 16 | public class ContentSectionDataModel : IPageBlockTypeDataModel 17 | { 18 | [Display(Description = "Optional title to display at the top of the section")] 19 | public string? Title { get; set; } 20 | 21 | [Required] 22 | [Display(Name = "Text", Description = "Rich text displayed at full width")] 23 | [Html(HtmlToolbarPreset.BasicFormatting, HtmlToolbarPreset.Headings, HtmlToolbarPreset.Media)] 24 | public string HtmlText { get; set; } = string.Empty; 25 | } 26 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Html; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// Each block type must have a display model that is marked with 7 | /// IPageBlockTypeDisplayModel. This is the model that is rendered 8 | /// in the view. In simple scenarios you can simply mark up the data 9 | /// model as the display model, but here we want to transform the 10 | /// HtmlText property so we need to define a separate model. 11 | /// 12 | /// See https://www.cofoundry.org/docs/content-management/page-block-types 13 | /// for more information 14 | /// 15 | public class ContentSectionDisplayModel : IPageBlockTypeDisplayModel 16 | { 17 | public required string? Title { get; set; } 18 | 19 | public required IHtmlContent HtmlText { get; set; } 20 | } 21 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Html; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// A IPageBlockDisplayModelMapper class handles the mapping from 7 | /// a display model to a data model. 8 | /// 9 | /// The mapper supports DI which gives you flexibility in what data 10 | /// you want to include in the display model and how you want to 11 | /// map it. Mapping is done in batch to improve performance when 12 | /// the same block type is used multiple times on a page 13 | /// 14 | public class ContentSectionDisplayModelMapper : IPageBlockTypeDisplayModelMapper 15 | { 16 | /// 17 | /// A IPageModuleDisplayModelMapper class handles the mapping from 18 | /// a display model to a data model. 19 | /// 20 | /// The mapper supports DI which gives you flexibility in what data 21 | /// you want to include in the display model and how you want to 22 | /// map it. Mapping is done in batch to improve performance when 23 | /// the same block type is used multiple times on a page. 24 | /// 25 | public Task MapAsync( 26 | PageBlockTypeDisplayModelMapperContext context, 27 | PageBlockTypeDisplayModelMapperResult result 28 | ) 29 | { 30 | foreach (var input in context.Items) 31 | { 32 | var output = new ContentSectionDisplayModel() 33 | { 34 | HtmlText = new HtmlString(input.DataModel.HtmlText), 35 | Title = input.DataModel.Title 36 | }; 37 | 38 | result.Add(input, output); 39 | } 40 | 41 | return Task.CompletedTask; 42 | } 43 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSection.cshtml: -------------------------------------------------------------------------------- 1 | @model ContentSplitSectionDisplayModel 2 | @inject ICofoundryBlockTypeHelper Cofoundry 3 | 4 | @{ 5 | // As with the ContentSection module, we set the description that 6 | // gets displayed against the module in the administration interface. 7 | 8 | // Additionally we can set a custom value for the display name, but 9 | // by default a humanized version of the template name is used. 10 | 11 | Cofoundry.BlockType 12 | .UseDisplayName("Split Section Content") 13 | .UseDescription("This is a content row split in two halves with text in one half and an image in the other"); 14 | } 15 | 16 |
17 |
18 | @if (!string.IsNullOrWhiteSpace(Model.Title)) 19 | { 20 |

@Model.Title

21 | } 22 | @Model.HtmlText 23 |
24 | 25 |
26 | 27 |
28 |
-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDataModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// Each block type should have a data model that implements IPageBlockTypeDataModel that 7 | /// describes the data to store in the database. Data is stored in an unstructured 8 | /// format (json) so simple serializable data types are best. 9 | /// 10 | /// Attributes can be used to describe validations as well as hints to the 11 | /// content editor UI on how to render the data input controls. 12 | /// 13 | /// See https://www.cofoundry.org/docs/content-management/page-block-types 14 | /// for more information 15 | /// 16 | public class ContentSplitSectionDataModel : IPageBlockTypeDataModel 17 | { 18 | [Display(Description = "Optional title to display at the top of the section")] 19 | public string? Title { get; set; } 20 | 21 | [Required] 22 | [Display(Name = "Text", Description = "Rich text displayed alongside the image")] 23 | [Html(HtmlToolbarPreset.BasicFormatting, HtmlToolbarPreset.Headings)] 24 | public string HtmlText { get; set; } = string.Empty; 25 | 26 | [Display(Description = "Image to display alongside the text")] 27 | [Image(MinWidth = 400, MinHeight = 400)] 28 | public int ImageAssetId { get; set; } 29 | } 30 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Html; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// Each blcck type must have a display model that is marked with 7 | /// IPageBlockTypeDisplayModel. This is the model that is rendered 8 | /// in the view. In simple scenarios you can simply mark up the data 9 | /// model as the display model, but here we want to transform the 10 | /// HtmlText property so we need to define a separate model. 11 | /// 12 | /// See https://www.cofoundry.org/docs/content-management/page-block-types 13 | /// for more information 14 | /// 15 | public class ContentSplitSectionDisplayModel : IPageBlockTypeDisplayModel 16 | { 17 | public required string? Title { get; set; } 18 | 19 | public required IHtmlContent HtmlText { get; set; } 20 | 21 | public required ImageAssetRenderDetails? Image { get; set; } 22 | } 23 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Html; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// A IPageBlockDisplayModelMapper class handles the mapping from 7 | /// a display model to a data model. 8 | /// 9 | /// The mapper supports DI which gives you flexibility in what data 10 | /// you want to include in the display model and how you want to 11 | /// map it. Mapping is done in batch to improve performance when 12 | /// the same block type is used multiple times on a page. 13 | /// 14 | public class ContentSplitSectionDisplayModelMapper : IPageBlockTypeDisplayModelMapper 15 | { 16 | private readonly IContentRepository _contentRepository; 17 | 18 | public ContentSplitSectionDisplayModelMapper( 19 | IContentRepository contentRepository 20 | ) 21 | { 22 | _contentRepository = contentRepository; 23 | } 24 | 25 | public async Task MapAsync( 26 | PageBlockTypeDisplayModelMapperContext context, 27 | PageBlockTypeDisplayModelMapperResult result 28 | ) 29 | { 30 | // Because mapping is done in batch, we have to map multiple images here 31 | // The Cofoundry IContentRepository gives us an easy to use data access api. 32 | // for us 33 | var imageAssetIds = context.Items.SelectDistinctModelValuesWithoutEmpty(i => i.ImageAssetId); 34 | var imageAssets = await _contentRepository 35 | .WithContext(context.ExecutionContext) 36 | .ImageAssets() 37 | .GetByIdRange(imageAssetIds) 38 | .AsRenderDetails() 39 | .ExecuteAsync(); 40 | 41 | foreach (var item in context.Items) 42 | { 43 | var displayModel = new ContentSplitSectionDisplayModel() 44 | { 45 | HtmlText = new HtmlString(item.DataModel.HtmlText), 46 | Title = item.DataModel.Title, 47 | Image = imageAssets.GetValueOrDefault(item.DataModel.ImageAssetId) 48 | }; 49 | 50 | result.Add(item, displayModel); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/Templates/ContentSplitSectionReverse.cshtml: -------------------------------------------------------------------------------- 1 | @model ContentSplitSectionDisplayModel 2 | @inject ICofoundryBlockTypeHelper Cofoundry 3 | 4 | @{ 5 | // Additional module templates can be defined which gives content editors 6 | // a choice in how the module data is rendered 7 | Cofoundry.BlockType 8 | .UseDisplayName("Reverse") 9 | .UseDescription("This is a reversed template with the image on the left and the text on the right"); 10 | } 11 | 12 |
13 |
14 | 15 |
16 | 17 |
18 | @if (!string.IsNullOrWhiteSpace(Model.Title)) 19 | { 20 |

@Model.Title

21 | } 22 | @Model.HtmlText 23 |
24 |
-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageTemplates/_BlogPostDetails.cshtml: -------------------------------------------------------------------------------- 1 | @model ICustomEntityPageViewModel 2 | @inject ICofoundryTemplateHelper> Cofoundry 3 | 4 | @{ 5 | Cofoundry.Template.UseDescription("Template for the blog post details page"); 6 | var post = Model.CustomEntity.Model; 7 | } 8 | 9 |
10 | 11 |
12 |
13 |

@Model.PageTitle

14 |
15 |
16 | 17 |
18 | @(await Cofoundry.Template.CustomEntityRegion("Body") 19 | .AllowMultipleBlocks() 20 | .AllowBlockType() 21 | .AllowBlockType() 22 | .EmptyContentMinHeight(500) 23 | .InvokeAsync()) 24 | 25 | @if (post.Author != null) 26 | { 27 | 43 | 44 | } 45 |
46 | 47 |
48 | @if (!EnumerableHelper.IsNullOrEmpty(post.Categories)) 49 | { 50 |

Categories

51 | 52 |
    53 | @foreach (var category in post.Categories) 54 | { 55 |
  • @category.Title
  • 56 | } 57 |
58 | } 59 | 60 |
61 | 62 |
-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageTemplates/_BlogPostList.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 | @inject ICofoundryTemplateHelper Cofoundry 3 | 4 | @Cofoundry.Template.UseDescription("Template for the blog post listing page") 5 | 6 |
7 |
8 |
9 | 10 | @* 11 | Although this list page template is content-mangeable, Cofoundry doesn't 12 | provide any helpers for outputting dynamic lists of items, so it's up to 13 | implement this using MVC ViewComponents 14 | *@ 15 | @await Component.InvokeAsync("BlogPostList") 16 | 17 |
18 | 19 | 22 |
23 |
-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageTemplates/_Contact.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 | @inject ICofoundryTemplateHelper Cofoundry 3 | 4 | @Cofoundry.Template.UseDescription("Template for the contact page") 5 | 6 |
7 | 8 |
9 |
10 | 11 |
12 |
13 |
14 |

@Model.PageTitle

15 |

16 | @(await Cofoundry 17 | .Template 18 | .Region("Introduction") 19 | .AllowBlockType() 20 | .EmptyContentMinHeight(200) 21 | .InvokeAsync()) 22 |

23 | 24 | @await Component.InvokeAsync("ContactRequestForm") 25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageTemplates/_General.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 | @inject ICofoundryTemplateHelper Cofoundry 3 | 4 | @Cofoundry.Template.UseDescription("A template for simple pages with flexible module content") 5 | 6 |
7 |
8 |
9 |

@Model.PageTitle

10 |
11 |
12 | @* 13 | Note here that we can use AllowBlockTypes() to specify multiple 14 | block types. Using the generic AllowBlockType() 15 | multiple times is preferable because it doesn't rely on magic 16 | strings, but there may be situations where this is more advantageous. 17 | *@ 18 | @(await Cofoundry.Template.Region("Body") 19 | .AllowMultipleBlocks() 20 | .AllowBlockTypes("ContentSection", "ContentSplitSection") 21 | .EmptyContentMinHeight(500) 22 | .InvokeAsync()) 23 | 24 |
25 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageTemplates/_Home.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 | @inject ICofoundryTemplateHelper Cofoundry 3 | 4 | @Cofoundry.Template.UseDescription("This template shoud only be used for the homepage") 5 | 6 |
7 | 8 |
9 |
10 | 11 |
12 |
13 |
14 |

15 | @(await Cofoundry 16 | .Template 17 | .Region("Introduction Title") 18 | .AllowBlockType() 19 | .InvokeAsync()) 20 |

21 | @(await Cofoundry 22 | .Template 23 | .Region("Introduction") 24 | .AllowBlockType() 25 | .EmptyContentMinHeight(200) 26 | .InvokeAsync()) 27 |
28 |
29 | 30 |
31 |
32 |

From our blog

33 |
34 | 35 | @await Component.InvokeAsync("HomepageBlogPosts") 36 |
37 |
38 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/PageTemplates/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Cofoundry/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Cofoundry.Samples.SimpleSite 2 | @using Cofoundry.Core 3 | @using Cofoundry.Domain 4 | @using Cofoundry.Web 5 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Models/Authors/AuthorDetails.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Html; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | public class AuthorDetails 6 | { 7 | public required string Name { get; set; } 8 | 9 | public required IHtmlContent Biography { get; set; } 10 | 11 | public ImageAssetRenderDetails? ProfileImage { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Models/BlogPost/BlogPostSummary.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | public class BlogPostSummary 4 | { 5 | public required string Title { get; set; } 6 | 7 | public required string ShortDescription { get; set; } 8 | 9 | public required string? AuthorName { get; set; } 10 | 11 | public ImageAssetRenderDetails? ThumbnailImageAsset { get; set; } 12 | 13 | public required string FullPath { get; set; } 14 | 15 | public required DateTime? PostDate { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Models/BlogPost/SearchBlogPostsQuery.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | /// 4 | /// Inheriting from SimplePageableQuery or IPageableQuery 5 | /// gives us a few extra features when working with pages 6 | /// data via the PagingExtensions set of extension methods. 7 | /// 8 | /// See https://www.cofoundry.org/docs/framework/data-access/paged-queries.cs 9 | /// 10 | public class SearchBlogPostsQuery : SimplePageableQuery 11 | { 12 | public int CategoryId { get; set; } 13 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Models/Categories/CategorySummary.cs: -------------------------------------------------------------------------------- 1 | namespace Cofoundry.Samples.SimpleSite; 2 | 3 | public class CategorySummary 4 | { 5 | public required int CategoryId { get; set; } 6 | 7 | public required string Title { get; set; } 8 | 9 | public required string? ShortDescription { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Models/Contact/ContactRequest.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | public class ContactRequest 6 | { 7 | [Required] 8 | [EmailAddress] 9 | [Display(Name = "Email Address")] 10 | public string EmailAddress { get; set; } = string.Empty; 11 | 12 | [Required] 13 | public string Name { get; set; } = string.Empty; 14 | 15 | [Required] 16 | public string Message { get; set; } = string.Empty; 17 | } 18 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Models/EmailTemplates/ContactRequestMailTemplate.cs: -------------------------------------------------------------------------------- 1 | using Cofoundry.Core.Mail; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | /// 6 | /// Cofoundry includes a framework for sending mail based around template 7 | /// classes and view files rendered using RazorEngine. 8 | /// 9 | /// For more information see https://www.cofoundry.org/docs/framework/mail 10 | /// 11 | public class ContactRequestMailTemplate : IMailTemplate 12 | { 13 | public string ViewFile 14 | { 15 | get 16 | { 17 | return "~/Views/EmailTemplates/ContactRequest"; 18 | } 19 | } 20 | 21 | public string Subject 22 | { 23 | get 24 | { 25 | return "New Contact Request"; 26 | } 27 | } 28 | 29 | public required ContactRequest Request { get; set; } 30 | } 31 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Models/Settings/SimpleSiteSettings.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using Cofoundry.Core.Configuration; 3 | 4 | namespace Cofoundry.Samples.SimpleSite; 5 | 6 | /// 7 | /// Cofoundry includes a system for easily creating strongly typed configuration 8 | /// settings just by defining a POCO class that inherits from IConfigurationSettings. 9 | /// These settings classes are automatically picked up by the DI system and bound 10 | /// to your config source (e.g. web.config/app.config) at runtime. 11 | /// 12 | /// See https://www.cofoundry.org/docs/framework/configuration-settings 13 | /// 14 | public class SimpleSiteSettings : IConfigurationSettings 15 | { 16 | /// 17 | /// Setting Name = SimpleSite:ContactRequestNotificationToAddress 18 | /// 19 | [Required] 20 | [EmailAddress] 21 | public string ContactRequestNotificationToAddress { get; set; } = string.Empty; 22 | } 23 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | builder.Services 4 | .AddMvc() 5 | .AddCofoundry(builder.Configuration); 6 | 7 | var app = builder.Build(); 8 | 9 | app.UseHttpsRedirection(); 10 | app.UseCofoundry(); 11 | 12 | app.Run(); 13 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:60932/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "Cofoundry.Samples.SimpleSite": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:60933" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Cofoundry.Core; 2 | global using Cofoundry.Domain; 3 | global using Cofoundry.Web; 4 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/ViewComponents/BlogPostListViewComponent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | public class BlogPostListViewComponent : ViewComponent 6 | { 7 | private readonly IContentRepository _contentRepository; 8 | private readonly IVisualEditorStateService _visualEditorStateService; 9 | 10 | public BlogPostListViewComponent( 11 | IContentRepository contentRepository, 12 | IVisualEditorStateService visualEditorStateService 13 | ) 14 | { 15 | _contentRepository = contentRepository; 16 | _visualEditorStateService = visualEditorStateService; 17 | } 18 | 19 | public async Task InvokeAsync() 20 | { 21 | var webQuery = ModelBind(); 22 | 23 | // We can use the current visual editor state (e.g. edit mode, live mode) to 24 | // determine whether to show unpublished blog posts in the list. 25 | var visualEditorState = await _visualEditorStateService.GetCurrentAsync(); 26 | var ambientEntityPublishStatusQuery = visualEditorState.GetAmbientEntityPublishStatusQuery(); 27 | 28 | var query = new SearchCustomEntityRenderSummariesQuery() 29 | { 30 | CustomEntityDefinitionCode = BlogPostCustomEntityDefinition.DefinitionCode, 31 | PageNumber = webQuery.PageNumber, 32 | PageSize = 30, 33 | PublishStatus = ambientEntityPublishStatusQuery 34 | }; 35 | 36 | // TODO: Filtering by Category (webQuery.CategoryId) 37 | // Searching/filtering custom entities is not implemented yet, but it 38 | // is possible to build your own search index using the message handling 39 | // framework or writing a custom query against the UnstructuredDataDependency table 40 | // See issue https://github.com/cofoundry-cms/cofoundry/issues/12 41 | 42 | var entities = await _contentRepository 43 | .CustomEntities() 44 | .Search() 45 | .AsRenderSummaries(query) 46 | .ExecuteAsync(); 47 | 48 | var viewModel = await MapBlogPostsAsync(entities, ambientEntityPublishStatusQuery); 49 | 50 | return View(viewModel); 51 | } 52 | 53 | /// 54 | /// ModelBinder is not supported in view components so we have to bind 55 | /// this manually. We have an issue open to try and improve the experience here 56 | /// https://github.com/cofoundry-cms/cofoundry/issues/125 57 | /// 58 | private SearchBlogPostsQuery ModelBind() 59 | { 60 | var webQuery = new SearchBlogPostsQuery(); 61 | webQuery.PageNumber = IntParser.ParseOrDefault(Request.Query[nameof(webQuery.PageNumber)]); 62 | webQuery.PageSize = IntParser.ParseOrDefault(Request.Query[nameof(webQuery.PageSize)]); 63 | webQuery.CategoryId = IntParser.ParseOrDefault(Request.Query[nameof(webQuery.CategoryId)]); 64 | 65 | return webQuery; 66 | } 67 | 68 | /// 69 | /// Here we map the raw custom entity data from Cofoundry into our 70 | /// own BlogPostSummary which will get sent to be rendered in the 71 | /// view. 72 | /// 73 | /// This code is repeated in HomepageBlogPostsViewComponent for 74 | /// simplicity, but typically you'd put the code into a shared 75 | /// mapper or break data access out into it's own shared layer. 76 | /// 77 | private async Task> MapBlogPostsAsync( 78 | PagedQueryResult customEntityResult, 79 | PublishStatusQuery ambientEntityPublishStatusQuery 80 | ) 81 | { 82 | var blogPosts = new List(customEntityResult.Items.Count); 83 | 84 | var imageAssetIds = customEntityResult 85 | .Items 86 | .Select(i => (BlogPostDataModel)i.Model) 87 | .Select(m => m.ThumbnailImageAssetId) 88 | .Distinct(); 89 | 90 | var authorIds = customEntityResult 91 | .Items 92 | .Select(i => (BlogPostDataModel)i.Model) 93 | .Select(m => m.AuthorId) 94 | .Distinct(); 95 | 96 | var imageLookup = await _contentRepository 97 | .ImageAssets() 98 | .GetByIdRange(imageAssetIds) 99 | .AsRenderDetails() 100 | .ExecuteAsync(); 101 | 102 | var authorQuery = new GetCustomEntityRenderSummariesByIdRangeQuery(authorIds, ambientEntityPublishStatusQuery); 103 | var authorLookup = await _contentRepository 104 | .CustomEntities() 105 | .GetByIdRange(authorIds) 106 | .AsRenderSummaries(ambientEntityPublishStatusQuery) 107 | .ExecuteAsync(); 108 | 109 | foreach (var customEntity in customEntityResult.Items) 110 | { 111 | var model = (BlogPostDataModel)customEntity.Model; 112 | var author = authorLookup.GetValueOrDefault(model.AuthorId); 113 | 114 | var blogPost = new BlogPostSummary() 115 | { 116 | Title = customEntity.Title, 117 | ShortDescription = model.ShortDescription, 118 | ThumbnailImageAsset = imageLookup.GetValueOrDefault(model.ThumbnailImageAssetId), 119 | FullPath = customEntity.PageUrls.FirstOrDefault() ?? string.Empty, 120 | PostDate = customEntity.PublishDate, 121 | AuthorName = author?.Title 122 | }; 123 | 124 | blogPosts.Add(blogPost); 125 | } 126 | 127 | return customEntityResult.ChangeType(blogPosts); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/ViewComponents/ContactRequestFormViewComponent.cs: -------------------------------------------------------------------------------- 1 | using Cofoundry.Core.Mail; 2 | using Cofoundry.Core.Validation; 3 | using Microsoft.AspNetCore.Mvc; 4 | 5 | namespace Cofoundry.Samples.SimpleSite; 6 | 7 | public class ContactRequestFormViewComponent : ViewComponent 8 | { 9 | private readonly IMailService _mailService; 10 | private readonly IModelValidationService _modelValidationService; 11 | private readonly SimpleSiteSettings _simpleTestSiteSettings; 12 | 13 | public ContactRequestFormViewComponent( 14 | IMailService mailService, 15 | IModelValidationService modelValidationService, 16 | SimpleSiteSettings simpleTestSiteSettings 17 | ) 18 | { 19 | _mailService = mailService; 20 | _modelValidationService = modelValidationService; 21 | _simpleTestSiteSettings = simpleTestSiteSettings; 22 | } 23 | 24 | public async Task InvokeAsync() 25 | { 26 | var contactRequest = new ContactRequest(); 27 | 28 | // ModelBinder is not supported in view components so we have to bind 29 | // this manually. We have an issue open to try and improve the experience here 30 | // https://github.com/cofoundry-cms/cofoundry/issues/125 31 | 32 | if (Request.Method.Equals("POST", StringComparison.OrdinalIgnoreCase)) 33 | { 34 | var form = await Request.ReadFormAsync(); 35 | contactRequest.Name = ReadFormField(form, nameof(contactRequest.Name)); 36 | contactRequest.EmailAddress = ReadFormField(form, nameof(contactRequest.EmailAddress)); 37 | contactRequest.Message = ReadFormField(form, nameof(contactRequest.Message)); 38 | 39 | ValidateModel(contactRequest); 40 | 41 | if (ModelState.IsValid) 42 | { 43 | // Send admin confirmation 44 | var template = new ContactRequestMailTemplate 45 | { 46 | Request = contactRequest 47 | }; 48 | 49 | await _mailService.SendAsync(_simpleTestSiteSettings.ContactRequestNotificationToAddress, template); 50 | 51 | return View("ContactSuccess"); 52 | } 53 | } 54 | 55 | return View(contactRequest); 56 | } 57 | 58 | private static string ReadFormField(IFormCollection form, string fieldName) 59 | { 60 | var value = form[fieldName]; 61 | return StringHelper.NullAsEmptyAndTrim(value); 62 | } 63 | 64 | /// 65 | /// Because model binding isn't supported in view components, we have to 66 | /// manually validate the model. 67 | /// 68 | private void ValidateModel(TModel model) 69 | { 70 | var errors = _modelValidationService.GetErrors(model); 71 | 72 | foreach (var error in errors) 73 | { 74 | var property = error.Properties.FirstOrDefault() ?? string.Empty; 75 | ModelState.AddModelError(property, error.Message); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/ViewComponents/HomepageBlogPostsViewComponent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | public class HomepageBlogPostsViewComponent : ViewComponent 6 | { 7 | private readonly IContentRepository _contentRepository; 8 | private readonly IVisualEditorStateService _visualEditorStateService; 9 | 10 | public HomepageBlogPostsViewComponent( 11 | IContentRepository contentRepository, 12 | IVisualEditorStateService visualEditorStateService 13 | ) 14 | { 15 | _contentRepository = contentRepository; 16 | _visualEditorStateService = visualEditorStateService; 17 | } 18 | 19 | public async Task InvokeAsync() 20 | { 21 | // We can use the current visual editor state (e.g. edit mode, live mode) to 22 | // determine whether to show unpublished blog posts in the list. 23 | var visualEditorState = await _visualEditorStateService.GetCurrentAsync(); 24 | var ambientEntityPublishStatusQuery = visualEditorState.GetAmbientEntityPublishStatusQuery(); 25 | 26 | var query = new SearchCustomEntityRenderSummariesQuery() 27 | { 28 | CustomEntityDefinitionCode = BlogPostCustomEntityDefinition.DefinitionCode, 29 | PageSize = 3, 30 | PublishStatus = ambientEntityPublishStatusQuery 31 | }; 32 | 33 | var entities = await _contentRepository 34 | .CustomEntities() 35 | .Search() 36 | .AsRenderSummaries(query) 37 | .ExecuteAsync(); 38 | 39 | var viewModel = await MapBlogPostsAsync(entities, ambientEntityPublishStatusQuery); 40 | 41 | return View(viewModel); 42 | } 43 | 44 | /// 45 | /// Here we map the raw custom entity data from Cofoundry into our 46 | /// own BlogPostSummary which will get sent to be rendered in the 47 | /// view. 48 | /// 49 | /// This code is repeated in BlogPostListViewComponent for 50 | /// simplicity, but typically you'd put the code into a shared 51 | /// mapper or break data access out into it's own shared layer. 52 | /// 53 | private async Task> MapBlogPostsAsync( 54 | PagedQueryResult customEntityResult, 55 | PublishStatusQuery ambientEntityPublishStatusQuery 56 | ) 57 | { 58 | var blogPosts = new List(customEntityResult.Items.Count); 59 | 60 | var imageAssetIds = customEntityResult 61 | .Items 62 | .Select(i => (BlogPostDataModel)i.Model) 63 | .Select(m => m.ThumbnailImageAssetId) 64 | .Distinct(); 65 | 66 | var authorIds = customEntityResult 67 | .Items 68 | .Select(i => (BlogPostDataModel)i.Model) 69 | .Select(m => m.AuthorId) 70 | .Distinct(); 71 | 72 | var imageLookup = await _contentRepository 73 | .ImageAssets() 74 | .GetByIdRange(imageAssetIds) 75 | .AsRenderDetails() 76 | .ExecuteAsync(); 77 | 78 | var authorLookup = await _contentRepository 79 | .CustomEntities() 80 | .GetByIdRange(authorIds) 81 | .AsRenderSummaries(ambientEntityPublishStatusQuery) 82 | .ExecuteAsync(); 83 | 84 | foreach (var customEntity in customEntityResult.Items) 85 | { 86 | var model = (BlogPostDataModel)customEntity.Model; 87 | var author = authorLookup.GetValueOrDefault(model.AuthorId); 88 | 89 | var blogPost = new BlogPostSummary() 90 | { 91 | Title = customEntity.Title, 92 | ShortDescription = model.ShortDescription, 93 | ThumbnailImageAsset = imageLookup.GetValueOrDefault(model.ThumbnailImageAssetId), 94 | FullPath = customEntity.PageUrls.FirstOrDefault() ?? string.Empty, 95 | PostDate = customEntity.PublishDate, 96 | AuthorName = author?.Title 97 | }; 98 | 99 | blogPosts.Add(blogPost); 100 | } 101 | 102 | return customEntityResult.ChangeType(blogPosts); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/ViewComponents/SidebarCategoriesViewComponent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Cofoundry.Samples.SimpleSite; 4 | 5 | public class SidebarCategoriesViewComponent : ViewComponent 6 | { 7 | private readonly IContentRepository _contentRepository; 8 | private readonly IVisualEditorStateService _visualEditorStateService; 9 | 10 | public SidebarCategoriesViewComponent( 11 | IContentRepository contentRepository, 12 | IVisualEditorStateService visualEditorStateService 13 | ) 14 | { 15 | _contentRepository = contentRepository; 16 | _visualEditorStateService = visualEditorStateService; 17 | } 18 | 19 | public async Task InvokeAsync() 20 | { 21 | // We can use the current visual editor state (e.g. edit mode, live mode) to 22 | // determine whether to show unpublished categories in the list. 23 | var visualEditorState = await _visualEditorStateService.GetCurrentAsync(); 24 | 25 | var query = new SearchCustomEntityRenderSummariesQuery() 26 | { 27 | CustomEntityDefinitionCode = CategoryCustomEntityDefinition.DefinitionCode, 28 | PageSize = 20, 29 | PublishStatus = visualEditorState.GetAmbientEntityPublishStatusQuery() 30 | }; 31 | 32 | var pagedCategories = await _contentRepository 33 | .CustomEntities() 34 | .Search() 35 | .AsRenderSummaries(query) 36 | .MapItem(MapCategory) 37 | .ExecuteAsync(); 38 | 39 | return View(pagedCategories.Items); 40 | } 41 | 42 | private CategorySummary MapCategory(CustomEntityRenderSummary customEntity) 43 | { 44 | var model = (CategoryDataModel)customEntity.Model; 45 | 46 | var category = new CategorySummary() 47 | { 48 | CategoryId = customEntity.CustomEntityId, 49 | Title = customEntity.Title, 50 | ShortDescription = model.ShortDescription 51 | }; 52 | 53 | return category; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/EmailTemplates/ContactRequest_html.cshtml: -------------------------------------------------------------------------------- 1 | @model ContactRequestMailTemplate 2 | 3 | @{ 4 | Layout = null; 5 | } 6 | 7 |

@Model.Subject

8 |

9 | This request came with the following information: 10 |

11 |

12 | Name: @Model.Request.Name 13 |
14 | Email: @Model.Request.EmailAddress 15 |
16 | Message: @Model.Request.Message 17 |

-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/EmailTemplates/ContactRequest_text.cshtml: -------------------------------------------------------------------------------- 1 | @model ContactRequestMailTemplate 2 | 3 | @{ 4 | Layout = null; 5 | } 6 | 7 | @Model.Subject 8 | 9 | This request came with the following information: 10 | 11 | ------------------------------------------------- 12 | Name: @Model.Request.Name 13 | 14 | Email: @Model.Request.EmailAddress 15 | 16 | Message: @Model.Request.Message 17 | -------------------------------------------------- 18 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/Components/BlogPostList/Default.cshtml: -------------------------------------------------------------------------------- 1 | @model PagedQueryResult 2 | @inject ICofoundryHelper Cofoundry 3 | 4 | @{ 5 | Layout = null; 6 | } 7 | 8 | @foreach (var blogPost in Model.Items) 9 | { 10 | var postDateText = blogPost.PostDate.HasValue ? blogPost.PostDate.Value.ToString("dd MMM yyyy") : "Not published"; 11 | 12 |
13 |
14 | 15 | 16 | 17 |
18 |
19 |

@blogPost.Title

20 | 21 | @postDateText 22 | @if (!string.IsNullOrWhiteSpace(blogPost.AuthorName)) 23 | { 24 | by @blogPost.AuthorName 25 | } 26 | 27 |

@blogPost.ShortDescription

28 | Read post 29 |
30 |
31 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/Components/ContactRequestForm/ContactSuccess.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = null; 3 | } 4 |

Thank you

5 |

We'll be in touch soon!

-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/Components/ContactRequestForm/Default.cshtml: -------------------------------------------------------------------------------- 1 | @model ContactRequest 2 | 3 | @{ 4 | Layout = null; 5 | } 6 | 7 |
8 | 9 | @Html.AntiForgeryToken() 10 | 11 |
12 | @Html.LabelFor(m => m.Name) 13 | @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "Name" }) 14 | @Html.ValidationMessageFor(m => m.Name) 15 |
16 | 17 |
18 | @Html.LabelFor(m => m.EmailAddress) 19 | @Html.TextBoxFor(m => m.EmailAddress, new { @class = "form-control", placeholder = "Email", @type = "Email" }) 20 | @Html.ValidationMessageFor(m => m.EmailAddress) 21 |
22 | 23 |
24 | @Html.LabelFor(m => m.Message) 25 | @Html.TextAreaFor(m => m.Message, new { @class = "form-control", placeholder = "Message", rows = "8" }) 26 | @Html.ValidationMessageFor(m => m.Message) 27 |
28 | 29 | 30 |
-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/Components/HomepageBlogPosts/Default.cshtml: -------------------------------------------------------------------------------- 1 | @model PagedQueryResult 2 | 3 | @{ 4 | Layout = null; 5 | } 6 | 7 | @foreach (var blogPost in Model.Items) 8 | { 9 | 10 |
11 |
12 |

@blogPost.Title

13 |

@blogPost.ShortDescription

14 | Read more 15 |
16 |
17 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/Components/SidebarCategories/Default.cshtml: -------------------------------------------------------------------------------- 1 | @model ICollection 2 | 3 | @{ 4 | Layout = null; 5 | } 6 | 7 |

Categories

8 |
    9 | @foreach (var category in Model) 10 | { 11 |
  • @category.Title
  • 12 | } 13 |
-------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model IErrorPageViewModel 2 | 3 | @{ 4 | var title = "A Custom Error Page"; 5 | ViewBag.Title = title; 6 | } 7 | 8 | 9 |
10 |
11 |
12 |

@title

13 |
14 |
15 | 16 |
17 |
18 | 19 |

@Model.StatusCodeDescription

20 | 21 |

Sorry, there has been an error

22 |

Please press back and try again. If the error persists then then please contact us.

23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/NotFound.cshtml: -------------------------------------------------------------------------------- 1 | @model INotFoundPageViewModel 2 | 3 | @{ 4 | var title = "A Custom 404 Page"; 5 | ViewBag.Title = title; 6 | } 7 | 8 | 9 |
10 |
11 |
12 |

@title

13 |
14 |
15 | 16 |
17 |
18 |

19 | Sorry, that page could not be found 20 |

21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @inject ICofoundryHelper Cofoundry 2 | 3 | @{ 4 | Layout = null; 5 | 6 | string? title = null; 7 | string? description = null; 8 | 9 | var metaDataModel = Model as IPageWithMetaDataViewModel; 10 | if (metaDataModel != null) 11 | { 12 | description = metaDataModel.MetaDescription; 13 | title = metaDataModel.PageTitle; 14 | } 15 | else 16 | { 17 | description = "Develop With Cofoundry"; 18 | } 19 | 20 | title = StringHelper.FirstNotNullOrWhitespace(title, "Develop With Cofoundry"); 21 | title += " | Simple Site"; 22 | } 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | @title 32 | 33 | 34 | 35 | @RenderSection("Meta", required: false) 36 | @if (IsSectionDefined("OpenGraph")) 37 | { 38 | @RenderSection("OpenGraph") 39 | } 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 70 | 71 |
72 | @RenderBody() 73 |
74 | 75 | 88 | 89 |
90 |
91 |
92 |
93 | Copyright © @DateTime.UtcNow.Year Example Inc. All Rights Reserved 94 |
95 |
96 | 100 |
101 |
102 |
103 |
104 | 105 | 106 | 107 | 108 | @if (IsSectionDefined("FooterScripts")) 109 | { 110 | @RenderSection("FooterScripts") 111 | } 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Cofoundry.Samples.SimpleSite 2 | @using Cofoundry.Core 3 | @using Cofoundry.Domain 4 | @using Cofoundry.Web 5 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | 10 | "SimpleSite": { 11 | "ContactRequestNotificationToAddress": "contact-requests@example.com" 12 | }, 13 | 14 | "Cofoundry": { 15 | 16 | "Database": { 17 | "ConnectionString": "Server=.\\sqlexpress;Database=Cofoundry.Samples.SimpleSite;Integrated Security=True;Encrypt=False;MultipleActiveResultSets=True" 18 | }, 19 | 20 | "Mail": { 21 | "DefaultFromAddress": "auto@example.com" 22 | }, 23 | 24 | "SmtpMail": { 25 | "DebugMailDropDirectory": "~/App_Data/Mail" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/wwwroot/css/style.css: -------------------------------------------------------------------------------- 1 | /* See https://gist.github.com/taupecat/4090271 */ 2 | /* Cross browser Opacity */ 3 | /* Non-inheriting cross browser opacity with white bg color */ 4 | body { 5 | padding-top: 60px; 6 | } 7 | 8 | a { 9 | color: #DC3522; 10 | } 11 | 12 | .navbar { 13 | background-color: #1E1E20; 14 | border: 0; 15 | height: 60px; 16 | } 17 | 18 | .navbar-toggle { 19 | margin-top: 12px; 20 | } 21 | 22 | .navbar-default .navbar-collapse { 23 | border: 0; 24 | background-color: #374140; 25 | } 26 | 27 | @media screen and (min-width: 48em) { 28 | .navbar-default .navbar-collapse { 29 | background-color: transparent; 30 | } 31 | } 32 | 33 | .navbar-header { 34 | height: 60px; 35 | } 36 | 37 | .navbar__menu { 38 | list-style-type: none; 39 | padding-left: 0; 40 | } 41 | 42 | .navbar__menu li { 43 | padding: 10px 0; 44 | } 45 | 46 | .navbar__menu a { 47 | color: white; 48 | display: block; 49 | } 50 | 51 | @media screen and (min-width: 48em) { 52 | .navbar__menu { 53 | float: right; 54 | } 55 | 56 | .navbar__menu li { 57 | display: inline-block; 58 | line-height: 60px; 59 | padding: 0; 60 | } 61 | 62 | .navbar__menu li:hover { 63 | background-color: #2A2C2B; 64 | } 65 | 66 | .navbar__menu a { 67 | padding: 0 15px; 68 | } 69 | } 70 | 71 | .main { 72 | padding-bottom: 30px; 73 | } 74 | 75 | @media screen and (min-width: 48em) { 76 | .main { 77 | padding-bottom: 80px; 78 | } 79 | } 80 | 81 | .content-block img { 82 | margin-top: 20px; 83 | } 84 | 85 | @media screen and (min-width: 48em) { 86 | .content-block { 87 | margin-top: 30px; 88 | } 89 | } 90 | 91 | .hero-banner { 92 | width: 100%; 93 | height: 300px; 94 | overflow: hidden; 95 | position: relative; 96 | } 97 | 98 | .hero-banner img { 99 | position: absolute; 100 | left: 50%; 101 | top: 50%; 102 | width: auto; 103 | height: 100%; 104 | transform: translate(-50%, -50%); 105 | } 106 | 107 | @media screen and (min-width: 31.25em) { 108 | .hero-banner img { 109 | left: 0; 110 | width: 100%; 111 | height: auto; 112 | transform: translateY(-50%); 113 | } 114 | } 115 | 116 | @media screen and (min-width: 50em) { 117 | .hero-banner { 118 | height: 450px; 119 | } 120 | } 121 | 122 | .hero-banner__overlay { 123 | position: relative; 124 | height: 100%; 125 | } 126 | 127 | .hero-banner__text { 128 | position: absolute; 129 | left: 0; 130 | top: 50%; 131 | transform: translateY(-50%); 132 | color: white; 133 | padding-left: 15px; 134 | } 135 | 136 | .blog-cards h2 { 137 | margin-bottom: 20px; 138 | } 139 | 140 | @media screen and (min-width: 48em) { 141 | .blog-cards { 142 | margin-top: 30px; 143 | } 144 | 145 | .blog-cards h2 { 146 | text-align: center; 147 | margin-bottom: 30px; 148 | } 149 | } 150 | 151 | .blog-cards__card { 152 | background-color: #1E1E20; 153 | color: white; 154 | padding: 30px; 155 | margin-bottom: 20px; 156 | } 157 | 158 | .blog-cards__card h3 { 159 | margin-top: 0; 160 | } 161 | 162 | .blog-cards__card p:last-of-type { 163 | margin-bottom: 20px; 164 | } 165 | 166 | @media screen and (min-width: 48em) { 167 | .blog-cards__card { 168 | margin-bottom: 0; 169 | } 170 | } 171 | 172 | .blog-teaser { 173 | margin-bottom: 30px; 174 | } 175 | 176 | .blog-teaser__image img { 177 | display: block; 178 | width: 100%; 179 | height: auto; 180 | } 181 | 182 | .blog-teaser__text { 183 | background-color: #1E1E20; 184 | padding: 30px; 185 | color: white; 186 | } 187 | 188 | .blog-teaser__text h2 { 189 | margin-top: 0; 190 | } 191 | 192 | .list-group, .list-group--alt { 193 | list-style-type: none; 194 | padding: 0; 195 | } 196 | 197 | .list-group li, .list-group--alt li { 198 | display: inline-block; 199 | background-color: #DC3522; 200 | padding: 5px 10px; 201 | border-radius: 10px; 202 | margin-bottom: 5px; 203 | } 204 | 205 | .list-group a, .list-group--alt a { 206 | color: #D9CB9E; 207 | } 208 | 209 | .list-group--alt li { 210 | background-color: #2A2C2B; 211 | } 212 | 213 | 214 | .blog-article-author { 215 | background-color: #eee; 216 | margin: 30px 0; 217 | padding: 0 20px 20px 20px; 218 | display: flex; 219 | flex-direction: column; 220 | border-radius: 3px; 221 | } 222 | 223 | .blog-article-author-image { 224 | width: 80px; 225 | margin-right: 20px; 226 | margin: 0 auto; 227 | flex-shrink: 0; 228 | } 229 | 230 | .blog-article-author-content { 231 | } 232 | 233 | .blog-article-author-image img { 234 | border-radius: 300px; 235 | } 236 | 237 | @media screen and (min-width: 48em) { 238 | 239 | .blog-article-author { 240 | flex-direction: row; 241 | margin: 30px; 242 | } 243 | 244 | .blog-article-author-image { 245 | margin-right: 20px; 246 | width: 60px; 247 | } 248 | 249 | } 250 | 251 | .product { 252 | margin-bottom: 30px; 253 | } 254 | 255 | .product__image { 256 | width: 100%; 257 | padding-bottom: 100%; 258 | overflow: hidden; 259 | position: relative; 260 | } 261 | 262 | .product__image img { 263 | position: absolute; 264 | left: 50%; 265 | top: 50%; 266 | width: 100%; 267 | transform: translate(-50%, -50%); 268 | } 269 | 270 | .product__details { 271 | margin-top: 10px; 272 | } 273 | 274 | .product__details .name { 275 | color: #374140; 276 | } 277 | 278 | .product__details .price { 279 | color: #1E1E20; 280 | float: right; 281 | } 282 | 283 | .product-images { 284 | position: relative; 285 | } 286 | 287 | .product-images img { 288 | display: block; 289 | width: 100%; 290 | height: auto; 291 | margin-bottom: 20px; 292 | } 293 | 294 | .product-info { 295 | position: relative; 296 | } 297 | 298 | .product-info .price { 299 | display: block; 300 | font-weight: bold; 301 | font-size: 20px; 302 | margin-bottom: 20px; 303 | } 304 | 305 | .breadcrumb { 306 | margin-top: 20px; 307 | } 308 | 309 | .newsletter-signup { 310 | background-color: #374140; 311 | padding: 30px 0; 312 | text-align: center; 313 | } 314 | 315 | .newsletter-signup .glyphicon { 316 | color: white; 317 | font-size: 35px; 318 | line-height: 30px; 319 | position: absolute; 320 | left: 0; 321 | top: -2px; 322 | } 323 | 324 | .newsletter-signup h2 { 325 | color: white; 326 | font-weight: 400; 327 | font-size: 20px; 328 | position: relative; 329 | padding-left: 50px; 330 | display: inline-block; 331 | } 332 | 333 | .newsletter-signup form { 334 | margin-top: 30px; 335 | } 336 | 337 | .footer { 338 | background-color: #1E1E20; 339 | color: white; 340 | padding: 30px 0; 341 | } 342 | 343 | .footer__links { 344 | list-style-type: none; 345 | float: right; 346 | } 347 | 348 | .footer__links li { 349 | display: inline-block; 350 | margin: 0 10px; 351 | } 352 | 353 | .footer__links a { 354 | color: white; 355 | } 356 | 357 | .footer__links a:hover { 358 | color: #DC3522; 359 | } 360 | 361 | .logo { 362 | color: white; 363 | font-size: 20px; 364 | margin-left: 10px; 365 | margin-top: 15px; 366 | display: inline-block; 367 | } 368 | 369 | .logo:hover { 370 | text-decoration: none; 371 | color: white; 372 | } 373 | -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/src/Cofoundry.Samples.SimpleSite/wwwroot/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/wwwroot/images/hero-banner-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cofoundry-cms/Cofoundry.Samples.SimpleSite/e3917baee26d7e42660fb8a0393f893e15f05e04/src/Cofoundry.Samples.SimpleSite/wwwroot/images/hero-banner-bg.jpg -------------------------------------------------------------------------------- /src/Cofoundry.Samples.SimpleSite/wwwroot/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under the MIT license 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); --------------------------------------------------------------------------------