├── .gitignore ├── LICENSE.md ├── README.md ├── config.yaml ├── config_template.yaml ├── console ├── err.html └── warn.html ├── data └── netlifycms │ └── fields │ ├── body.yaml │ ├── date.yaml │ ├── description.yaml │ ├── image.yaml │ ├── slug.yaml │ └── title.yaml ├── go.mod ├── partials ├── private │ ├── GetCMSVersion.html │ ├── GetConfig.html │ ├── GetModuleConfig.html │ ├── go.html │ ├── import.html │ └── parse.html └── scripts.html └── templates ├── single.html.html ├── single.netlifycms_config.yml └── single.netlifycms_debug.html /.gitignore: -------------------------------------------------------------------------------- 1 | # OS 2 | .DS_Store 3 | Thumbs.db 4 | 5 | # IDEs 6 | .buildpath 7 | .project 8 | .settings/ 9 | .build/ 10 | .idea/ 11 | nbproject/ 12 | public 13 | 14 | # Vagrant 15 | .vagrant/ 16 | 17 | # FE Setup 18 | .bin/node_modules/ 19 | /node_modules/ 20 | /npm-debug.log.* 21 | /npm-debug.log 22 | /npm-debug.log* 23 | /dist/ 24 | /src/client.config.json 25 | /docs/ 26 | 27 | /junit.xml 28 | partials/structure/stylesheet.html 29 | 30 | # Hugo 31 | hugo_stats.json 32 | resources 33 | public 34 | 35 | # Local Netlify folder 36 | .netlify -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 the New Dynamic 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 | # TND NetlifyCMS Hugo Module 2 | 3 | This module try to simplify the construct of Netlify CMS lone config file. It also sets up the Netlify CMS page wherever on the project with minimal user intervention. 4 | 5 | In order to be able to reuse data objects inside the lone NetlifyCMS `config.yaml` file, this module makes use of Hugo's data file to store said data objects and allow them to be recursively imported in the configuration file. 6 | 7 | ## Requirements 8 | 9 | Requirements: 10 | - Go 1.14 11 | - Hugo 0.61.0 12 | 13 | ## Installation 14 | 15 | If not already, [init](https://gohugo.io/hugo-modules/use-modules/#initialize-a-new-module) your project as Hugo Module: 16 | 17 | ``` 18 | $: hugo mod init {repo_url} 19 | ``` 20 | 21 | Configure your project's module to import this module: 22 | 23 | ```yaml 24 | # config.yaml 25 | module: 26 | imports: 27 | - path: github.com/theNewDynamic/hugo-module-tnd-netlifycms 28 | ``` 29 | 30 | ## Usage 31 | 32 | ### Adding to your project 33 | 34 | 1. Add this module's path to your `module.imports` config array 35 | ``` 36 | module: 37 | imports: 38 | - path: github.com/theNewDynamic/hugo-module-tnd-netlifycms 39 | ``` 40 | 1. Create a page where your Netlify CMS dashboard should live. 41 | 2. Add the `netlifycms` type to it through Front Matter. 42 | 3. Add the `netlifycms_config` output format to it through Front Matter (alongside HTML): 43 | ```yaml 44 | Title: Your CMS 45 | type: netlifycms 46 | outputs: 47 | - HTML 48 | - netlifycms_config 49 | ``` 50 | 4. Add your Netlify config data in `data/netlifycms/config.yaml` and use (or not) `import` statements. 51 | 5. Add the data files matching your imports statements to the `data/netlifycms` dir under `/collections` and `/fields` 52 | 53 | ### Import and Extend data sets 54 | 55 | NetlifyCMS uses yaml extensively. In order to avoid a lot of copy/paste the module allow to import a data set stored in `data/netlifycms/**/*.yaml` as part of a yaml array. 56 | 57 | It's also possible to extend/overwrite the data found in the file. 58 | 59 | #### Import 60 | 61 | From inside a `yaml` array, you can either use the string import statement, or the map import statement. 62 | 63 | `- import collection pages` or `- import: collection pages` 64 | 65 | #### Extend 66 | 67 | By using the map version of the import statement, you can add an extra `extend` key containing a map with values the add or overwrite: 68 | 69 | ```yaml 70 | - import: collection pages 71 | extend: 72 | name: Pages FR 73 | folder: content/fr 74 | ``` 75 | See example below of usage. 76 | 77 | ### Example of the base config data file 78 | 79 | ```yaml 80 | # data/netlifycms/config.yaml 81 | backend: 82 | name: git-gateway 83 | branch: easier-netlify-cms 84 | collections: 85 | - import collection events #--> data/netlifycms/collections/pages.yaml 86 | - import collection posts #--> data/netlifycms/collections/posts.yaml 87 | - import: collection posts 88 | extend: 89 | name: updates 90 | label: News Updates 91 | folder: content/updates 92 | ``` 93 | 94 | Above, the Events and Posts collections are stored in the mentioned data file. As we import the data as is, we can use a simple `import` statement. 95 | 96 | For updates, we need almost the same settings and fields as the Post collection, except for a few keys that need to be overwritten. 97 | We can use a map with two keys: 98 | - import: For the statement 99 | - extend: The data which will be added/merged on top of the 100 | data set. 101 | 102 | 103 | ### Example of a Collection data file 104 | 105 | ```yaml 106 | # data/netlifycms/collections/posts.yaml 107 | name: "events" 108 | label: "Events" 109 | folder: "content/events" 110 | create: true 111 | fields: 112 | - import field title #--> data/netlifycms/fields/title.yaml 113 | - import field authors #--> data/netlifycms/fields/authors.yaml 114 | - import field date #--> data/netlifycms/fields/date.yaml 115 | - import field images #--> data/netlifycms/fields/images.yaml 116 | - import field body #--> data/netlifycms/fields/body.yaml 117 | - import: field time #--> data/netlifycms/fields/time.yaml 118 | extend: 119 | name: start_time 120 | label: Start 121 | - import: field time 122 | extend: 123 | name: end_time 124 | label: End 125 | - { 126 | label: "Tags", 127 | name: "tags", 128 | widget: "list", 129 | field: 130 | { 131 | label: "Tag", 132 | widget: "string", 133 | }, 134 | } 135 | ``` 136 | 137 | Above we can see that regular handwritten data and import statements, as well as extending data can perfectly coexist among the same array. 138 | 139 | It is convenient to create a "base" field like `time.yaml` on which to extend special data. This way, the two fields storing a "Start" and an "End" time can use the same base of settings for date and time formating while retaining their own `name` and `label`. 140 | 141 | ### Examples of a Field data file 142 | 143 | ```yaml 144 | # data/netlifycms/fields/title.yaml 145 | label: "Title" 146 | name: "title" 147 | widget: "string" 148 | ``` 149 | 150 | ```yaml 151 | # data/netlifycms/fields/time.yaml 152 | label: "Time" 153 | name: "time" 154 | widget: "datetime" 155 | default: "" 156 | dateFormat: "DD.MM.YYYY" # e.g. 24.12.2021 157 | timeFormat: "HH:mm" # e.g. 21:07 158 | format: "LLL" 159 | pickerUtc: false 160 | ``` 161 | 162 | ### Settings 163 | 164 | Module settings are set as part of the shared `data/netlifycms/config.yaml` file under the reserved `tnd_netlifycms` map key. 165 | 166 | Available settings are: 167 | - cms_version (default: `^2.0.0`): Semantic versioning string to be used when calling CDN endpoint. 168 | 169 | ## Scripts 170 | 171 | The module facilitates the addition of extra Netlify CMS scripts for WidgetPreviews, CollectionPreviews etc... 172 | 173 | By default the module prints the content of any `assets/netlifycms.js` file found inside a ` 201 | ``` 202 | 203 | ## theNewDynamic 204 | 205 | This project is maintained and loved by [thenewDynamic](https://www.thenewdynamic.com). -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | module: 2 | hugoVersion: 3 | min: "0.64.0" 4 | mounts: 5 | - source: data 6 | target: data 7 | - source: templates 8 | target: layouts/netlifycms 9 | - source: partials 10 | target: layouts/partials/tnd-netlifycms 11 | - source: console 12 | target: layouts/partials/tnd-netlifycms 13 | outputFormats: 14 | netlifycms_debug: 15 | baseName: config 16 | isPlainText: true 17 | mediatype: text/html 18 | notAlternative: false 19 | netlifycms_config: 20 | baseName: config 21 | isPlainText: true 22 | mediatype: application/yaml 23 | notAlternative: false 24 | mediaTypes: 25 | application/yaml: 26 | suffixes: 27 | - yml -------------------------------------------------------------------------------- /config_template.yaml: -------------------------------------------------------------------------------- 1 | backend: 2 | name: git-gateway 3 | branch: 58b-testing-netlify-cms # Branch to update (optional; defaults to master) 4 | publish_mode: editorial_workflow 5 | show_preview_links: true 6 | local_backend: true 7 | use_graphql: true 8 | media_folder: static/uploads 9 | public_folder: /uploads 10 | site_url: "https://deploy-preview-62--aaldef.netlify.com" 11 | slug: 12 | encoding: "ascii" 13 | clean_accents: true 14 | sanitize_replacement: "_" 15 | 16 | collections: 17 | - name: "pages" 18 | label: "Pages" 19 | files: 20 | - name: "home-page" 21 | label: "Home Page" 22 | file: "content/_index.md" 23 | fields: 24 | - { label: "Title", name: "title", widget: "string" } 25 | - { 26 | label: "Description", 27 | name: "description", 28 | widget: "markdown", 29 | required: false, 30 | } 31 | - label: "Page Sections" 32 | name: "page_sections" 33 | widget: "list" 34 | types: 35 | - label: "Events Section" 36 | name: "events-section" 37 | widget: "object" 38 | fields: 39 | - { 40 | label: "Type", 41 | name: "type", 42 | widget: "hidden", 43 | default: "events-section", 44 | } 45 | - { 46 | label: "Template", 47 | name: template, 48 | widget: "hidden", 49 | default: "partial-block-events", 50 | } 51 | - { 52 | label: "Block", 53 | name: "block", 54 | widget: "hidden", 55 | default: "events", 56 | } 57 | - { 58 | label: "Number of Past Events", 59 | name: "number_of_past_events", 60 | widget: "number", 61 | } 62 | - { 63 | label: "Events Label", 64 | name: "events_label", 65 | widget: "string", 66 | } 67 | - { 68 | label: "Past Events Label", 69 | name: "past_events_label", 70 | widget: "string", 71 | } 72 | - label: "Updates Section" 73 | name: "updates-section" 74 | widget: "object" 75 | fields: 76 | - { 77 | label: "Type", 78 | name: "type", 79 | widget: "hidden", 80 | default: "updates-section", 81 | } 82 | - { 83 | label: "Template", 84 | name: template, 85 | widget: "hidden", 86 | default: "partial-block-updates", 87 | } 88 | - { 89 | label: "Block", 90 | name: "block", 91 | widget: "hidden", 92 | default: "updates", 93 | } 94 | - label: "Sections" 95 | name: "sections" 96 | widget: "list" 97 | types: 98 | - label: "Section" 99 | name: "sub-section" 100 | widget: "object" 101 | fields: 102 | - { 103 | label: "Type", 104 | name: "type", 105 | widget: "hidden", 106 | default: "sub-section", 107 | } 108 | - { 109 | label: "Section Label", 110 | name: "section_label", 111 | widget: "string", 112 | } 113 | - { 114 | label: "Section", 115 | name: "section", 116 | widget: "select", 117 | options: ["news", "press-release", "blog"], 118 | } 119 | - { 120 | label: "Number of Posts", 121 | name: "number_of_posts", 122 | widget: "number", 123 | } 124 | - label: "Past Events Section" 125 | name: "past-events-section" 126 | widget: "object" 127 | fields: 128 | - { 129 | label: "Type", 130 | name: "type", 131 | widget: "hidden", 132 | default: "past-events-section", 133 | } 134 | - { 135 | label: "Template", 136 | name: template, 137 | widget: "hidden", 138 | default: "partial-block-events-past", 139 | } 140 | - { 141 | label: "Block", 142 | name: "block", 143 | widget: "hidden", 144 | default: "events-past", 145 | } 146 | - { 147 | label: "Number of Past Events", 148 | name: "number_of_past_events", 149 | widget: "number", 150 | } 151 | - { 152 | label: "Past Events Label", 153 | name: "past_events_label", 154 | widget: "string", 155 | } 156 | 157 | - name: "contact-page" 158 | label: "Contact Page" 159 | file: "content/contact-us.md" 160 | fields: 161 | - { label: "Title", name: "title", widget: "string" } 162 | - { 163 | label: "Description", 164 | name: "description", 165 | widget: "markdown", 166 | required: false, 167 | } 168 | - label: "Images" 169 | name: "images" 170 | widget: "list" 171 | fields: 172 | - label: "Image" 173 | name: "image" 174 | widget: "image" 175 | - label: "Credit" 176 | name: "credit" 177 | widget: "string" 178 | - label: "Caption" 179 | name: "caption" 180 | widget: "string" 181 | - { 182 | label: "Authors", 183 | name: "authors", 184 | widget: "list", 185 | field: 186 | { 187 | label: "Author", 188 | widget: "relation", 189 | collection: "authors", 190 | searchFields: "title", 191 | valueField: "title", 192 | }, 193 | } 194 | - { 195 | label: "Related Programs", 196 | name: "related_programs", 197 | widget: "list", 198 | field: 199 | { 200 | label: "Program", 201 | widget: "relation", 202 | collection: "programs", 203 | searchFields: "title", 204 | valueField: "title", 205 | }, 206 | } 207 | - { 208 | label: "Link to Original", 209 | name: "link_to_original", 210 | widget: "string", 211 | required: false, 212 | } 213 | - label: "SEO" 214 | name: "seo" 215 | widget: "object" 216 | fields: 217 | - { 218 | label: "Image", 219 | name: "image", 220 | widget: "image", 221 | required: false, 222 | } 223 | - { 224 | label: "Description", 225 | name: "description", 226 | widget: "markdown", 227 | required: false, 228 | } 229 | - { label: "Body", name: "body", widget: "markdown", required: false } 230 | - name: "search-page" 231 | label: "Search Page" 232 | file: "content/search.md" 233 | fields: 234 | - { label: "Title", name: "title", widget: "string" } 235 | - name: "thank-you-page" 236 | label: "Thank You Page" 237 | file: "content/thank-you.md" 238 | fields: 239 | - { label: "Title", name: "title", widget: "string" } 240 | - { label: "Body", name: "body", widget: "markdown", required: false } 241 | - name: "unity-map" 242 | label: "Unity Map" 243 | file: "content/unity-map.md" 244 | fields: 245 | - { label: "Title", name: "title", widget: "string" } 246 | - { label: "Body", name: "body", widget: "markdown", required: false } 247 | - name: "about-page" 248 | label: "About Page" 249 | file: "content/about/_index.md" 250 | fields: 251 | - { label: "Title", name: "title", widget: "string" } 252 | - { label: "Link Title", name: "linkTitle", widget: "string" } 253 | - { 254 | label: "Aliases", 255 | name: "aliases", 256 | widget: "list", 257 | field: { label: "Alias", widget: "string" }, 258 | } 259 | - { 260 | label: "Description", 261 | name: "description", 262 | widget: "text", 263 | required: false, 264 | } 265 | - { 266 | label: "Images", 267 | name: "images", 268 | widget: "list", 269 | field: { label: "Image", name: "image", widget: "image" }, 270 | } 271 | - { label: "Body", name: "body", widget: "markdown", required: false } 272 | - name: "board-of-directors" 273 | label: "Board of Directors" 274 | file: "content/about/board-of-directors.md" 275 | fields: 276 | - { label: "Title", name: "title", widget: "string" } 277 | - { 278 | label: "Description", 279 | name: "description", 280 | widget: "text", 281 | required: false, 282 | } 283 | - { 284 | label: "Images", 285 | name: "images", 286 | widget: "list", 287 | field: { label: "Image", name: "image", widget: "image" }, 288 | } 289 | - label: "Board" 290 | name: "board" 291 | widget: "list" 292 | fields: 293 | - label: "Name" 294 | name: "name" 295 | widget: "string" 296 | - label: "Affiliation" 297 | name: "affiliation" 298 | widget: "string" 299 | - name: "our-history" 300 | label: "Our History" 301 | file: "content/about/history.md" 302 | fields: 303 | - { label: "Title", name: "title", widget: "string" } 304 | - { 305 | label: "Description", 306 | name: "description", 307 | widget: "text", 308 | required: false, 309 | } 310 | - { 311 | label: "Images", 312 | name: "images", 313 | widget: "list", 314 | field: { label: "Image", name: "image", widget: "image" }, 315 | } 316 | - { label: "Body", name: "body", widget: "markdown", required: false } 317 | - name: "jobs-page" 318 | label: "Jobs Page" 319 | file: "content/about/jobs.md" 320 | fields: 321 | - { label: "Title", name: "title", widget: "string" } 322 | - { label: "Date", name: "date", widget: "date" } 323 | - { 324 | label: "Description", 325 | name: "description", 326 | widget: "text", 327 | required: false, 328 | } 329 | - { label: "Body", name: "body", widget: "markdown", required: false } 330 | - name: "events-page" 331 | label: "Events Page" 332 | file: "content/events/_index.md" 333 | fields: 334 | - { label: "Title", name: "title", widget: "string" } 335 | - { 336 | label: "Exclude From Collection", 337 | name: "exclude_collection", 338 | widget: "boolean", 339 | default: true, 340 | } 341 | - name: "blogs-page" 342 | label: "Blogs Page" 343 | file: "content/blog/_index.md" 344 | fields: 345 | - { label: "Title", name: "title", widget: "string" } 346 | - { 347 | label: "Exclude From Collection", 348 | name: "exclude_collection", 349 | widget: "boolean", 350 | default: true, 351 | } 352 | - name: "litigation-docket-page" 353 | label: "Litigation Docket Page" 354 | file: "content/litigation-docket/_index.md" 355 | fields: 356 | - { label: "Title", name: "title", widget: "string" } 357 | - { 358 | label: "Exclude From Collection", 359 | name: "exclude_collection", 360 | widget: "boolean", 361 | default: true, 362 | } 363 | - { 364 | label: "Description", 365 | name: "description", 366 | widget: "text", 367 | required: false, 368 | } 369 | - name: "news-page" 370 | label: "News Page" 371 | file: "content/news/_index.md" 372 | fields: 373 | - { label: "Title", name: "title", widget: "string" } 374 | - { 375 | label: "Exclude From Collection", 376 | name: "exclude_collection", 377 | widget: "boolean", 378 | default: true, 379 | } 380 | - name: "press-releases-page" 381 | label: "Press Releases Page" 382 | file: "content/press-release/_index.md" 383 | fields: 384 | - { label: "Title", name: "title", widget: "string" } 385 | - { 386 | label: "Exclude From Collection", 387 | name: "exclude_collection", 388 | widget: "boolean", 389 | default: true, 390 | } 391 | - name: "programs-page" 392 | label: "Programs Page" 393 | file: "content/programs/_index.md" 394 | fields: 395 | - { label: "Title", name: "title", widget: "string" } 396 | - { 397 | label: "Exclude From Collection", 398 | name: "exclude_collection", 399 | widget: "boolean", 400 | default: true, 401 | } 402 | - { 403 | label: "Description", 404 | name: "description", 405 | widget: "markdown", 406 | required: false, 407 | } 408 | - { 409 | label: "Images", 410 | name: "images", 411 | widget: "list", 412 | field: { label: "Image", name: "image", widget: "image" }, 413 | } 414 | - { 415 | label: "Featured", 416 | name: "Featured", 417 | widget: "boolean", 418 | default: false, 419 | } 420 | - name: "publications-page" 421 | label: "Publications Page" 422 | file: "content/publications/_index.md" 423 | fields: 424 | - { label: "Title", name: "title", widget: "string" } 425 | - { 426 | label: "Exclude From Collection", 427 | name: "exclude_collection", 428 | widget: "boolean", 429 | default: true, 430 | } 431 | - { 432 | label: "Description", 433 | name: "description", 434 | widget: "markdown", 435 | required: false, 436 | } 437 | - { 438 | label: "Images", 439 | name: "images", 440 | widget: "list", 441 | field: { label: "Image", name: "image", widget: "image" }, 442 | } 443 | - name: "staff-page" 444 | label: "Staff Page" 445 | file: "content/staff/_index.md" 446 | fields: 447 | - { label: "Title", name: "title", widget: "string" } 448 | - { 449 | label: "Exclude From Collection", 450 | name: "exclude_collection", 451 | widget: "boolean", 452 | default: true, 453 | } 454 | - { 455 | label: "Images", 456 | name: "images", 457 | widget: "list", 458 | field: { label: "Image", name: "image", widget: "image" }, 459 | } 460 | - name: "take-action-page" 461 | label: "Take Action Page" 462 | file: "content/take-action/_index.md" 463 | fields: 464 | - { label: "Title", name: "title", widget: "string" } 465 | - { 466 | label: "Description", 467 | name: "description", 468 | widget: "markdown", 469 | required: false, 470 | } 471 | - { 472 | label: "Images", 473 | name: "images", 474 | widget: "list", 475 | field: { label: "Image", name: "image", widget: "image" }, 476 | } 477 | - { label: "Date", name: "date", widget: "date" } 478 | - name: "donate-page" 479 | label: "Donate Page" 480 | file: "content/take-action/donate.md" 481 | fields: 482 | - { label: "Title", name: "title", widget: "string" } 483 | - { 484 | label: "Description", 485 | name: "description", 486 | widget: "markdown", 487 | required: false, 488 | } 489 | - { 490 | label: "Images", 491 | name: "images", 492 | widget: "list", 493 | field: { label: "Image", name: "image", widget: "image" }, 494 | } 495 | - { 496 | label: "Aliases", 497 | name: "aliases", 498 | widget: "list", 499 | field: { label: "Alias", widget: "string" }, 500 | } 501 | - label: Topic 502 | name: topic 503 | widget: list 504 | fields: 505 | - { label: "Heading", name: "heading", widget: "string" } 506 | - { label: "Copy", name: "copy", widget: "markdown" } 507 | - { label: "Copy", name: "copy", widget: "markdown", required: false } 508 | - { 509 | label: "Italicize", 510 | name: "italicize", 511 | widget: "boolean", 512 | default: "false", 513 | } 514 | - label: "Page Bottom Copy" 515 | name: "page_bottom_copy" 516 | widget: "object" 517 | fields: 518 | - { 519 | label: "Copy", 520 | name: "copy", 521 | widget: "markdown", 522 | required: false, 523 | } 524 | - { 525 | label: "Italicize", 526 | name: "italicize", 527 | widget: "boolean", 528 | default: false, 529 | } 530 | - { label: "Body", name: "body", widget: "markdown", required: false } 531 | - name: "follow-us-page" 532 | label: "Follow Us Page" 533 | file: "content/take-action/follow-us.md" 534 | fields: 535 | - { label: "Title", name: "title", widget: "string" } 536 | - { 537 | label: "Images", 538 | name: "images", 539 | widget: "list", 540 | field: { label: "Image", name: "image", widget: "image" }, 541 | } 542 | - { 543 | label: "Description", 544 | name: "description", 545 | widget: "markdown", 546 | required: false, 547 | } 548 | - { label: "Date", name: "date", widget: "date", required: false } 549 | - { label: "Body", name: "body", widget: "markdown", required: false } 550 | - name: "volunteer-page" 551 | label: "Volunteer Page" 552 | file: "content/take-action/volunteer.md" 553 | fields: 554 | - { label: "Title", name: "title", widget: "string" } 555 | - { 556 | label: "Images", 557 | name: "images", 558 | widget: "list", 559 | field: { label: "Image", name: "image", widget: "image" }, 560 | } 561 | - { label: "Date", name: "date", widget: "date", required: false } 562 | - { 563 | label: "Description", 564 | name: "description", 565 | widget: "markdown", 566 | required: false, 567 | } 568 | - name: "translated-content" 569 | label: "Translated Content" 570 | file: "content/translation/_index.md" 571 | fields: 572 | - { label: "Title", name: "title", widget: "string" } 573 | - { 574 | label: "Exclude From Collection", 575 | name: "exclude_collection", 576 | widget: "boolean", 577 | default: true, 578 | } 579 | - { label: "Draft", name: "draft", widget: "boolean", default: true } 580 | - name: "updates-page" 581 | label: "Updates Page" 582 | file: "content/updates/_index.md" 583 | fields: 584 | - { label: "Title", name: "title", widget: "string" } 585 | 586 | - name: "blog-posts" 587 | label: "Blog Posts" 588 | folder: "content/blog" 589 | filter: { field: "exclude_collection" } 590 | create: true 591 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 592 | editor: 593 | preview: false 594 | fields: 595 | - { label: "Title", name: "title", widget: "string" } 596 | - { 597 | label: "Contributors", 598 | name: "contributors", 599 | widget: "list", 600 | field: 601 | { 602 | label: "Contributor", 603 | widget: "relation", 604 | collection: "contributors", 605 | searchFields: "title", 606 | valueField: "title", 607 | }, 608 | } 609 | - { label: "Publish Date", name: "date", widget: "datetime" } 610 | - { 611 | label: "Description", 612 | name: "description", 613 | widget: "string", 614 | required: false, 615 | } 616 | - { name: "type", widget: "hidden", default: "updates", required: false } 617 | - { 618 | label: "Related Programs", 619 | name: "related_programs", 620 | widget: "list", 621 | field: 622 | { 623 | label: "Program", 624 | widget: "relation", 625 | collection: "programs", 626 | searchFields: "title", 627 | valueField: "title", 628 | }, 629 | } 630 | - { 631 | label: "Images", 632 | name: "images", 633 | widget: "list", 634 | field: { label: "Image", name: "image", widget: "image" }, 635 | } 636 | - { 637 | label: "Tags", 638 | name: "tags", 639 | widget: "list", 640 | field: 641 | { 642 | label: "Tag", 643 | widget: "string", 644 | }, 645 | } 646 | - label: "SEO" 647 | name: "seo" 648 | widget: "object" 649 | fields: 650 | - label: "Image" 651 | name: "image" 652 | widget: "image" 653 | required: false 654 | - label: "Description" 655 | name: "description" 656 | widget: "text" 657 | required: false 658 | - { label: "Body", name: "body", widget: "markdown", required: false } 659 | - name: "events" 660 | label: "Events" 661 | folder: "content/events" 662 | filter: { field: "exclude_collection" } 663 | create: true 664 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 665 | editor: 666 | preview: false 667 | fields: 668 | - { label: "Title", name: "title", widget: "string" } 669 | - { 670 | label: "Description", 671 | name: "description", 672 | widget: "markdown", 673 | required: false, 674 | } 675 | - { label: "Date", name: "date", widget: "date" } 676 | - { 677 | label: "Images", 678 | name: "images", 679 | widget: "list", 680 | field: { label: "Image", name: "image", widget: "image" }, 681 | } 682 | - { 683 | label: "Show Time", 684 | name: "show_time", 685 | widget: "boolean", 686 | default: true, 687 | } 688 | - label: "Venue" 689 | name: "venue" 690 | widget: "object" 691 | fields: 692 | - label: "Name" 693 | name: "name" 694 | widget: "string" 695 | required: false 696 | - label: "Street 1" 697 | name: "street1" 698 | widget: "string" 699 | required: false 700 | - label: "Street 2" 701 | name: "street2" 702 | widget: "string" 703 | required: false 704 | - label: "City" 705 | name: "city" 706 | widget: "string" 707 | required: false 708 | - label: "State" 709 | name: "state" 710 | widget: "string" 711 | required: false 712 | - label: "Zip Code" 713 | name: "zip" 714 | widget: "string" 715 | required: false 716 | - label: "Country" 717 | name: "country" 718 | widget: "string" 719 | required: false 720 | - { 721 | label: "Authors", 722 | name: "authors", 723 | widget: "list", 724 | field: 725 | { 726 | label: "Author", 727 | widget: "relation", 728 | collection: "authors", 729 | searchFields: "title", 730 | valueField: "title", 731 | }, 732 | } 733 | - { 734 | label: "Related Programs", 735 | name: "related_programs", 736 | widget: "list", 737 | field: 738 | { 739 | label: "Program", 740 | widget: "relation", 741 | collection: "programs", 742 | searchFields: "title", 743 | valueField: "title", 744 | }, 745 | } 746 | - { label: "Link to Original", name: "link_to_original", required: false } 747 | - label: "SEO" 748 | name: "seo" 749 | widget: "object" 750 | fields: 751 | - label: "Image" 752 | name: "image" 753 | widget: "image" 754 | required: false 755 | - label: "Description" 756 | name: "description" 757 | widget: "text" 758 | required: false 759 | - { label: "Draft", name: "draft", widget: "boolean", default: false } 760 | - { label: "Body", name: "body", widget: "markdown", required: false } 761 | - name: "litigation-dockets" 762 | label: "Litigation Dockets" 763 | folder: "content/litigation-docket" 764 | filter: { field: "exclude_collection" } 765 | create: true 766 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 767 | editor: 768 | preview: false 769 | fields: 770 | - { label: "Title", name: "title", widget: "string" } 771 | - { 772 | label: "Related Programs", 773 | name: "related_programs", 774 | widget: "list", 775 | field: 776 | { 777 | label: "Program", 778 | widget: "relation", 779 | collection: "programs", 780 | searchFields: "title", 781 | valueField: "title", 782 | }, 783 | } 784 | - { 785 | label: "Description", 786 | name: "description", 787 | widget: "markdown", 788 | required: false, 789 | } 790 | - { label: "Body", name: "body", widget: "markdown", required: false } 791 | - name: "news-posts" 792 | label: "News Posts" 793 | folder: "content/news" 794 | filter: { field: "exclude_collection" } 795 | create: true 796 | slug: "{{slug}}" 797 | preview_path: news/{{slug}} 798 | editor: 799 | preview: true 800 | fields: 801 | - { label: "Title", name: "title", widget: "string" } 802 | - { 803 | label: "Authors", 804 | name: "authors", 805 | widget: "list", 806 | field: 807 | { 808 | label: "Author", 809 | widget: "relation", 810 | collection: "authors", 811 | searchFields: "title", 812 | valueField: "title", 813 | }, 814 | } 815 | - { name: "type", widget: "hidden", default: "updates", required: false } 816 | - { label: "Date", name: "date", widget: "date" } 817 | - { 818 | label: "Related Programs", 819 | name: "related_programs", 820 | widget: "list", 821 | field: 822 | { 823 | label: "Program", 824 | widget: "relation", 825 | collection: "programs", 826 | searchFields: "title", 827 | valueField: "title", 828 | }, 829 | } 830 | - { 831 | label: "Link to Original", 832 | name: "link_to_original", 833 | widget: "string", 834 | required: false, 835 | } 836 | - label: "Images" 837 | name: "images" 838 | widget: "list" 839 | fields: 840 | - label: "Image" 841 | name: "image" 842 | widget: "image" 843 | - label: "Credit" 844 | name: "credit" 845 | widget: "string" 846 | - label: "Caption" 847 | name: "caption" 848 | widget: "string" 849 | - { 850 | label: "Tags", 851 | name: "tags", 852 | widget: "list", 853 | field: 854 | { 855 | label: "Tag", 856 | widget: "string", 857 | }, 858 | } 859 | - { label: "Body", name: "body", widget: "markdown", required: false } 860 | - name: "press-releases" 861 | label: "Press Releases" 862 | folder: "content/press-release" 863 | filter: { field: "exclude_collection" } 864 | create: true 865 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 866 | editor: 867 | preview: false 868 | fields: 869 | - { label: "Title", name: "title", widget: "string" } 870 | - { 871 | label: "Authors", 872 | name: "authors", 873 | widget: "list", 874 | field: 875 | { 876 | label: "Author", 877 | widget: "relation", 878 | collection: "authors", 879 | searchFields: "title", 880 | valueField: "title", 881 | }, 882 | } 883 | - { 884 | label: "Type", 885 | name: "type", 886 | widget: "select", 887 | options: ["updates"], 888 | required: false, 889 | } 890 | - { label: "Date", name: "date", widget: "date" } 891 | - { 892 | label: "Related Programs", 893 | name: "related_programs", 894 | widget: "list", 895 | field: 896 | { 897 | label: "Program", 898 | widget: "relation", 899 | collection: "programs", 900 | searchFields: "title", 901 | valueField: "title", 902 | }, 903 | } 904 | - { 905 | label: "Link to Original", 906 | name: "link_to_original", 907 | widget: "string", 908 | required: false, 909 | } 910 | - { 911 | label: "Images", 912 | name: "images", 913 | widget: "list", 914 | field: { label: "Image", name: "image", widget: "image" }, 915 | } 916 | - { 917 | label: "Tags", 918 | name: "tags", 919 | widget: "list", 920 | field: 921 | { 922 | label: "Tag", 923 | widget: "string", 924 | }, 925 | } 926 | - { label: "Body", name: "body", widget: "markdown", required: false } 927 | - name: "programs" 928 | label: "Programs" 929 | folder: "content/programs" 930 | filter: { field: "exclude_collection" } 931 | create: true 932 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 933 | editor: 934 | preview: false 935 | fields: 936 | - { label: "Title", name: "title", widget: "string" } 937 | - { label: "Date", name: "date", widget: "date" } 938 | - { 939 | label: "Images", 940 | name: "images", 941 | widget: "list", 942 | field: { label: "Image", name: "image", widget: "image" }, 943 | } 944 | - { 945 | label: "Description", 946 | name: "description", 947 | widget: "markdown", 948 | required: false, 949 | } 950 | - { 951 | label: "Featured", 952 | name: "Featured", 953 | widget: "boolean", 954 | default: false, 955 | } 956 | - { label: "Body", name: "body", widget: "markdown", required: false } 957 | - name: "publications" 958 | label: "Publications" 959 | folder: "content/publications" 960 | filter: { field: "exclude_collection" } 961 | create: true 962 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 963 | editor: 964 | preview: false 965 | fields: 966 | - { label: "Title", name: "title", widget: "string" } 967 | - { label: "Date", name: "date", widget: "date" } 968 | - { 969 | label: "Description", 970 | name: "description", 971 | widget: "markdown", 972 | required: false, 973 | } 974 | - label: "Files" 975 | name: "files" 976 | widget: "list" 977 | fields: 978 | - { label: "Title", name: "title", widget: "string" } 979 | - { label: "File", name: "file", widget: "file" } 980 | - { 981 | label: "Images", 982 | name: "images", 983 | widget: "list", 984 | field: { label: "Image", name: "image", widget: "image" }, 985 | } 986 | - { 987 | label: "Related Programs", 988 | name: "related_programs", 989 | widget: "list", 990 | field: 991 | { 992 | label: "Program", 993 | widget: "relation", 994 | collection: "programs", 995 | searchFields: "title", 996 | valueField: "title", 997 | }, 998 | } 999 | - name: "contributors" 1000 | label: "Contributors" 1001 | folder: "content/contributor" 1002 | create: true 1003 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 1004 | editor: 1005 | preview: false 1006 | fields: 1007 | - { label: "Title", name: "title", widget: "string" } 1008 | - { label: "Last Name", name: "name_last", widget: "string" } 1009 | - { label: "First Name", name: "name_first", widget: "string" } 1010 | - { label: "Position", name: "position", widget: "string" } 1011 | - { 1012 | label: "Internal", 1013 | name: "internal", 1014 | widget: "boolean", 1015 | default: true, 1016 | } 1017 | - { 1018 | label: "Images", 1019 | name: "images", 1020 | widget: "list", 1021 | field: { label: "Image", name: "image", widget: "image" }, 1022 | } 1023 | - { label: "Group", name: "group", widget: "string", required: false } 1024 | - { 1025 | label: "Description", 1026 | name: "description", 1027 | widget: "markdown", 1028 | required: false, 1029 | } 1030 | - { label: "Body", name: "body", widget: "markdown", required: false } 1031 | - name: "authors" 1032 | label: "Staff Pages" 1033 | folder: "content/staff" 1034 | filter: { field: "exclude_collection" } 1035 | create: true 1036 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 1037 | editor: 1038 | preview: false 1039 | fields: 1040 | - { label: "Title", name: "title", widget: "string" } 1041 | - { label: "Last Name", name: "name_last", widget: "string" } 1042 | - { label: "First Name", name: "name_first", widget: "string" } 1043 | - { label: "Position", name: "position", widget: "string" } 1044 | - { 1045 | label: "Internal", 1046 | name: "internal", 1047 | widget: "boolean", 1048 | default: true, 1049 | } 1050 | - { 1051 | label: "Images", 1052 | name: "images", 1053 | widget: "list", 1054 | field: { label: "Image", name: "image", widget: "image" }, 1055 | } 1056 | - { label: "Date", name: "date", widget: "date" } 1057 | - { 1058 | label: "Group", 1059 | name: "group", 1060 | widget: "select", 1061 | options: 1062 | ["Program Staff", "Development and Administration", "Executive"], 1063 | } 1064 | - { label: "Weight", name: "weight", widget: "number", required: false } 1065 | - { 1066 | label: "Description", 1067 | name: "description", 1068 | widget: "markdown", 1069 | required: false, 1070 | } 1071 | - { label: "Body", name: "body", widget: "markdown", required: false } 1072 | - name: "translations" 1073 | label: "Translations" 1074 | folder: "content/translation" 1075 | filter: { field: "exclude_collection" } 1076 | create: true 1077 | slug: "{{year}}-{{month}}-{{day}}-{{slug}}" 1078 | editor: 1079 | preview: false 1080 | fields: 1081 | - { label: "Title", name: "title", widget: "string" } 1082 | - { label: "Type", name: "type", widget: "hidden", defaulut: "about" } 1083 | - { label: "Date", name: "date", widget: "date", required: false } 1084 | - { label: "Description", name: "description", widget: "string" } 1085 | - { 1086 | label: "Related Programs", 1087 | name: "related_programs", 1088 | widget: "list", 1089 | field: 1090 | { 1091 | label: "Program", 1092 | widget: "relation", 1093 | collection: "programs", 1094 | searchFields: "title", 1095 | valueField: "title", 1096 | }, 1097 | } 1098 | - label: "Files" 1099 | name: "files" 1100 | widget: "list" 1101 | fields: 1102 | - { label: "Title", name: "title", widget: "string" } 1103 | - { label: "File", name: "file", widget: "file" } 1104 | - { 1105 | label: "Images", 1106 | name: "images", 1107 | widget: "list", 1108 | field: { label: "Image", name: "image", widget: "image" }, 1109 | } 1110 | - { 1111 | label: "Language Code", 1112 | name: "language_code", 1113 | widget: "string", 1114 | required: false, 1115 | } 1116 | - { label: "Draft", name: "draft", widget: "boolean", default: true } 1117 | - { label: "Body", name: "body", widget: "markdown", required: false } 1118 | -------------------------------------------------------------------------------- /console/err.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | err 3 | Emits a warning using the module's Header. 4 | 5 | @author @regisphilibert 6 | 7 | @context String 8 | 9 | @access public 10 | 11 | @example - Go Template 12 | {{ partial "tnd-forms/warn" $message }} 13 | */}} 14 | {{ $header := "TND Module NetlifyCMS" }} 15 | {{ errorf "\n%s:\n%s" $header . }} 16 | 17 | {{ return true }} -------------------------------------------------------------------------------- /console/warn.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | warn 3 | Emits a warning using the module's Header. 4 | 5 | @author @regisphilibert 6 | 7 | @context String 8 | 9 | @access public 10 | 11 | @example - Go Template 12 | {{ partial "tnd-forms/warn" $message }} 13 | */}} 14 | {{ $header := "TND Module NetlifyCMS" }} 15 | {{ warnf "\n%s:\n%s" $header . }} 16 | 17 | {{ return true }} -------------------------------------------------------------------------------- /data/netlifycms/fields/body.yaml: -------------------------------------------------------------------------------- 1 | label: "Body" 2 | name: "body" 3 | widget: "markdown" 4 | required: false -------------------------------------------------------------------------------- /data/netlifycms/fields/date.yaml: -------------------------------------------------------------------------------- 1 | label: "Date" 2 | name: "date" 3 | widget: "date" -------------------------------------------------------------------------------- /data/netlifycms/fields/description.yaml: -------------------------------------------------------------------------------- 1 | label: Description 2 | name: description 3 | widget: markdown 4 | required: false -------------------------------------------------------------------------------- /data/netlifycms/fields/image.yaml: -------------------------------------------------------------------------------- 1 | label: "Image" 2 | name: "image" 3 | widget: "image" 4 | required: false -------------------------------------------------------------------------------- /data/netlifycms/fields/slug.yaml: -------------------------------------------------------------------------------- 1 | label: "Slug" 2 | name: "slug" 3 | widget: "string" 4 | required: false -------------------------------------------------------------------------------- /data/netlifycms/fields/title.yaml: -------------------------------------------------------------------------------- 1 | label: "Title" 2 | name: "title" 3 | widget: "string" -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/theNewDynamic/hugo-module-tnd-netlifycms 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /partials/private/GetCMSVersion.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | GetCMSVersion retrieves the version as set in the tnd_netlifycms settings. 3 | 4 | @author @regisphilibert 5 | 6 | @context Any (.) 7 | 8 | @access public 9 | 10 | @return String (default: ^2.0.0) 11 | 12 | @example - Go Template 13 | {{ partial "path" context }} 14 | {{ partialCached "path" context "variant" }} 15 | */}} 16 | 17 | {{/* Default is `^2.0.0` for now */}} 18 | {{ $version := `^2.0.0` }} 19 | 20 | {{ with partialCached "tnd-netlifycms/private/GetModuleConfig" . "tnd-netlifycms/private/GetModuleConfig" }} 21 | {{ with .cms_version }} 22 | {{ $version = . }} 23 | {{ end }} 24 | {{ end }} 25 | 26 | 27 | {{ return $version }} -------------------------------------------------------------------------------- /partials/private/GetConfig.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | GetConfig returns the config as set in data/netlifycms/config.yaml 3 | 4 | @author @regisphilibert 5 | 6 | @context Any 7 | 8 | @return Map 9 | 10 | @access private 11 | 12 | @example - Go Template 13 | {{ with partial "tnd-netlifycms/private/GetConfig" . }} 14 | {{ $config = . }} 15 | {{ end }} 16 | */}} 17 | {{ $return := "" }} 18 | {{ with site.Data.netlifycms.config }} 19 | {{ $return = . }} 20 | {{ end }} 21 | 22 | {{ return $return }} -------------------------------------------------------------------------------- /partials/private/GetModuleConfig.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | GetModuleConfig returns the config as set in data/netlifycms/config.yaml's tnd_netlifycms map. 3 | 4 | @author @regisphilibert 5 | 6 | @context Any 7 | 8 | @return Map 9 | 10 | @access private 11 | 12 | @example - Go Template 13 | {{ with partial "tnd-netlifycms/private/GetModuleConfig" . }} 14 | {{ $config = . }} 15 | {{ end }} 16 | */}} 17 | {{ $return := dict }} 18 | {{ with site.Params.tnd_netlifycms }} 19 | {{ $return = . }} 20 | {{ else }} 21 | {{ with site.Data.netlifycms.config.tnd_netlifycms }} 22 | {{ $return = . }} 23 | {{ end }} 24 | {{ end }} 25 | 26 | {{ return $return }} -------------------------------------------------------------------------------- /partials/private/go.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | Go simply run the process and returns data for templates. 3 | 4 | @author @regisphilibert 5 | 6 | @context Type (.name) 7 | 8 | @access private 9 | 10 | @use 11 | - private/GetConfig 12 | 13 | @example - Go Template 14 | {{- with partial "tnd-netlifycms/private/go" . -}} 15 | {{ . }} 16 | {{- end -}} 17 | */}} 18 | {{ $config := dict }} 19 | {{ with partialCached "tnd-netlifycms/private/GetConfig" . "tnd-netlifycms/private/GetConfig" }} 20 | {{ $config = . }} 21 | {{ end }} 22 | 23 | {{ with $config.collections }} 24 | {{ with partial "tnd-netlifycms/private/parse" . }} 25 | {{ $config = merge $config (dict "collections" .) }} 26 | {{ end }} 27 | {{ end }} 28 | 29 | {{ $return := transform.Remarshal "yaml" $config }} 30 | 31 | {{ return $return }} -------------------------------------------------------------------------------- /partials/private/import.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | import 3 | Reads a data object, look for an import statement and returns the correspondig data if present in data files. 4 | If no import found returns the context data as is. 5 | 6 | @author @regisphilibert 7 | 8 | @context Any (.) 9 | 10 | @return Any (.) 11 | 12 | @access private 13 | 14 | @example - Go Template 15 | {{ with partialCached "tnd-netlifycms/private/import" . . }} 16 | {{ end }} 17 | */}} 18 | {{/* regex101.com > https://regex101.com/r/mIrmn0/1 */}} 19 | {{ $pattern := "^([a-zA-Z]*) ([.a-zA-Z/_-]*)$"}} 20 | {{ $string_pattern := "^import ([a-zA-Z]*) ([.a-zA-Z/_-]*)$" }} 21 | {{/* Return variable, by default, will be the passed context */}} 22 | {{ $return := . }} 23 | {{ $type := false }} 24 | {{ $file := false }} 25 | {{ $input := false }} 26 | {{ $extend := dict }} 27 | {{/* We're looking for a String or a Map, so we start by eliminating Slices */}} 28 | {{ if not (reflect.IsSlice .) }} 29 | {{ if not (reflect.IsMap .) }} 30 | {{/* We have a string and store it as $input */}} 31 | {{ $input = . }} 32 | {{/* We use the $string_pattern for subsequent findRE */}} 33 | {{ $pattern = $string_pattern }} 34 | {{ else }} 35 | {{/* We have a map. We look for .import and store it as $input */}} 36 | {{ with .import }} 37 | {{ $input = . }} 38 | {{ end }} 39 | {{/* We also look for potential .extend data */}} 40 | {{ with .extend }} 41 | {{ $extend = . }} 42 | {{ end }} 43 | {{ end }} 44 | 45 | {{/* We're looking for a properly formated import statement */}} 46 | {{ with findRE $pattern $input }} 47 | {{/* We do have an import statement, we reset $return as we're about to fill it with new data. 48 | If the import statement fails to point to valid data file, we'll return an empty dict */}} 49 | {{ $return = dict }} 50 | {{/* We isolate the Type from the statement */}} 51 | {{ with replaceRE $pattern "$1" $input }} 52 | {{ $type = . }} 53 | {{ end }} 54 | {{/* We isolate the File from the statement */}} 55 | {{ with replaceRE $pattern "$2" $input }} 56 | {{ $file = . }} 57 | {{ end }} 58 | {{/* With both File and Type... */}} 59 | {{ if and $type $file }} 60 | {{/* We look for the matching data file located in `data/netlifycms/{Type}/{File}.yaml` */}} 61 | {{ with index site.Data.netlifycms (pluralize $type) }} 62 | {{ $with := index . $file }} 63 | {{/* If we find a "." in the File string, it means user is trying to access a nested value. 64 | We'll split the string and check for two nesting level max 65 | */}} 66 | {{ $file_split := split $file "." }} 67 | {{ if eq (len $file_split) 2 }} 68 | {{/* We have something like `import fields greeting.spanish */}} 69 | {{ $with = index . (index $file_split 0) (index $file_split 1) }} 70 | {{ else if eq (len $file_split) 3 }} 71 | {{/* We have something like `import fields greeting.spanish.singular */}} 72 | {{ $with = index . (index $file_split 0) (index $file_split 1) (index $file_split 2) }} 73 | {{ end }} 74 | 75 | {{ with $with }} 76 | {{ $return = . }} 77 | {{ with $extend }} 78 | {{ $return = merge $return . }} 79 | {{ end }} 80 | {{ else }} 81 | {{ $message := printf "We couldn't find %s/%s" $type $file }} 82 | {{ with $file_split }} 83 | {{ if gt . 2 }} 84 | {{ $message = print $message " because object depth is limited to 2" }} 85 | {{ end }} 86 | {{ end }} 87 | {{ partial "tnd-netlifycms/warn" $message }} 88 | {{ end }} 89 | {{ else }} 90 | {{ partial "tnd-netlifycms/warn" (printf "We couldn't find Type %s" $type) }} 91 | {{ end }} 92 | {{ end }} 93 | {{ end }} 94 | {{ end }} 95 | 96 | {{ return $return }} -------------------------------------------------------------------------------- /partials/private/parse.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | parse 3 | Take some data, range through it and apply the importing logic when available. 4 | 5 | @author @regisphilibert 6 | 7 | @context Slice/Map 8 | 9 | @return Slice/Map 10 | 11 | @use 12 | - Self 13 | - private/import 14 | 15 | @access private 16 | 17 | @example - Go Template 18 | {{ with partial "tnd-netlifycms/private/parse" . }} 19 | {{ $do := . }} 20 | {{ end }} 21 | */}} 22 | {{ $return := . }} 23 | {{/* We only modify the data if context is a Map or a Slice */}} 24 | {{ if or (reflect.IsSlice .) (reflect.IsMap .) }} 25 | {{/* If context is slice */}} 26 | {{ if reflect.IsSlice . }} 27 | {{/* We init a new slice */}} 28 | {{ $slice := slice }} 29 | {{/* We range on its item */}} 30 | {{ range . }} 31 | {{ with . }} 32 | {{/* As it is a slice, its entries might be "imports" */}} 33 | {{ with partialCached "tnd-netlifycms/private/import" . . }} 34 | {{/* We recursively use self partial to deep parse the result */}} 35 | {{ with partialCached "tnd-netlifycms/private/parse" . . }} 36 | {{/* We add the produced data as an entry to the newly processed slice */}} 37 | {{ $slice = $slice | append . }} 38 | {{ end }} 39 | {{ end }} 40 | {{ end }} 41 | {{ end }} 42 | {{/* We'll return the $slice */}} 43 | {{ $return = $slice }} 44 | {{/* If context is a map */}} 45 | {{ else if reflect.IsMap . }} 46 | {{/* We init an empty map */}} 47 | {{ $map := . }} 48 | {{ $origin := . }} 49 | {{/* We range on it via key and value */}} 50 | {{ range $key, $value := . }} 51 | {{/* As it's a not a slice, there is no potential imports, we can directly use parse 52 | We make sure the value is not emtpy. As of Hugo .75 returning partial now requires a non-zero argument 53 | */}} 54 | {{ with . }} 55 | {{ with partialCached "tnd-netlifycms/private/parse" . . }} 56 | {{/* We merge the produced data with the newly created $map */}} 57 | {{ if ne . $value }} 58 | {{ $map = merge $map (dict $key .) }} 59 | {{ end }} 60 | {{ end }} 61 | {{ end }} 62 | {{ end }} 63 | {{/* We'll return the $map */}} 64 | {{ if ne $origin $map }} 65 | {{ $return = $map }} 66 | {{ else }} 67 | {{ $return = $origin }} 68 | {{ end }} 69 | {{ end }} 70 | {{ else }} 71 | {{ $return = . }} 72 | {{ end }} 73 | 74 | {{ return $return }} 75 | -------------------------------------------------------------------------------- /partials/scripts.html: -------------------------------------------------------------------------------- 1 | {{ with resources.Get "netlifycms.js" }} 2 | 3 | {{ end }} -------------------------------------------------------------------------------- /templates/single.html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |