├── .ddev ├── commands │ └── host │ │ └── vite-visualizer.sh └── config.yaml ├── .editorconfig ├── .env.example.dev ├── .env.example.production ├── .env.example.staging ├── .gitignore ├── .husky └── pre-commit ├── .prettierignore ├── .prettierrc ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── ARCHITECTURE.md ├── README.md ├── bootstrap.php ├── composer-scripts ├── ScriptHelpers.php └── post-create-project.php ├── composer.json ├── composer.lock ├── config ├── app.php ├── general.php ├── htmlpurifier │ └── Default.json ├── imager-x-aws-serverless-transformer.php ├── imager-x-transforms.php ├── imager-x.php ├── project │ ├── ckeditor │ │ └── configs │ │ │ ├── b7e66782-af96-4012-9e17-914134073ced.yaml │ │ │ └── d39724b0-dd22-4c74-aa0b-87a022555cf2.yaml │ ├── entryTypes │ │ ├── callToAction--534ccdd8-7abd-4300-a102-71885b21c126.yaml │ │ ├── cardGrid--7ced3e9d-9b54-47f6-8103-e5c3a4fbaf9c.yaml │ │ ├── codeBlock--cbf3aeac-588c-4aeb-9573-6f1920206abf.yaml │ │ ├── globalCode--25362218-e66c-494e-9f2c-63e8cbc6ce0a.yaml │ │ ├── heading--e445a3b9-5827-422a-8328-6b10449fa891.yaml │ │ ├── home--0e7762a5-2553-4c0d-b8af-9b43b59524bf.yaml │ │ ├── iconCard--3f1dc0c5-f091-469a-858a-4cbd3596bab7.yaml │ │ ├── imageCard--7d418368-91eb-4c64-8f5b-94c62cd62359.yaml │ │ ├── pageHero--27f19bae-64f8-47b8-9fc9-7552e11e2656.yaml │ │ ├── richText--896b8f2a-ed0c-42c9-b5fd-ba8668fc6784.yaml │ │ └── textWithMedia--3bcf7ddb-71e7-4115-868c-815b3611b34c.yaml │ ├── fields │ │ ├── basicLink--69fe4c18-21c9-4a3d-8fce-9988d3f741e4.yaml │ │ ├── button--2ea51656-9b0c-4736-a6fe-c95dc805dc60.yaml │ │ ├── cardGrid--5e84b0b7-6851-47ed-962e-76498ac9476f.yaml │ │ ├── code--7a701601-ee6c-4d56-8bd0-efa7719f6a67.yaml │ │ ├── codeBlocks--9c7dc3c3-cb8c-4167-880d-ab9426eef873.yaml │ │ ├── codePosition--f7d30e72-f872-487a-aba1-c8e95268a220.yaml │ │ ├── description--a99edea2-f8ae-44e5-a12f-89cb9aa66738.yaml │ │ ├── heading--4382f55f-01a1-4b67-84c8-ebbc89b238d2.yaml │ │ ├── icon--0011a64a-91b6-4aa3-98e6-be048394a2cf.yaml │ │ ├── image--570fb481-ad97-46db-8bad-f7b0fd90e831.yaml │ │ ├── mediaType--ac3b0590-d417-429e-aa1f-96be3c79a5b0.yaml │ │ ├── pageBlocks--7bd21dd3-6b12-4163-8432-030ea6a3f8d3.yaml │ │ ├── richText--cd489d3c-f914-475c-a270-ab926e4e7485.yaml │ │ ├── richTextSimple--c52a9170-652b-4d92-a226-69894b1822ed.yaml │ │ ├── side--d7f9c488-b14d-48c2-b6fc-d616b7a9f49f.yaml │ │ └── videoUrl--55cc26b6-8b49-47de-bbe7-5908da6f4545.yaml │ ├── navigation │ │ └── navs │ │ │ ├── footerNavigation--101b4db6-8914-45eb-a661-180b15f70894.yaml │ │ │ └── primaryNavigation--b3d7753a-c7ad-4f33-aca8-df63277e9b42.yaml │ ├── project.yaml │ ├── sections │ │ ├── globalCode--b4bfeb63-5bc4-4368-b4c9-408f7bac68fc.yaml │ │ └── home--969acdd6-6362-41b1-b782-6bbd43a8a6b4.yaml │ ├── siteGroups │ │ └── 805d8826-faed-4186-9b88-f509eb9b07e6.yaml │ ├── sites │ │ └── default--35b563a0-4662-40b9-b885-a8450a2868d9.yaml │ └── volumes │ │ └── assets--853413e4-e02c-487e-81a5-04e58eb18683.yaml ├── redirects.php ├── routes.php ├── tailwind │ ├── buttons.js │ ├── dialog.js │ ├── forms.js │ └── rich-text.js └── vite.php ├── craft ├── docs ├── block-call-to-action-admin.png ├── block-call-to-action-frontend.png ├── block-card-grid-admin.png ├── block-card-grid-frontend.png ├── block-heading-admin.png ├── block-heading-frontend.png ├── block-page-hero-admin.png ├── block-page-hero-frontend.png ├── block-rich-text-admin.png ├── block-rich-text-frontend.png ├── block-text-with-media-image-admin.png ├── block-text-with-media-image-frontend.png ├── block-text-with-media-video-admin.png ├── block-text-with-media-video-frontend.png ├── building-with-site-starter.md ├── project-logo.png ├── release-qa-1.png ├── release-qa-2.png └── site-starter-ecosystem.excalidraw.png ├── ecs.php ├── eslint.config.js ├── lint-staged.config.js ├── modules └── todo.php ├── package-lock.json ├── package.json ├── phpstan.neon ├── postcss.config.js ├── src ├── css │ └── app.css ├── fonts │ ├── .gitkeep │ ├── sourcesanspro-bold-webfont.woff2 │ ├── sourcesanspro-light-webfont.woff2 │ ├── sourcesanspro-regular-webfont.woff2 │ └── sourcesanspro-semibold-webfont.woff2 ├── icons │ ├── arrow-left.svg │ ├── arrow-right.svg │ ├── chevron-down.svg │ ├── clock.svg │ ├── close.svg │ ├── error.svg │ ├── logo-mark.svg │ └── logo-primary.svg └── js │ ├── alpine │ └── nav.js │ └── app.js ├── storage ├── .gitignore └── config-deltas │ └── .gitignore ├── templates ├── .gitkeep ├── _blocks │ ├── _callToAction.twig │ ├── _cardGrid.twig │ ├── _heading.twig │ ├── _pageHero.twig │ ├── _richText.twig │ ├── _textWithMedia.twig │ └── index.twig ├── _components │ ├── accordion.twig │ ├── alert-banner.twig │ ├── button.twig │ ├── call-to-action.twig │ ├── card-icon.twig │ ├── card-image.twig │ ├── dialog.twig │ ├── field-group.twig │ ├── field-select.twig │ ├── field-text-input.twig │ ├── field-textarea.twig │ ├── icon.twig │ ├── image-caption.twig │ ├── image.twig │ ├── page-hero.twig │ ├── pagination.twig │ ├── tabs.twig │ ├── tag.twig │ └── video.twig ├── _elements │ └── home.twig ├── _layouts │ └── base.twig ├── _partials │ ├── footer.twig │ ├── global-code-blocks.twig │ ├── header.twig │ ├── nav-desktop.twig │ └── nav-mobile.twig └── parts-kit │ ├── accordion │ └── default.twig │ ├── alert-banner │ └── default.twig │ ├── button │ └── default.twig │ ├── call-to-action │ └── default.twig │ ├── card │ ├── card-with-icon.twig │ └── card-with-image.twig │ ├── dialog │ ├── default.twig │ └── digalog-triggers-dialog.twig │ ├── forms │ ├── select.twig │ ├── text-input.twig │ └── textarea.twig │ ├── icons │ └── default.twig │ ├── image-caption │ └── default.twig │ ├── image │ └── default.twig │ ├── page-hero │ └── default.twig │ ├── paginaton │ └── default.twig │ ├── tabs │ └── default.twig │ ├── tag │ └── default.twig │ └── video │ └── default.twig ├── vite.config.js └── web ├── .htaccess ├── cpresources └── .gitignore ├── index.php └── web.config /.ddev/commands/host/vite-visualizer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Description: Analyze and visualize the Vite bundle with the current project 4 | ## OSTypes: darwin 5 | ## Usage: vite-visualizer 6 | ## Example: "ddev vite-visualizer" 7 | ## See: https://www.npmjs.com/package/vite-bundle-visualizer 8 | 9 | ddev exec npx vite-bundle-visualizer -o vite-bundle-visualizer.html 10 | 11 | open "${DDEV_APPROOT}/vite-bundle-visualizer.html" -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://EditorConfig.org 2 | 3 | root = true 4 | 5 | # Unix-style newlines with a newline ending every file 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [*.csv] 15 | insert_final_newline = false 16 | 17 | [*.{php,py}] 18 | indent_size = 4 19 | 20 | # https://www.markdownguide.org/basic-syntax/#line-breaks 21 | [*.md] 22 | trim_trailing_whitespace = false 23 | -------------------------------------------------------------------------------- /.env.example.dev: -------------------------------------------------------------------------------- 1 | # Read about configuration, here: 2 | # https://craftcms.com/docs/5.x/configure.html 3 | 4 | # The application ID used to to uniquely store session and cache data, mutex locks, and more 5 | CRAFT_APP_ID= 6 | 7 | # The environment Craft is currently running in (dev, staging, production, etc.) 8 | CRAFT_ENVIRONMENT=dev 9 | 10 | # Email 11 | SYSTEM_EMAIL_ADDRESS=craft@viget.com 12 | SYSTEM_EMAIL_SENDER="Craft CMS" 13 | SYSTEM_EMAIL_HOSTNAME= 14 | SYSTEM_EMAIL_PORT= 15 | SYSTEM_EMAIL_USERNAME= 16 | SYSTEM_EMAIL_PASSWORD= 17 | 18 | # Database connection settings 19 | CRAFT_DB_DRIVER=mysql 20 | CRAFT_DB_SERVER=127.0.0.1 21 | CRAFT_DB_PORT=3306 22 | CRAFT_DB_DATABASE= 23 | CRAFT_DB_USER=root 24 | CRAFT_DB_PASSWORD= 25 | CRAFT_DB_SCHEMA=public 26 | CRAFT_DB_TABLE_PREFIX= 27 | 28 | # General settings 29 | CRAFT_SECURITY_KEY= 30 | CRAFT_DEV_MODE=true 31 | CRAFT_ALLOW_ADMIN_CHANGES=true 32 | CRAFT_DISALLOW_ROBOTS=true 33 | 34 | # Amazon S3 35 | S3_BASE_URL= 36 | S3_SUBFOLDER= 37 | S3_BUCKET_REGION= 38 | S3_BUCKET= 39 | S3_ACCESS_KEY_ID= 40 | S3_SECRET_ACCESS_KEY= 41 | S3_CLOUDFRONT_DISTRIBUTION_ID= 42 | 43 | # AWS Serverless 44 | IMAGERX_SERVERLESS_DISTRIBUTION_URL= 45 | IMAGERX_SERVERLESS_DISTRIBUTION_SIGNATURE= 46 | -------------------------------------------------------------------------------- /.env.example.production: -------------------------------------------------------------------------------- 1 | # Read about configuration, here: 2 | # https://craftcms.com/docs/5.x/configure.html 3 | 4 | # The application ID used to to uniquely store session and cache data, mutex locks, and more 5 | CRAFT_APP_ID= 6 | 7 | # The environment Craft is currently running in (dev, staging, production, etc.) 8 | CRAFT_ENVIRONMENT=production 9 | 10 | # Email 11 | SYSTEM_EMAIL_FROM=craft@viget.com 12 | SYSTEM_EMAIL_HOSTNAME= 13 | SYSTEM_EMAIL_PORT= 14 | SYSTEM_EMAIL_USERNAME= 15 | SYSTEM_EMAIL_PASSWORD= 16 | 17 | # Database connection settings 18 | CRAFT_DB_DRIVER=mysql 19 | CRAFT_DB_SERVER=127.0.0.1 20 | CRAFT_DB_PORT=3306 21 | CRAFT_DB_DATABASE= 22 | CRAFT_DB_USER=root 23 | CRAFT_DB_PASSWORD= 24 | CRAFT_DB_SCHEMA=public 25 | CRAFT_DB_TABLE_PREFIX= 26 | 27 | # General settings 28 | CRAFT_SECURITY_KEY= 29 | CRAFT_DEV_MODE=false 30 | CRAFT_ALLOW_ADMIN_CHANGES=false 31 | CRAFT_DISALLOW_ROBOTS=false 32 | -------------------------------------------------------------------------------- /.env.example.staging: -------------------------------------------------------------------------------- 1 | # Read about configuration, here: 2 | # https://craftcms.com/docs/5.x/configure.html 3 | 4 | # The application ID used to to uniquely store session and cache data, mutex locks, and more 5 | CRAFT_APP_ID= 6 | 7 | # The environment Craft is currently running in (dev, staging, production, etc.) 8 | CRAFT_ENVIRONMENT=staging 9 | 10 | # Email 11 | SYSTEM_EMAIL_FROM=craft@viget.com 12 | SYSTEM_EMAIL_HOSTNAME= 13 | SYSTEM_EMAIL_PORT= 14 | SYSTEM_EMAIL_USERNAME= 15 | SYSTEM_EMAIL_PASSWORD= 16 | 17 | # Database connection settings 18 | CRAFT_DB_DRIVER=mysql 19 | CRAFT_DB_SERVER=127.0.0.1 20 | CRAFT_DB_PORT=3306 21 | CRAFT_DB_DATABASE= 22 | CRAFT_DB_USER=root 23 | CRAFT_DB_PASSWORD= 24 | CRAFT_DB_SCHEMA=public 25 | CRAFT_DB_TABLE_PREFIX= 26 | 27 | # General settings 28 | CRAFT_SECURITY_KEY= 29 | CRAFT_DEV_MODE=false 30 | CRAFT_ALLOW_ADMIN_CHANGES=false 31 | CRAFT_DISALLOW_ROBOTS=true 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.env 2 | /.idea 3 | /vendor 4 | .DS_Store 5 | node_modules 6 | /web/dist 7 | /web/assets 8 | /web/imager 9 | /.vite 10 | php-cs-fixer.cache 11 | # Ignore generated visualization files 12 | vite-bundle-visualizer.html 13 | 14 | # BEGIN-STARTER-ONLY 15 | config/license.key 16 | # END-STARTER-ONLY 17 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | ddev exec npx lint-staged 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | composer.lock 4 | composer.json 5 | vendor 6 | config/project 7 | storage 8 | web 9 | package-lock.json 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "trailingComma": "all" 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "EditorConfig.EditorConfig", 4 | "bradlc.vscode-tailwindcss", 5 | "DEVSENSE.phptools-vscode", 6 | "biati.ddev-manager", 7 | "xdebug.php-debug", 8 | "moetelo.twiggy" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Listen for Xdebug", 5 | "type": "php", 6 | "request": "launch", 7 | "hostname": "0.0.0.0", 8 | "port": 9003, 9 | "pathMappings": { 10 | "/var/www/html": "${workspaceFolder}" 11 | }, 12 | "preLaunchTask": "DDEV: Enable Xdebug", 13 | "postDebugTask": "DDEV: Disable Xdebug" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "intelephense.environment.phpVersion": "8.2", 3 | "php.version": "8.2", 4 | "twiggy.framework": "craft" 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "DDEV: Enable Xdebug", 6 | "type": "shell", 7 | "command": "ddev xdebug on", 8 | "presentation": { 9 | "reveal": "silent", 10 | "close": true 11 | } 12 | }, 13 | { 14 | "label": "DDEV: Disable Xdebug", 15 | "type": "shell", 16 | "command": "ddev xdebug off", 17 | "presentation": { 18 | "reveal": "silent", 19 | "close": true 20 | } 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /ARCHITECTURE.md: -------------------------------------------------------------------------------- 1 | # Architecture 2 | 3 | ## Goals 4 | 5 | - As simple as possible 6 | - Easy to contribute 7 | - Use PHP/Composer as much as possible for setup scripts 8 | - Easy to test changes 9 | - Make it easy to `ddev start` this repo and test your plugin and build tool changes. 10 | - It should feel like you're working on a typical Craft project 11 | - Cross-platform (Mac, Windows, Linux) 12 | - We can achieve this by using PHP/Composer and running scripts from within Docker containers. 13 | 14 | ## Overview 15 | 16 | This starter is a Composer "project" that can be installed using `composer create-project`. 17 | 18 | composer.json has a `post-create-project-cmd` [script](https://getcomposer.org/doc/articles/scripts.md) that will run after the project is created. 19 | 20 | We use this hook to start the installation process (modify and delete files, edit config, etc). 21 | 22 | Some aspects of the installation are single line bash scripts. However, more complex actions are handled by PHP files in the [install-scripts](/install-scripts) directory 23 | -------------------------------------------------------------------------------- /bootstrap.php: -------------------------------------------------------------------------------- 1 | safeLoad(); 18 | } 19 | -------------------------------------------------------------------------------- /composer-scripts/ScriptHelpers.php: -------------------------------------------------------------------------------- 1 | true, 16 | ]); 17 | 18 | Console::output("Great! We'll use the name: $projectName"); 19 | 20 | $suggestedProjectSlug = StringHelper::toKebabCase($projectName); 21 | 22 | $projectSlugPrompt = Console::prompt("Customize the project slug? This controls the DDEV URL, etc.", [ 23 | 'default' => $suggestedProjectSlug, 24 | ]); 25 | 26 | $projectSlug = !empty(trim($projectSlugPrompt)) ? StringHelper::toKebabCase($projectSlugPrompt) : $suggestedProjectSlug; 27 | 28 | Console::output("Great! We'll use $projectSlug"); 29 | 30 | /** 31 | * Update DDEV config 32 | */ 33 | 34 | ScriptHelpers::replaceFileText( 35 | filePath: "$cwd/.ddev/config.yaml", 36 | pattern: "/name:\s+viget-craft-starter/", 37 | replacement: "name: $projectSlug", 38 | ); 39 | 40 | /** 41 | * Update package.json 42 | */ 43 | 44 | ScriptHelpers::replaceFileText( 45 | filePath: "$cwd/package.json", 46 | pattern: "/\"name\": \"viget-craft-starter\"/", 47 | replacement: "\"name\": \"$projectSlug\"", 48 | ); 49 | 50 | ScriptHelpers::replaceFileText( 51 | filePath: "$cwd/package-lock.json", 52 | pattern: "/\"name\": \"viget-craft-starter\"/", 53 | replacement: "\"name\": \"$projectSlug\"", 54 | ); 55 | 56 | /** 57 | * Update project config 58 | */ 59 | 60 | // Replace "Viget Craft Starter" site name in every file in the project config directory. 61 | ScriptHelpers::replaceFileTextInDirectory( 62 | directoryPath: "$cwd/config/project/", 63 | pattern: "/Viget Craft Starter/", 64 | replacement: "$projectName", 65 | ); 66 | 67 | // Replace plugin license keys. 68 | // These are regenerated when viewing the Control Panel 69 | ScriptHelpers::replaceFileText( 70 | filePath: "$cwd/config/project/project.yaml", 71 | pattern: "/ licenseKey: REPLACE[\r\n|\r|\n]/", // Make sure to remove new line too 72 | replacement: "", 73 | ); 74 | 75 | /** 76 | * .gitignore 77 | */ 78 | 79 | ScriptHelpers::replaceFileText( 80 | filePath: "$cwd/.gitignore", 81 | pattern: "/# BEGIN-STARTER-ONLY\X*# END-STARTER-ONLY/m", 82 | replacement: '', 83 | ); 84 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viget/craft-site-starter", 3 | "type": "project", 4 | "license": "0BSD", 5 | "minimum-stability": "dev", 6 | "prefer-stable": true, 7 | "require": { 8 | "craftcms/aws-s3": "2.2.2", 9 | "craftcms/ckeditor": "4.9.0", 10 | "craftcms/cms": "5.7.7", 11 | "mmikkel/cp-field-inspect": "2.0.4", 12 | "nystudio107/craft-emptycoalesce": "5.0.0", 13 | "nystudio107/craft-retour": "5.0.10", 14 | "nystudio107/craft-seomatic": "5.1.13", 15 | "nystudio107/craft-vite": "5.0.1", 16 | "spacecatninja/imager-x": "5.1.3", 17 | "spacecatninja/imager-x-aws-serverless-transformer": "3.0.2", 18 | "spacecatninja/imager-x-power-pack": "1.0.5", 19 | "verbb/expanded-singles": "3.0.2", 20 | "verbb/navigation": "3.0.8", 21 | "viget/craft-classnames": "3.0.0", 22 | "viget/craft-parts-kit": "dev-main", 23 | "vlucas/phpdotenv": "^5.4.0" 24 | }, 25 | "require-dev": { 26 | "craftcms/ecs": "dev-main", 27 | "craftcms/generator": "^2.0.0", 28 | "craftcms/phpstan": "dev-main", 29 | "nystudio107/craft-autocomplete": "^1.12", 30 | "yiisoft/yii2-shell": "^2.0.3" 31 | }, 32 | "autoload": { 33 | "psr-4": { 34 | "modules\\": "modules/" 35 | } 36 | }, 37 | "config": { 38 | "allow-plugins": { 39 | "craftcms/plugin-installer": true, 40 | "yiisoft/yii2-composer": true 41 | }, 42 | "sort-packages": true, 43 | "optimize-autoloader": true, 44 | "platform": { 45 | "php": "8.2" 46 | } 47 | }, 48 | "scripts": { 49 | "post-create-project-cmd": [ 50 | "@php -r \"file_exists('.env') || copy('.env.example.dev', '.env');\"", 51 | "@php composer-scripts/post-create-project.php", 52 | "echo 'Cleaning composer.json'", 53 | "@composer config --unset scripts.post-create-project-cmd", 54 | "@composer config --unset name", 55 | "@composer config --unset license", 56 | "@composer config --unset type", 57 | "@composer update --ignore-platform-reqs", 58 | "@composer dump-autoload -o", 59 | "rm -rf composer-scripts" 60 | ], 61 | "post-root-package-install": [ 62 | "@php -r \"file_exists('.env') || copy('.env.example.dev', '.env');\"" 63 | ], 64 | "ecs-check": "ecs check --ansi", 65 | "ecs-fix": "ecs check --ansi --fix", 66 | "phpstan": "phpstan --memory-limit=1G" 67 | }, 68 | "repositories": [ 69 | { 70 | "type": "composer", 71 | "url": "https://composer.craftcms.com", 72 | "canonical": false 73 | }, 74 | { 75 | "type": "github", 76 | "url": "https://github.com/vigetlabs/craft-parts-kit.git" 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | App::env('CRAFT_APP_ID') ?: 'CraftCMS', 27 | ]; 28 | -------------------------------------------------------------------------------- /config/general.php: -------------------------------------------------------------------------------- 1 | defaultWeekStartDay(1) 17 | // Prevent generated URLs from including "index.php" 18 | ->omitScriptNameInUrls() 19 | // Preload Single entries as Twig variables 20 | ->preloadSingles() 21 | // Prevent user enumeration attacks 22 | ->preventUserEnumeration() 23 | // Set the @webroot alias so the clear-caches command knows where to find CP resources 24 | ->aliases([ 25 | '@webroot' => dirname(__DIR__) . '/web', 26 | ]) 27 | ; 28 | -------------------------------------------------------------------------------- /config/htmlpurifier/Default.json: -------------------------------------------------------------------------------- 1 | { 2 | "Attr.AllowedFrameTargets": ["_blank"], 3 | "Attr.EnableID": true, 4 | "HTML.AllowedComments": ["pagebreak"], 5 | "HTML.SafeIframe": true, 6 | "URI.SafeIframeRegexp": "%^(https?:)?//(www.youtube.com/|player.vimeo.com/)%" 7 | } 8 | -------------------------------------------------------------------------------- /config/imager-x-aws-serverless-transformer.php: -------------------------------------------------------------------------------- 1 | App::env('IMAGERX_SERVERLESS_DISTRIBUTION_URL'), 7 | 'signatureKey' => App::env('IMAGERX_SERVERLESS_DISTRIBUTION_SIGNATURE'), 8 | ]; 9 | -------------------------------------------------------------------------------- /config/imager-x-transforms.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'displayName' => 'Example Named Transform', 22 | 'transforms' => [ 23 | ['width' => 300], 24 | ['width' => 700], 25 | ], 26 | 'defaults' => [ 27 | 'ratio' => 9 / 16, 28 | 'format' => 'webp', 29 | ], 30 | ], 31 | ]; 32 | -------------------------------------------------------------------------------- /config/imager-x.php: -------------------------------------------------------------------------------- 1 | 'awsserverless', 7 | 'removeMetadata' => true, 8 | 'cacheRemoteFiles' => true, 9 | 'allowUpscale' => false, 10 | 'preserveColorProfiles' => true, 11 | 'transformAnimatedGifs' => false, 12 | 'transformSvgs' => false, 13 | 'fillTransforms' => true, 14 | 'imagerUrl' => App::env('S3_BASE_URL') . '/' . App::env('S3_SUBFOLDER') . '/transforms/', 15 | 'storages' => ['aws'], 16 | 'storageConfig' => [ 17 | 'aws' => [ 18 | 'accessKey' => App::env('S3_ACCESS_KEY_ID'), 19 | 'secretAccessKey' => App::env('S3_SECRET_ACCESS_KEY'), 20 | 'region' => App::env('S3_BUCKET_REGION'), 21 | 'bucket' => App::env('S3_BUCKET'), 22 | 'folder' => App::env('S3_SUBFOLDER') . '/transforms', 23 | 'requestHeaders' => [], 24 | 'storageType' => 'standard', 25 | 'public' => false, 26 | 'cloudfrontInvalidateEnabled' => true, 27 | 'cloudfrontDistributionId' => App::env('S3_CLOUDFRONT_DISTRIBUTION_ID'), 28 | ], 29 | ], 30 | ]; 31 | -------------------------------------------------------------------------------- /config/project/ckeditor/configs/b7e66782-af96-4012-9e17-914134073ced.yaml: -------------------------------------------------------------------------------- 1 | headingLevels: 2 | - 1 3 | - 2 4 | - 3 5 | - 4 6 | - 5 7 | - 6 8 | name: Simple 9 | toolbar: 10 | - bold 11 | - italic 12 | - underline 13 | - link 14 | -------------------------------------------------------------------------------- /config/project/ckeditor/configs/d39724b0-dd22-4c74-aa0b-87a022555cf2.yaml: -------------------------------------------------------------------------------- 1 | css: "/* Hides style buttons that don't apply to selection */\r\n.ck-style-grid__button.ck-disabled { display: none!important; }\r\n\r\n.ck.ck-content .rich-text-size-xlarge {\r\n font-size: 32px;\r\n line-height: 1.2;\r\n}\r\n\r\n.ck.ck-content .rich-text-size-large {\r\n font-size: 24px;\r\n line-height: 1.2;\r\n}\r\n\r\n.ck.ck-content .rich-text-size-medium {\r\n font-size: 18px;\r\n line-height: 1.2;\r\n}\r\n\r\n.ck.ck-content .rich-text-size-small {\r\n font-size: 12px;\r\n line-height: 1.2;\r\n}" 2 | headingLevels: false 3 | js: "/**\r\n * Takes a given definition and creates that definition for the tags defined in elements\r\n */\r\nfunction defintionsForElements(definition, elements = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p']) {\r\n return elements.map((element) => ({\r\n ...definition,\r\n element,\r\n name: `${definition.name} - ${element}`\r\n }))\r\n}\r\n\r\ndebugger\r\n\r\nreturn {\r\n list: {\r\n properties: {\r\n styles: false,\r\n },\r\n },\r\n fontSize: {\r\n options: [\r\n 'a',\r\n 'b',\r\n 'c',\r\n 'd',\r\n 'e',\r\n ]\r\n },\r\n style: {\r\n definitions: [\r\n ...defintionsForElements({\r\n name: 'Heading XXL',\r\n classes: [\r\n 'richtext-heading-xxl',\r\n ],\r\n }),\r\n ...defintionsForElements({\r\n name: 'Heading XL',\r\n classes: [\r\n 'richtext-heading-xl',\r\n ],\r\n }),\r\n ...defintionsForElements({\r\n name: 'Heading XL',\r\n classes: [\r\n 'richtext-heading-xl',\r\n ],\r\n })\r\n ],\r\n },\r\n}" 4 | name: Advanced 5 | toolbar: 6 | - undo 7 | - redo 8 | - style 9 | - fontSize 10 | - '|' 11 | - bold 12 | - italic 13 | - underline 14 | - link 15 | - blockQuote 16 | - '|' 17 | - bulletedList 18 | - numberedList 19 | - outdent 20 | - indent 21 | - '|' 22 | - removeFormat 23 | -------------------------------------------------------------------------------- /config/project/entryTypes/callToAction--534ccdd8-7abd-4300-a102-71885b21c126.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | 1c969fb9-3597-4082-8e64-34c1c9d9a30e: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | autocapitalize: true 10 | autocomplete: false 11 | autocorrect: true 12 | class: null 13 | dateAdded: '2024-10-01T00:05:01+00:00' 14 | disabled: false 15 | elementCondition: null 16 | id: null 17 | includeInCards: false 18 | inputType: null 19 | instructions: null 20 | label: null 21 | max: null 22 | min: null 23 | name: null 24 | orientation: null 25 | placeholder: null 26 | providesThumbs: false 27 | readonly: false 28 | required: true 29 | size: null 30 | step: null 31 | tip: null 32 | title: null 33 | type: craft\fieldlayoutelements\entries\EntryTitleField 34 | uid: eee9050d-ab79-46d2-87ee-878855f72e52 35 | userCondition: null 36 | warning: null 37 | width: 100 38 | - 39 | dateAdded: '2024-10-01T13:11:53+00:00' 40 | elementCondition: null 41 | fieldUid: c52a9170-652b-4d92-a226-69894b1822ed # Rich Text: Simple 42 | handle: null 43 | includeInCards: false 44 | instructions: null 45 | label: Description 46 | providesThumbs: false 47 | required: false 48 | tip: null 49 | type: craft\fieldlayoutelements\CustomField 50 | uid: ba1291b5-b2a2-4ca5-b843-6373de152e83 51 | userCondition: null 52 | warning: null 53 | width: 100 54 | - 55 | dateAdded: '2024-10-01T00:12:31+00:00' 56 | elementCondition: null 57 | type: craft\fieldlayoutelements\HorizontalRule 58 | uid: 484dde25-62c7-4238-aea8-6b652747f0e5 59 | userCondition: null 60 | - 61 | dateAdded: '2025-01-03T17:45:49+00:00' 62 | elementCondition: null 63 | fieldUid: 2ea51656-9b0c-4736-a6fe-c95dc805dc60 # Button 64 | handle: null 65 | includeInCards: false 66 | instructions: null 67 | label: null 68 | providesThumbs: false 69 | required: false 70 | tip: null 71 | type: craft\fieldlayoutelements\CustomField 72 | uid: 765e759a-f61a-4cfa-b03c-9906bd4bdfe6 73 | userCondition: null 74 | warning: null 75 | width: 100 76 | name: Content 77 | uid: 8f12bd58-cd2c-4be0-9371-9e66d9828ff5 78 | userCondition: null 79 | handle: callToAction 80 | hasTitleField: true 81 | icon: diagram-next 82 | name: 'Call To Action' 83 | showSlugField: true 84 | showStatusField: true 85 | slugTranslationKeyFormat: null 86 | slugTranslationMethod: site 87 | titleFormat: null 88 | titleTranslationKeyFormat: null 89 | titleTranslationMethod: site 90 | -------------------------------------------------------------------------------- /config/project/entryTypes/cardGrid--7ced3e9d-9b54-47f6-8103-e5c3a4fbaf9c.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | 20f64bfb-c1fa-4afa-9631-7660c7cdeb37: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | dateAdded: '2024-10-02T23:56:36+00:00' 10 | elementCondition: null 11 | fieldUid: 4382f55f-01a1-4b67-84c8-ebbc89b238d2 # Heading 12 | handle: null 13 | includeInCards: false 14 | instructions: null 15 | label: null 16 | providesThumbs: false 17 | required: false 18 | tip: null 19 | type: craft\fieldlayoutelements\CustomField 20 | uid: dbdfb37c-efcb-4c7f-a367-c9bf274977ed 21 | userCondition: null 22 | warning: null 23 | width: 100 24 | - 25 | dateAdded: '2024-09-30T23:33:26+00:00' 26 | elementCondition: null 27 | fieldUid: 5e84b0b7-6851-47ed-962e-76498ac9476f # Card Grid 28 | handle: null 29 | includeInCards: false 30 | instructions: null 31 | label: null 32 | providesThumbs: false 33 | required: false 34 | tip: null 35 | type: craft\fieldlayoutelements\CustomField 36 | uid: 34ece3df-7fa2-439f-985c-2cd74abfd1e3 37 | userCondition: null 38 | warning: null 39 | width: 100 40 | name: Content 41 | uid: be2ae502-0ddb-4540-a73b-eecc45b4753a 42 | userCondition: null 43 | handle: cardGrid 44 | hasTitleField: false 45 | icon: grid 46 | name: 'Card Grid' 47 | showSlugField: false 48 | showStatusField: true 49 | slugTranslationKeyFormat: null 50 | slugTranslationMethod: site 51 | titleFormat: null 52 | titleTranslationKeyFormat: null 53 | titleTranslationMethod: site 54 | -------------------------------------------------------------------------------- /config/project/entryTypes/codeBlock--cbf3aeac-588c-4aeb-9573-6f1920206abf.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | e399cfbc-ad49-4346-af55-44c91bafc80c: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | dateAdded: '2025-03-10T16:53:04+00:00' 10 | elementCondition: null 11 | fieldUid: f7d30e72-f872-487a-aba1-c8e95268a220 # Code Position 12 | handle: null 13 | includeInCards: false 14 | instructions: null 15 | label: null 16 | providesThumbs: false 17 | required: false 18 | tip: null 19 | type: craft\fieldlayoutelements\CustomField 20 | uid: 0945a6dc-8201-4deb-bbad-dc2af0e0dd9b 21 | userCondition: null 22 | warning: null 23 | width: 100 24 | - 25 | dateAdded: '2025-03-10T17:28:48+00:00' 26 | elementCondition: null 27 | fieldUid: a99edea2-f8ae-44e5-a12f-89cb9aa66738 # Description 28 | handle: null 29 | includeInCards: false 30 | instructions: null 31 | label: null 32 | providesThumbs: false 33 | required: false 34 | tip: "Add a brief description of your code block. \r\n\r\nThis will never appear on the front end of the site. " 35 | type: craft\fieldlayoutelements\CustomField 36 | uid: 1b062515-de1a-4a90-b9e7-368032fe47e7 37 | userCondition: null 38 | warning: null 39 | width: 100 40 | - 41 | dateAdded: '2025-03-10T16:44:51+00:00' 42 | elementCondition: null 43 | fieldUid: 7a701601-ee6c-4d56-8bd0-efa7719f6a67 # Code 44 | handle: null 45 | includeInCards: false 46 | instructions: null 47 | label: null 48 | providesThumbs: false 49 | required: false 50 | tip: null 51 | type: craft\fieldlayoutelements\CustomField 52 | uid: 9848de68-0b9e-4a27-a38c-34a7f68eeaba 53 | userCondition: null 54 | warning: 'Use Caution: Improperly formatted code can break pages.' 55 | width: 100 56 | name: Content 57 | uid: 39937348-1f3d-4fa6-aaf3-cffe7a6c2a13 58 | userCondition: null 59 | handle: codeBlock 60 | hasTitleField: false 61 | icon: code 62 | name: 'Code Block' 63 | showSlugField: false 64 | showStatusField: false 65 | slugTranslationKeyFormat: null 66 | slugTranslationMethod: site 67 | titleFormat: null 68 | titleTranslationKeyFormat: null 69 | titleTranslationMethod: site 70 | -------------------------------------------------------------------------------- /config/project/entryTypes/globalCode--25362218-e66c-494e-9f2c-63e8cbc6ce0a.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | f275bbb7-5f45-46ad-8feb-16f35f683456: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | dateAdded: '2025-03-10T17:00:59+00:00' 10 | dismissible: false 11 | elementCondition: null 12 | style: warning 13 | tip: "**Use Caution:** Improperly formatted code can break pages. \r\n\r\nBe sure to wrap any JavaScript in opening and closing tags. \r\n\r\n " 14 | type: craft\fieldlayoutelements\Tip 15 | uid: 6dae3c5a-5842-433f-93ff-8f5696852098 16 | userCondition: null 17 | - 18 | content: "## Instructions\r\n\r\n**Code Positions**\r\n\r\n- **Start of
** - Code is loaded at the beginning of the tag. Only use when absolutely required.\r\n- **End of ** - Code is loaded at the end of the .\r\n- **Start of ** - Code is loaded at the beginning of the tag. \r\n- **End of ** - Code is loaded at the bottom of the tag after all other scripts, styles and markup has loaded. \r\nThis option has the lowest impact on page speed. " 19 | dateAdded: '2025-03-10T17:02:50+00:00' 20 | displayInPane: true 21 | elementCondition: null 22 | type: craft\fieldlayoutelements\Markdown 23 | uid: c4baee17-adfa-4390-a757-7697c5e4752a 24 | userCondition: null 25 | width: 100 26 | - 27 | dateAdded: '2025-03-10T16:49:09+00:00' 28 | elementCondition: null 29 | fieldUid: 9c7dc3c3-cb8c-4167-880d-ab9426eef873 # Code Blocks 30 | handle: null 31 | includeInCards: false 32 | instructions: null 33 | label: null 34 | providesThumbs: false 35 | required: false 36 | tip: null 37 | type: craft\fieldlayoutelements\CustomField 38 | uid: c37c8413-d135-4e9e-8d12-7ebca4b5662f 39 | userCondition: null 40 | warning: null 41 | width: 100 42 | name: Content 43 | uid: 0cc45244-3937-457a-899e-6f786bb6b0a4 44 | userCondition: null 45 | handle: globalCode 46 | hasTitleField: false 47 | icon: code 48 | name: 'Global Code' 49 | showSlugField: false 50 | showStatusField: false 51 | slugTranslationKeyFormat: null 52 | slugTranslationMethod: site 53 | titleFormat: null 54 | titleTranslationKeyFormat: null 55 | titleTranslationMethod: site 56 | -------------------------------------------------------------------------------- /config/project/entryTypes/heading--e445a3b9-5827-422a-8328-6b10449fa891.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | 506cf507-9ade-49bb-a2d1-82b7a13493c8: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | autocapitalize: true 10 | autocomplete: false 11 | autocorrect: true 12 | class: null 13 | dateAdded: '2024-10-02T21:54:11+00:00' 14 | disabled: false 15 | elementCondition: null 16 | id: null 17 | includeInCards: false 18 | inputType: null 19 | instructions: null 20 | label: null 21 | max: null 22 | min: null 23 | name: null 24 | orientation: null 25 | placeholder: null 26 | providesThumbs: false 27 | readonly: false 28 | requirable: false 29 | size: null 30 | step: null 31 | tip: null 32 | title: null 33 | type: craft\fieldlayoutelements\entries\EntryTitleField 34 | uid: 96628d9f-2772-4b53-b6fc-7a4108ed43f3 35 | userCondition: null 36 | warning: null 37 | width: 100 38 | - 39 | dateAdded: '2024-10-02T22:19:47+00:00' 40 | elementCondition: null 41 | fieldUid: 4382f55f-01a1-4b67-84c8-ebbc89b238d2 # Heading 42 | handle: null 43 | includeInCards: false 44 | instructions: null 45 | label: null 46 | providesThumbs: false 47 | required: true 48 | tip: null 49 | type: craft\fieldlayoutelements\CustomField 50 | uid: 7f551dd8-de08-4ab1-bd9a-cb6c3a17915e 51 | userCondition: null 52 | warning: null 53 | width: 100 54 | name: Content 55 | uid: 5455a7fa-e8af-4d57-ab81-16c5aabd6f30 56 | userCondition: null 57 | handle: heading 58 | hasTitleField: false 59 | icon: text 60 | name: Heading 61 | showSlugField: false 62 | showStatusField: true 63 | slugTranslationKeyFormat: null 64 | slugTranslationMethod: site 65 | titleFormat: '' 66 | titleTranslationKeyFormat: null 67 | titleTranslationMethod: site 68 | -------------------------------------------------------------------------------- /config/project/entryTypes/home--0e7762a5-2553-4c0d-b8af-9b43b59524bf.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | 1ba4cf8b-7fa5-48a1-bedc-228107cc529a: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | autocapitalize: true 10 | autocomplete: false 11 | autocorrect: true 12 | class: null 13 | dateAdded: '2024-09-30T22:56:28+00:00' 14 | disabled: false 15 | elementCondition: null 16 | id: null 17 | includeInCards: false 18 | inputType: null 19 | instructions: null 20 | label: null 21 | max: null 22 | min: null 23 | name: null 24 | orientation: null 25 | placeholder: null 26 | providesThumbs: false 27 | readonly: false 28 | requirable: false 29 | size: null 30 | step: null 31 | tip: null 32 | title: null 33 | type: craft\fieldlayoutelements\entries\EntryTitleField 34 | uid: ea0cb902-1247-4433-bd52-2cccebaa964c 35 | userCondition: null 36 | warning: null 37 | width: 100 38 | - 39 | dateAdded: '2024-09-30T23:01:15+00:00' 40 | elementCondition: null 41 | fieldUid: 7bd21dd3-6b12-4163-8432-030ea6a3f8d3 # Page Blocks 42 | handle: null 43 | includeInCards: false 44 | instructions: null 45 | label: null 46 | providesThumbs: false 47 | required: false 48 | tip: null 49 | type: craft\fieldlayoutelements\CustomField 50 | uid: c2b7fef9-1532-475d-88ab-66770a63c552 51 | userCondition: null 52 | warning: null 53 | width: 100 54 | name: Content 55 | uid: a5f66f1f-782a-4b31-978c-9c9f79c9af26 56 | userCondition: null 57 | handle: home 58 | hasTitleField: false 59 | icon: house 60 | name: Home 61 | showSlugField: false 62 | showStatusField: true 63 | slugTranslationKeyFormat: null 64 | slugTranslationMethod: site 65 | titleFormat: Home 66 | titleTranslationKeyFormat: null 67 | titleTranslationMethod: site 68 | -------------------------------------------------------------------------------- /config/project/entryTypes/iconCard--3f1dc0c5-f091-469a-858a-4cbd3596bab7.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | 57d6dbf5-4050-46e9-b1d8-2990c925c04c: 4 | cardView: 5 | - 'layoutElement:93e23b5a-05ee-4ba1-9ae8-b4a7471b69e1' 6 | - 'layoutElement:e44a04d0-1ede-4985-9d10-8e2c13dfc7d9' 7 | tabs: 8 | - 9 | elementCondition: null 10 | elements: 11 | - 12 | dateAdded: '2024-09-30T23:33:06+00:00' 13 | elementCondition: null 14 | fieldUid: 0011a64a-91b6-4aa3-98e6-be048394a2cf # Icon 15 | handle: null 16 | includeInCards: true 17 | instructions: null 18 | label: null 19 | providesThumbs: false 20 | required: false 21 | tip: null 22 | type: craft\fieldlayoutelements\CustomField 23 | uid: 93e23b5a-05ee-4ba1-9ae8-b4a7471b69e1 24 | userCondition: null 25 | warning: null 26 | width: 100 27 | - 28 | dateAdded: '2024-09-30T23:33:06+00:00' 29 | elementCondition: null 30 | fieldUid: 69fe4c18-21c9-4a3d-8fce-9988d3f741e4 # Link 31 | handle: null 32 | includeInCards: false 33 | instructions: null 34 | label: null 35 | providesThumbs: false 36 | required: false 37 | tip: null 38 | type: craft\fieldlayoutelements\CustomField 39 | uid: 7a0ed038-606f-41eb-a3a3-c5783a9e4df4 40 | userCondition: null 41 | warning: null 42 | width: 100 43 | - 44 | autocapitalize: true 45 | autocomplete: false 46 | autocorrect: true 47 | class: null 48 | dateAdded: '2024-09-30T23:29:31+00:00' 49 | disabled: false 50 | elementCondition: null 51 | id: null 52 | includeInCards: false 53 | inputType: null 54 | instructions: null 55 | label: null 56 | max: null 57 | min: null 58 | name: null 59 | orientation: null 60 | placeholder: null 61 | providesThumbs: false 62 | readonly: false 63 | required: true 64 | size: null 65 | step: null 66 | tip: null 67 | title: null 68 | type: craft\fieldlayoutelements\entries\EntryTitleField 69 | uid: 2a49c922-8c52-4df2-8069-e87e89e2f03e 70 | userCondition: null 71 | warning: null 72 | width: 100 73 | - 74 | dateAdded: '2024-09-30T23:33:06+00:00' 75 | elementCondition: null 76 | fieldUid: a99edea2-f8ae-44e5-a12f-89cb9aa66738 # Description 77 | handle: null 78 | includeInCards: true 79 | instructions: null 80 | label: null 81 | providesThumbs: false 82 | required: false 83 | tip: null 84 | type: craft\fieldlayoutelements\CustomField 85 | uid: e44a04d0-1ede-4985-9d10-8e2c13dfc7d9 86 | userCondition: null 87 | warning: null 88 | width: 100 89 | name: Content 90 | uid: 3eca7200-b91a-4369-98b2-54b2d5970c79 91 | userCondition: null 92 | handle: iconCard 93 | hasTitleField: true 94 | icon: icons 95 | name: 'Icon Card' 96 | showSlugField: false 97 | showStatusField: false 98 | slugTranslationKeyFormat: null 99 | slugTranslationMethod: site 100 | titleFormat: null 101 | titleTranslationKeyFormat: null 102 | titleTranslationMethod: site 103 | -------------------------------------------------------------------------------- /config/project/entryTypes/imageCard--7d418368-91eb-4c64-8f5b-94c62cd62359.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | 35c4a5cf-04f0-400e-a3bd-107187ab73ee: 4 | cardView: 5 | - 'layoutElement:137a7e8f-bd2a-46c9-972b-365f2ea8a1b7' 6 | - 'layoutElement:14a7db31-c0d3-47d5-a03a-24b0bba82130' 7 | tabs: 8 | - 9 | elementCondition: null 10 | elements: 11 | - 12 | dateAdded: '2024-09-30T23:29:23+00:00' 13 | elementCondition: null 14 | fieldUid: 570fb481-ad97-46db-8bad-f7b0fd90e831 # Image 15 | handle: null 16 | includeInCards: true 17 | instructions: null 18 | label: null 19 | providesThumbs: false 20 | required: false 21 | tip: null 22 | type: craft\fieldlayoutelements\CustomField 23 | uid: 137a7e8f-bd2a-46c9-972b-365f2ea8a1b7 24 | userCondition: null 25 | warning: null 26 | width: 100 27 | - 28 | dateAdded: '2024-09-30T23:29:23+00:00' 29 | elementCondition: null 30 | fieldUid: 69fe4c18-21c9-4a3d-8fce-9988d3f741e4 # Link 31 | handle: null 32 | includeInCards: false 33 | instructions: null 34 | label: null 35 | providesThumbs: false 36 | required: false 37 | tip: null 38 | type: craft\fieldlayoutelements\CustomField 39 | uid: c76db590-6bba-4a59-9353-adbf9eeb9cf6 40 | userCondition: null 41 | warning: null 42 | width: 100 43 | - 44 | autocapitalize: true 45 | autocomplete: false 46 | autocorrect: true 47 | class: null 48 | dateAdded: '2024-09-30T23:24:56+00:00' 49 | disabled: false 50 | elementCondition: null 51 | id: null 52 | includeInCards: false 53 | inputType: null 54 | instructions: null 55 | label: null 56 | max: null 57 | min: null 58 | name: null 59 | orientation: null 60 | placeholder: null 61 | providesThumbs: false 62 | readonly: false 63 | required: true 64 | size: null 65 | step: null 66 | tip: null 67 | title: null 68 | type: craft\fieldlayoutelements\entries\EntryTitleField 69 | uid: 860a8146-8741-437e-95e0-b4e2bf886d5f 70 | userCondition: null 71 | warning: null 72 | width: 100 73 | - 74 | dateAdded: '2024-09-30T23:29:23+00:00' 75 | elementCondition: null 76 | fieldUid: a99edea2-f8ae-44e5-a12f-89cb9aa66738 # Description 77 | handle: null 78 | includeInCards: true 79 | instructions: null 80 | label: null 81 | providesThumbs: false 82 | required: false 83 | tip: null 84 | type: craft\fieldlayoutelements\CustomField 85 | uid: 14a7db31-c0d3-47d5-a03a-24b0bba82130 86 | userCondition: null 87 | warning: null 88 | width: 100 89 | name: Content 90 | uid: 2d299e0f-b490-4172-874c-983cf1b2cd4f 91 | userCondition: null 92 | handle: imageCard 93 | hasTitleField: true 94 | icon: image-polaroid 95 | name: 'Image Card' 96 | showSlugField: false 97 | showStatusField: false 98 | slugTranslationKeyFormat: null 99 | slugTranslationMethod: site 100 | titleFormat: null 101 | titleTranslationKeyFormat: null 102 | titleTranslationMethod: site 103 | -------------------------------------------------------------------------------- /config/project/entryTypes/pageHero--27f19bae-64f8-47b8-9fc9-7552e11e2656.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | 4fea0032-240b-4dbe-b1b6-a467326f5323: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | autocapitalize: true 10 | autocomplete: false 11 | autocorrect: true 12 | class: null 13 | dateAdded: '2024-10-01T13:27:07+00:00' 14 | disabled: false 15 | elementCondition: null 16 | id: null 17 | includeInCards: false 18 | inputType: null 19 | instructions: null 20 | label: null 21 | max: null 22 | min: null 23 | name: null 24 | orientation: null 25 | placeholder: null 26 | providesThumbs: false 27 | readonly: false 28 | requirable: false 29 | size: null 30 | step: null 31 | tip: null 32 | title: null 33 | type: craft\fieldlayoutelements\entries\EntryTitleField 34 | uid: 77b77d44-0b65-428f-ba8f-f078760a3ff8 35 | userCondition: null 36 | warning: null 37 | width: 100 38 | - 39 | dateAdded: '2024-10-01T13:31:02+00:00' 40 | elementCondition: null 41 | fieldUid: c52a9170-652b-4d92-a226-69894b1822ed # Rich Text: Simple 42 | handle: null 43 | includeInCards: false 44 | instructions: null 45 | label: Description 46 | providesThumbs: false 47 | required: false 48 | tip: null 49 | type: craft\fieldlayoutelements\CustomField 50 | uid: dcf0db81-9675-40bc-ae62-5f69274da598 51 | userCondition: null 52 | warning: null 53 | width: 100 54 | - 55 | dateAdded: '2024-10-01T13:31:02+00:00' 56 | elementCondition: null 57 | fieldUid: 570fb481-ad97-46db-8bad-f7b0fd90e831 # Image 58 | handle: null 59 | includeInCards: false 60 | instructions: null 61 | label: null 62 | providesThumbs: false 63 | required: false 64 | tip: null 65 | type: craft\fieldlayoutelements\CustomField 66 | uid: 252b484d-2307-4e74-b167-a3c63074ae10 67 | userCondition: null 68 | warning: null 69 | width: 100 70 | name: Content 71 | uid: 232fbbf7-98ae-45f0-992d-e4597db12aad 72 | userCondition: null 73 | handle: pageHero 74 | hasTitleField: true 75 | icon: subtitles 76 | name: 'Page Hero' 77 | showSlugField: false 78 | showStatusField: true 79 | slugTranslationKeyFormat: null 80 | slugTranslationMethod: site 81 | titleFormat: '' 82 | titleTranslationKeyFormat: null 83 | titleTranslationMethod: site 84 | -------------------------------------------------------------------------------- /config/project/entryTypes/richText--896b8f2a-ed0c-42c9-b5fd-ba8668fc6784.yaml: -------------------------------------------------------------------------------- 1 | color: null 2 | fieldLayouts: 3 | e33f8044-cf16-4605-bc3d-09679348a498: 4 | tabs: 5 | - 6 | elementCondition: null 7 | elements: 8 | - 9 | autocapitalize: true 10 | autocomplete: false 11 | autocorrect: true 12 | class: null 13 | dateAdded: '2024-09-30T22:58:38+00:00' 14 | disabled: false 15 | elementCondition: null 16 | id: null 17 | includeInCards: false 18 | inputType: null 19 | instructions: null 20 | label: null 21 | max: null 22 | min: null 23 | name: null 24 | orientation: null 25 | placeholder: null 26 | providesThumbs: false 27 | readonly: false 28 | requirable: false 29 | size: null 30 | step: null 31 | tip: null 32 | title: null 33 | type: craft\fieldlayoutelements\entries\EntryTitleField 34 | uid: 205c8050-85f3-478e-b411-c7e6073f9b3e 35 | userCondition: null 36 | warning: null 37 | width: 100 38 | - 39 | dateAdded: '2024-09-30T23:04:32+00:00' 40 | elementCondition: null 41 | fieldUid: cd489d3c-f914-475c-a270-ab926e4e7485 # Rich Text 42 | handle: null 43 | includeInCards: false 44 | instructions: null 45 | label: null 46 | providesThumbs: false 47 | required: false 48 | tip: null 49 | type: craft\fieldlayoutelements\CustomField 50 | uid: 0fc08c7a-1dfa-40d0-b234-5540eae14b50 51 | userCondition: null 52 | warning: null 53 | width: 100 54 | name: Content 55 | uid: b1d8412f-75ff-4e81-896b-ef3b9e203f18 56 | userCondition: null 57 | handle: richText 58 | hasTitleField: false 59 | icon: font-case 60 | name: 'Rich Text' 61 | showSlugField: false 62 | showStatusField: true 63 | slugTranslationKeyFormat: null 64 | slugTranslationMethod: site 65 | titleFormat: '' 66 | titleTranslationKeyFormat: null 67 | titleTranslationMethod: site 68 | -------------------------------------------------------------------------------- /config/project/fields/basicLink--69fe4c18-21c9-4a3d-8fce-9988d3f741e4.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: basicLink 3 | instructions: null 4 | name: Link 5 | searchable: false 6 | settings: 7 | maxLength: 255 8 | showLabelField: false 9 | showTargetField: true 10 | typeSettings: 11 | __assoc__: 12 | - 13 | - url 14 | - 15 | __assoc__: 16 | - 17 | - allowRootRelativeUrls 18 | - '1' 19 | - 20 | - allowAnchors 21 | - '1' 22 | - 23 | - asset 24 | - 25 | __assoc__: 26 | - 27 | - sources 28 | - '*' 29 | - 30 | - allowedKinds 31 | - '*' 32 | - 33 | - showUnpermittedVolumes 34 | - '' 35 | - 36 | - showUnpermittedFiles 37 | - '' 38 | - 39 | - entry 40 | - 41 | __assoc__: 42 | - 43 | - sources 44 | - '*' 45 | types: 46 | - url 47 | - asset 48 | - email 49 | - entry 50 | - tel 51 | translationKeyFormat: null 52 | translationMethod: none 53 | type: craft\fields\Link 54 | -------------------------------------------------------------------------------- /config/project/fields/button--2ea51656-9b0c-4736-a6fe-c95dc805dc60.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: button 3 | instructions: null 4 | name: Button 5 | searchable: false 6 | settings: 7 | maxLength: 255 8 | showLabelField: true 9 | showTargetField: true 10 | typeSettings: 11 | __assoc__: 12 | - 13 | - entry 14 | - 15 | __assoc__: 16 | - 17 | - sources 18 | - '*' 19 | - 20 | - url 21 | - 22 | __assoc__: 23 | - 24 | - allowRootRelativeUrls 25 | - '' 26 | - 27 | - allowAnchors 28 | - '' 29 | - 30 | - asset 31 | - 32 | __assoc__: 33 | - 34 | - sources 35 | - '*' 36 | - 37 | - allowedKinds 38 | - '*' 39 | - 40 | - showUnpermittedVolumes 41 | - '' 42 | - 43 | - showUnpermittedFiles 44 | - '' 45 | types: 46 | - entry 47 | - url 48 | - asset 49 | - email 50 | - tel 51 | translationKeyFormat: null 52 | translationMethod: none 53 | type: craft\fields\Link 54 | -------------------------------------------------------------------------------- /config/project/fields/cardGrid--5e84b0b7-6851-47ed-962e-76498ac9476f.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: cardGrid 3 | instructions: null 4 | name: 'Card Grid' 5 | searchable: false 6 | settings: 7 | createButtonLabel: 'New card' 8 | defaultIndexViewMode: cards 9 | entryTypes: 10 | - 7d418368-91eb-4c64-8f5b-94c62cd62359 # Image Card 11 | - 3f1dc0c5-f091-469a-858a-4cbd3596bab7 # Icon Card 12 | includeTableView: false 13 | maxEntries: null 14 | minEntries: null 15 | pageSize: 50 16 | propagationKeyFormat: null 17 | propagationMethod: all 18 | showCardsInGrid: true 19 | viewMode: cards 20 | translationKeyFormat: null 21 | translationMethod: site 22 | type: craft\fields\Matrix 23 | -------------------------------------------------------------------------------- /config/project/fields/code--7a701601-ee6c-4d56-8bd0-efa7719f6a67.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: code 3 | instructions: null 4 | name: Code 5 | searchable: false 6 | settings: 7 | byteLimit: null 8 | charLimit: null 9 | code: true 10 | initialRows: 4 11 | multiline: true 12 | placeholder: null 13 | uiMode: normal 14 | translationKeyFormat: null 15 | translationMethod: none 16 | type: craft\fields\PlainText 17 | -------------------------------------------------------------------------------- /config/project/fields/codeBlocks--9c7dc3c3-cb8c-4167-880d-ab9426eef873.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: codeBlocks 3 | instructions: null 4 | name: 'Code Blocks' 5 | searchable: false 6 | settings: 7 | createButtonLabel: 'Add Code Block' 8 | defaultIndexViewMode: cards 9 | entryTypes: 10 | - 11 | __assoc__: 12 | - 13 | - uid 14 | - cbf3aeac-588c-4aeb-9573-6f1920206abf # Code Block 15 | includeTableView: false 16 | maxEntries: null 17 | minEntries: null 18 | pageSize: null 19 | propagationKeyFormat: null 20 | propagationMethod: all 21 | showCardsInGrid: false 22 | viewMode: blocks 23 | translationKeyFormat: null 24 | translationMethod: site 25 | type: craft\fields\Matrix 26 | -------------------------------------------------------------------------------- /config/project/fields/codePosition--f7d30e72-f872-487a-aba1-c8e95268a220.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: codePosition 3 | instructions: null 4 | name: 'Code Position' 5 | searchable: false 6 | settings: 7 | customOptions: false 8 | options: 9 | - 10 | __assoc__: 11 | - 12 | - label 13 | - 'Start of ' 14 | - 15 | - value 16 | - headTop 17 | - 18 | - default 19 | - '' 20 | - 21 | __assoc__: 22 | - 23 | - label 24 | - 'End of ' 25 | - 26 | - value 27 | - headBottom 28 | - 29 | - default 30 | - '1' 31 | - 32 | __assoc__: 33 | - 34 | - label 35 | - 'Start of ' 36 | - 37 | - value 38 | - bodyTop 39 | - 40 | - default 41 | - '' 42 | - 43 | __assoc__: 44 | - 45 | - label 46 | - 'End of ' 47 | - 48 | - value 49 | - bodyBottom 50 | - 51 | - default 52 | - '' 53 | translationKeyFormat: null 54 | translationMethod: none 55 | type: craft\fields\Dropdown 56 | -------------------------------------------------------------------------------- /config/project/fields/description--a99edea2-f8ae-44e5-a12f-89cb9aa66738.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: description 3 | instructions: null 4 | name: Description 5 | searchable: false 6 | settings: 7 | byteLimit: null 8 | charLimit: null 9 | code: false 10 | initialRows: 2 11 | multiline: true 12 | placeholder: null 13 | uiMode: normal 14 | translationKeyFormat: null 15 | translationMethod: none 16 | type: craft\fields\PlainText 17 | -------------------------------------------------------------------------------- /config/project/fields/heading--4382f55f-01a1-4b67-84c8-ebbc89b238d2.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: heading 3 | instructions: null 4 | name: Heading 5 | searchable: false 6 | settings: 7 | byteLimit: null 8 | charLimit: null 9 | code: false 10 | initialRows: 1 11 | multiline: true 12 | placeholder: null 13 | uiMode: normal 14 | translationKeyFormat: null 15 | translationMethod: none 16 | type: craft\fields\PlainText 17 | -------------------------------------------------------------------------------- /config/project/fields/icon--0011a64a-91b6-4aa3-98e6-be048394a2cf.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: icon 3 | instructions: null 4 | name: Icon 5 | searchable: false 6 | settings: 7 | options: 8 | - 9 | __assoc__: 10 | - 11 | - label 12 | - None 13 | - 14 | - value 15 | - '' 16 | - 17 | - default 18 | - '1' 19 | - 20 | __assoc__: 21 | - 22 | - label 23 | - 'Arrow Left' 24 | - 25 | - value 26 | - arrow-left 27 | - 28 | - default 29 | - '' 30 | - 31 | __assoc__: 32 | - 33 | - label 34 | - 'Arrow Right' 35 | - 36 | - value 37 | - arrowRight 38 | - 39 | - default 40 | - '' 41 | - 42 | __assoc__: 43 | - 44 | - label 45 | - Clock 46 | - 47 | - value 48 | - clock 49 | - 50 | - default 51 | - '' 52 | - 53 | __assoc__: 54 | - 55 | - label 56 | - Close 57 | - 58 | - value 59 | - close 60 | - 61 | - default 62 | - '' 63 | translationKeyFormat: null 64 | translationMethod: none 65 | type: craft\fields\Dropdown 66 | -------------------------------------------------------------------------------- /config/project/fields/image--570fb481-ad97-46db-8bad-f7b0fd90e831.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: image 3 | instructions: null 4 | name: Image 5 | searchable: false 6 | settings: 7 | allowSelfRelations: false 8 | allowSubfolders: false 9 | allowUploads: true 10 | allowedKinds: 11 | - image 12 | branchLimit: null 13 | defaultUploadLocationSource: 'volume:853413e4-e02c-487e-81a5-04e58eb18683' # Assets 14 | defaultUploadLocationSubpath: null 15 | maintainHierarchy: false 16 | maxRelations: 1 17 | minRelations: null 18 | previewMode: full 19 | restrictFiles: true 20 | restrictLocation: false 21 | restrictedDefaultUploadSubpath: null 22 | restrictedLocationSource: 'volume:853413e4-e02c-487e-81a5-04e58eb18683' # Assets 23 | restrictedLocationSubpath: null 24 | selectionLabel: 'Add image' 25 | showCardsInGrid: false 26 | showSiteMenu: false 27 | showUnpermittedFiles: false 28 | showUnpermittedVolumes: false 29 | sources: '*' 30 | targetSiteId: null 31 | validateRelatedElements: false 32 | viewMode: list 33 | translationKeyFormat: null 34 | translationMethod: none 35 | type: craft\fields\Assets 36 | -------------------------------------------------------------------------------- /config/project/fields/mediaType--ac3b0590-d417-429e-aa1f-96be3c79a5b0.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: mediaType 3 | instructions: null 4 | name: 'Media Type' 5 | searchable: false 6 | settings: 7 | options: 8 | - 9 | __assoc__: 10 | - 11 | - label 12 | - Image 13 | - 14 | - value 15 | - image 16 | - 17 | - default 18 | - '1' 19 | - 20 | __assoc__: 21 | - 22 | - label 23 | - Video 24 | - 25 | - value 26 | - video 27 | - 28 | - default 29 | - '' 30 | translationKeyFormat: null 31 | translationMethod: none 32 | type: craft\fields\RadioButtons 33 | -------------------------------------------------------------------------------- /config/project/fields/pageBlocks--7bd21dd3-6b12-4163-8432-030ea6a3f8d3.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: pageBlocks 3 | instructions: null 4 | name: 'Page Blocks' 5 | searchable: false 6 | settings: 7 | createButtonLabel: 'New Block' 8 | defaultIndexViewMode: cards 9 | entryTypes: 10 | - 27f19bae-64f8-47b8-9fc9-7552e11e2656 # Page Hero 11 | - e445a3b9-5827-422a-8328-6b10449fa891 # Heading 12 | - 896b8f2a-ed0c-42c9-b5fd-ba8668fc6784 # Rich Text 13 | - 3bcf7ddb-71e7-4115-868c-815b3611b34c # Text With Media 14 | - 7ced3e9d-9b54-47f6-8103-e5c3a4fbaf9c # Card Grid 15 | - 534ccdd8-7abd-4300-a102-71885b21c126 # Call To Action 16 | includeTableView: false 17 | maxEntries: null 18 | minEntries: null 19 | pageSize: null 20 | propagationKeyFormat: null 21 | propagationMethod: all 22 | showCardsInGrid: false 23 | viewMode: blocks 24 | translationKeyFormat: null 25 | translationMethod: site 26 | type: craft\fields\Matrix 27 | -------------------------------------------------------------------------------- /config/project/fields/richText--cd489d3c-f914-475c-a270-ab926e4e7485.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: richText 3 | instructions: null 4 | name: 'Rich Text' 5 | searchable: false 6 | settings: 7 | availableTransforms: '' 8 | availableVolumes: '*' 9 | ckeConfig: d39724b0-dd22-4c74-aa0b-87a022555cf2 # Advanced 10 | createButtonLabel: null 11 | defaultTransform: null 12 | enableSourceEditingForNonAdmins: false 13 | purifierConfig: null 14 | purifyHtml: true 15 | showUnpermittedFiles: false 16 | showUnpermittedVolumes: false 17 | showWordCount: false 18 | wordLimit: null 19 | translationKeyFormat: null 20 | translationMethod: none 21 | type: craft\ckeditor\Field 22 | -------------------------------------------------------------------------------- /config/project/fields/richTextSimple--c52a9170-652b-4d92-a226-69894b1822ed.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: richTextSimple 3 | instructions: null 4 | name: 'Rich Text: Simple' 5 | searchable: false 6 | settings: 7 | availableTransforms: '' 8 | availableVolumes: '*' 9 | ckeConfig: b7e66782-af96-4012-9e17-914134073ced # Simple 10 | createButtonLabel: null 11 | defaultTransform: null 12 | enableSourceEditingForNonAdmins: false 13 | purifierConfig: null 14 | purifyHtml: true 15 | showUnpermittedFiles: false 16 | showUnpermittedVolumes: false 17 | showWordCount: false 18 | wordLimit: null 19 | translationKeyFormat: null 20 | translationMethod: none 21 | type: craft\ckeditor\Field 22 | -------------------------------------------------------------------------------- /config/project/fields/side--d7f9c488-b14d-48c2-b6fc-d616b7a9f49f.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: side 3 | instructions: null 4 | name: 'Show Media On' 5 | searchable: false 6 | settings: 7 | options: 8 | - 9 | __assoc__: 10 | - 11 | - label 12 | - Left 13 | - 14 | - value 15 | - left 16 | - 17 | - default 18 | - '1' 19 | - 20 | __assoc__: 21 | - 22 | - label 23 | - Right 24 | - 25 | - value 26 | - right 27 | - 28 | - default 29 | - '' 30 | translationKeyFormat: null 31 | translationMethod: none 32 | type: craft\fields\RadioButtons 33 | -------------------------------------------------------------------------------- /config/project/fields/videoUrl--55cc26b6-8b49-47de-bbe7-5908da6f4545.yaml: -------------------------------------------------------------------------------- 1 | columnSuffix: null 2 | handle: videoUrl 3 | instructions: null 4 | name: 'Video Url' 5 | searchable: false 6 | settings: 7 | byteLimit: null 8 | charLimit: null 9 | code: false 10 | initialRows: 4 11 | multiline: false 12 | placeholder: null 13 | uiMode: normal 14 | translationKeyFormat: null 15 | translationMethod: none 16 | type: craft\fields\PlainText 17 | -------------------------------------------------------------------------------- /config/project/project.yaml: -------------------------------------------------------------------------------- 1 | dateModified: 1748040902 2 | elementSources: 3 | craft\elements\Entry: 4 | - 5 | defaultSort: 6 | - postDate 7 | - desc 8 | defaultViewMode: '' 9 | disabled: false 10 | key: '*' 11 | tableAttributes: 12 | - status 13 | - section 14 | - postDate 15 | - expiryDate 16 | - link 17 | type: native 18 | - 19 | heading: Singles 20 | type: heading 21 | - 22 | key: 'single:969acdd6-6362-41b1-b782-6bbd43a8a6b4' # Home 23 | type: native 24 | - 25 | heading: Globals 26 | type: heading 27 | - 28 | defaultSort: 29 | - id 30 | - asc 31 | defaultViewMode: '' 32 | disabled: false 33 | key: 'single:b4bfeb63-5bc4-4368-b4c9-408f7bac68fc' # Global Code 34 | tableAttributes: 35 | - status 36 | - postDate 37 | - expiryDate 38 | - link 39 | type: native 40 | email: 41 | fromEmail: $SYSTEM_EMAIL_FROM 42 | fromName: 'Viget Craft Starter' 43 | replyToEmail: null 44 | template: null 45 | transportSettings: 46 | host: $SYSTEM_EMAIL_HOSTNAME 47 | password: $SYSTEM_EMAIL_PASSWORD 48 | port: $SYSTEM_EMAIL_PORT 49 | useAuthentication: '1' 50 | username: $SYSTEM_EMAIL_USERNAME 51 | transportType: craft\mail\transportadapters\Smtp 52 | fs: 53 | s3: 54 | hasUrls: true 55 | name: S3 56 | settings: 57 | addSubfolderToRootUrl: true 58 | autoFocalPoint: false 59 | bucket: $S3_BUCKET 60 | bucketSelectionMode: manual 61 | cfDistributionId: $S3_CLOUDFRONT_DISTRIBUTION_ID 62 | cfPrefix: $S3_SUBFOLDER 63 | expires: '30 days' 64 | keyId: $S3_ACCESS_KEY_ID 65 | makeUploadsPublic: false 66 | region: $S3_BUCKET_REGION 67 | secret: $S3_SECRET_ACCESS_KEY 68 | storageClass: '' 69 | subfolder: $S3_SUBFOLDER 70 | type: craft\awss3\Fs 71 | url: $S3_BASE_URL 72 | meta: 73 | __names__: 74 | 0e7762a5-2553-4c0d-b8af-9b43b59524bf: Home # Home 75 | 2ea51656-9b0c-4736-a6fe-c95dc805dc60: Button # Button 76 | 3bcf7ddb-71e7-4115-868c-815b3611b34c: 'Text With Media' # Text With Media 77 | 3f1dc0c5-f091-469a-858a-4cbd3596bab7: 'Icon Card' # Icon Card 78 | 5e84b0b7-6851-47ed-962e-76498ac9476f: 'Card Grid' # Card Grid 79 | 7a701601-ee6c-4d56-8bd0-efa7719f6a67: Code # Code 80 | 7bd21dd3-6b12-4163-8432-030ea6a3f8d3: 'Page Blocks' # Page Blocks 81 | 7ced3e9d-9b54-47f6-8103-e5c3a4fbaf9c: 'Card Grid' # Card Grid 82 | 7d418368-91eb-4c64-8f5b-94c62cd62359: 'Image Card' # Image Card 83 | 9c7dc3c3-cb8c-4167-880d-ab9426eef873: 'Code Blocks' # Code Blocks 84 | 0011a64a-91b6-4aa3-98e6-be048394a2cf: Icon # Icon 85 | 27f19bae-64f8-47b8-9fc9-7552e11e2656: 'Page Hero' # Page Hero 86 | 35b563a0-4662-40b9-b885-a8450a2868d9: 'Viget Craft Starter' # Viget Craft Starter 87 | 55cc26b6-8b49-47de-bbe7-5908da6f4545: 'Video Url' # Video Url 88 | 69fe4c18-21c9-4a3d-8fce-9988d3f741e4: Link # Link 89 | 101b4db6-8914-45eb-a661-180b15f70894: 'Footer Navigation' # Footer Navigation 90 | 534ccdd8-7abd-4300-a102-71885b21c126: 'Call To Action' # Call To Action 91 | 570fb481-ad97-46db-8bad-f7b0fd90e831: Image # Image 92 | 805d8826-faed-4186-9b88-f509eb9b07e6: 'Viget Craft Starter' # Viget Craft Starter 93 | 896b8f2a-ed0c-42c9-b5fd-ba8668fc6784: 'Rich Text' # Rich Text 94 | 969acdd6-6362-41b1-b782-6bbd43a8a6b4: Home # Home 95 | 4382f55f-01a1-4b67-84c8-ebbc89b238d2: Heading # Heading 96 | 853413e4-e02c-487e-81a5-04e58eb18683: Assets # Assets 97 | 25362218-e66c-494e-9f2c-63e8cbc6ce0a: 'Global Code' # Global Code 98 | a99edea2-f8ae-44e5-a12f-89cb9aa66738: Description # Description 99 | ac3b0590-d417-429e-aa1f-96be3c79a5b0: 'Media Type' # Media Type 100 | b3d7753a-c7ad-4f33-aca8-df63277e9b42: 'Primary Navigation' # Primary Navigation 101 | b4bfeb63-5bc4-4368-b4c9-408f7bac68fc: 'Global Code' # Global Code 102 | b7e66782-af96-4012-9e17-914134073ced: Simple # Simple 103 | c52a9170-652b-4d92-a226-69894b1822ed: 'Rich Text: Simple' # Rich Text: Simple 104 | cbf3aeac-588c-4aeb-9573-6f1920206abf: 'Code Block' # Code Block 105 | cd489d3c-f914-475c-a270-ab926e4e7485: 'Rich Text' # Rich Text 106 | d7f9c488-b14d-48c2-b6fc-d616b7a9f49f: 'Show Media On' # Show Media On 107 | d39724b0-dd22-4c74-aa0b-87a022555cf2: Advanced # Advanced 108 | e445a3b9-5827-422a-8328-6b10449fa891: Heading # Heading 109 | f7d30e72-f872-487a-aba1-c8e95268a220: 'Code Position' # Code Position 110 | plugins: 111 | aws-s3: 112 | edition: standard 113 | enabled: true 114 | schemaVersion: '2.0' 115 | ckeditor: 116 | edition: standard 117 | enabled: true 118 | schemaVersion: 3.0.0.0 119 | classnames: 120 | edition: standard 121 | enabled: true 122 | schemaVersion: 3.0.0 123 | cp-field-inspect: 124 | edition: standard 125 | enabled: true 126 | schemaVersion: 1.0.0 127 | empty-coalesce: 128 | edition: standard 129 | enabled: true 130 | schemaVersion: 1.0.0 131 | expanded-singles: 132 | edition: standard 133 | enabled: true 134 | schemaVersion: 1.0.0 135 | settings: 136 | expandSingles: true 137 | redirectToEntry: true 138 | imager-x: 139 | edition: pro 140 | enabled: true 141 | licenseKey: REPLACE 142 | schemaVersion: 4.0.0 143 | imager-x-aws-serverless-transformer: 144 | edition: standard 145 | enabled: true 146 | schemaVersion: 2.0.0 147 | imager-x-power-pack: 148 | edition: standard 149 | enabled: true 150 | schemaVersion: 1.0.0 151 | navigation: 152 | edition: standard 153 | enabled: true 154 | licenseKey: REPLACE 155 | schemaVersion: 2.1.0 156 | retour: 157 | edition: standard 158 | enabled: true 159 | licenseKey: REPLACE 160 | schemaVersion: 3.0.12 161 | seomatic: 162 | edition: standard 163 | enabled: true 164 | licenseKey: REPLACE 165 | schemaVersion: 3.0.13 166 | viget-parts-kit: 167 | edition: standard 168 | enabled: true 169 | schemaVersion: 1.0.0 170 | vite: 171 | edition: standard 172 | enabled: true 173 | schemaVersion: 1.0.0 174 | system: 175 | edition: solo 176 | live: true 177 | name: 'Viget Craft Starter' 178 | schemaVersion: 5.7.0.3 179 | timeZone: America/Los_Angeles 180 | users: 181 | allowPublicRegistration: false 182 | defaultGroup: null 183 | photoSubpath: null 184 | photoVolumeUid: null 185 | require2fa: false 186 | requireEmailVerification: true 187 | -------------------------------------------------------------------------------- /config/project/sections/globalCode--b4bfeb63-5bc4-4368-b4c9-408f7bac68fc.yaml: -------------------------------------------------------------------------------- 1 | defaultPlacement: end 2 | enableVersioning: true 3 | entryTypes: 4 | - 5 | uid: 25362218-e66c-494e-9f2c-63e8cbc6ce0a # Global Code 6 | handle: globalCode 7 | maxAuthors: 1 8 | name: 'Global Code' 9 | propagationMethod: all 10 | siteSettings: 11 | 35b563a0-4662-40b9-b885-a8450a2868d9: # Viget Craft Starter 12 | enabledByDefault: true 13 | hasUrls: false 14 | template: null 15 | uriFormat: null 16 | type: single 17 | -------------------------------------------------------------------------------- /config/project/sections/home--969acdd6-6362-41b1-b782-6bbd43a8a6b4.yaml: -------------------------------------------------------------------------------- 1 | defaultPlacement: end 2 | enableVersioning: true 3 | entryTypes: 4 | - 0e7762a5-2553-4c0d-b8af-9b43b59524bf # Home 5 | handle: home 6 | maxAuthors: 1 7 | name: Home 8 | previewTargets: 9 | - 10 | __assoc__: 11 | - 12 | - label 13 | - 'Primary entry page' 14 | - 15 | - urlFormat 16 | - '{url}' 17 | - 18 | - refresh 19 | - '1' 20 | propagationMethod: all 21 | siteSettings: 22 | 35b563a0-4662-40b9-b885-a8450a2868d9: # Viget Craft Starter 23 | enabledByDefault: true 24 | hasUrls: true 25 | template: _elements/home.twig 26 | uriFormat: __home__ 27 | type: single 28 | -------------------------------------------------------------------------------- /config/project/siteGroups/805d8826-faed-4186-9b88-f509eb9b07e6.yaml: -------------------------------------------------------------------------------- 1 | name: 'Viget Craft Starter' 2 | -------------------------------------------------------------------------------- /config/project/sites/default--35b563a0-4662-40b9-b885-a8450a2868d9.yaml: -------------------------------------------------------------------------------- 1 | baseUrl: $PRIMARY_SITE_URL 2 | enabled: true 3 | handle: default 4 | hasUrls: true 5 | language: en-US 6 | name: 'Viget Craft Starter' 7 | primary: true 8 | siteGroup: 805d8826-faed-4186-9b88-f509eb9b07e6 # Viget Craft Starter 9 | sortOrder: 1 10 | -------------------------------------------------------------------------------- /config/project/volumes/assets--853413e4-e02c-487e-81a5-04e58eb18683.yaml: -------------------------------------------------------------------------------- 1 | altTranslationKeyFormat: null 2 | altTranslationMethod: none 3 | fieldLayouts: 4 | a7f496e4-142f-49a4-b241-2cb6ce1a1f30: 5 | tabs: 6 | - 7 | elementCondition: null 8 | elements: 9 | - 10 | autocapitalize: true 11 | autocomplete: false 12 | autocorrect: true 13 | class: null 14 | dateAdded: '2024-09-25T21:25:44+00:00' 15 | disabled: false 16 | elementCondition: null 17 | id: null 18 | includeInCards: false 19 | inputType: null 20 | instructions: null 21 | label: null 22 | max: null 23 | min: null 24 | name: null 25 | orientation: null 26 | placeholder: null 27 | providesThumbs: false 28 | readonly: false 29 | requirable: false 30 | size: null 31 | step: null 32 | tip: null 33 | title: null 34 | type: craft\fieldlayoutelements\assets\AssetTitleField 35 | uid: 46777601-180e-43d4-8853-3ab2dcd42057 36 | userCondition: null 37 | warning: null 38 | width: 100 39 | - 40 | attribute: alt 41 | class: null 42 | cols: null 43 | dateAdded: '2024-09-25T21:27:17+00:00' 44 | disabled: false 45 | elementCondition: null 46 | id: null 47 | includeInCards: false 48 | instructions: null 49 | label: null 50 | name: null 51 | orientation: null 52 | placeholder: null 53 | providesThumbs: false 54 | readonly: false 55 | requirable: true 56 | required: false 57 | rows: null 58 | tip: null 59 | title: null 60 | type: craft\fieldlayoutelements\assets\AltField 61 | uid: d508c2f5-a04e-4614-b005-f848c95bfaa5 62 | userCondition: null 63 | warning: null 64 | width: 100 65 | name: Content 66 | uid: c5d6deb9-e383-44bf-aa0f-a8de30dfca6f 67 | userCondition: null 68 | fs: s3 69 | handle: assets 70 | name: Assets 71 | sortOrder: 1 72 | subpath: '' 73 | titleTranslationKeyFormat: null 74 | titleTranslationMethod: site 75 | transformFs: '' 76 | transformSubpath: transforms 77 | -------------------------------------------------------------------------------- /config/redirects.php: -------------------------------------------------------------------------------- 1 | { 4 | // Base Styles 5 | const base = { 6 | // core 7 | '@apply inline-flex items-center justify-center rounded font-bold transition text-base gap-12 cursor-pointer no-underline': 8 | {}, 9 | // focus 10 | '@apply focus:outline-none focus-visible:ring-4': {}, 11 | // disabled 12 | '@apply disabled:opacity-20 disabled:pointer-events-none': {}, 13 | // icon 14 | '& svg': { 15 | '@apply size-20': {}, 16 | }, 17 | // text exempt 18 | '&:not(.btn-text)': { 19 | '@apply px-20 min-h-40': {}, 20 | }, 21 | } 22 | 23 | const buttons = { 24 | // Button Variants 25 | '.btn-contained': { 26 | ...base, 27 | [`@apply 28 | bg-sky-600 text-white 29 | hover:bg-sky-700 30 | active:bg-sky-800 31 | focus-visible:bg-sky-700 focus-visible:ring-sky-600/50 32 | dark:bg-sky-200 dark:text-sky-800 33 | dark:hover:bg-sky-50 34 | dark:active:bg-sky-100 35 | dark:focus-visible:bg-sky-50 dark:focus-visible:ring-white/50`]: {}, 36 | }, 37 | 38 | '.btn-outlined': { 39 | ...base, 40 | [`@apply 41 | border border-sky-600 bg-transparent text-sky-600 42 | hover:bg-sky-100 hover:border-sky-700 hover:text-sky-700 43 | active:bg-sky-200/80 active:text-sky-800 44 | focus-visible:bg-sky-100 focus-visible:border-sky-700 focus-visible:ring-sky-600/50 45 | dark:border-white dark:text-white 46 | dark:hover:bg-white/25 47 | dark:active:bg-white/30 48 | dark:focus-visible:bg-sky-100/30 dark:focus-visible:ring-white/50`]: {}, 49 | }, 50 | 51 | '.btn-subtle': { 52 | ...base, 53 | [`@apply 54 | bg-transparent bg-transparent text-sky-600 55 | hover:bg-sky-100 hover:text-sky-700 56 | active:bg-sky-200/80 active:text-sky-800 57 | focus-visible:bg-sky-100 focus-visible:border-sky-700 focus-visible:ring-sky-600/50 58 | dark:text-white 59 | dark:hover:bg-white/25 60 | dark:active:bg-white/30 61 | dark:focus-visible:bg-sky-100/30 dark:focus-visible:ring-white/75`]: {}, 62 | }, 63 | 64 | '.btn-text': { 65 | ...base, 66 | [`@apply 67 | bg-transparent text-sky-600 68 | hover:text-sky-700 hover:underline 69 | active:text-sky-800 70 | focus-visible:bg-sky-100 focus-visible:ring-sky-600/50 71 | dark:border-white dark:text-white 72 | dark:hover:text-white/90 73 | dark:active:text-white/80 74 | dark:focus-visible:bg-sky-100/30 dark:focus-visible:ring-white/75`]: 75 | {}, 76 | }, 77 | 78 | // Button Sizes 79 | '.btn-sm': { 80 | '@apply text-sm gap-8': {}, 81 | '& svg': { 82 | '@apply size-16': {}, 83 | }, 84 | '&:not(.btn-text)': { 85 | '@apply px-16 min-h-32': {}, 86 | }, 87 | }, 88 | '.btn-lg': { 89 | '@apply text-xl gap-12': {}, 90 | '& svg': { 91 | '@apply size-24': {}, 92 | }, 93 | '&:not(.btn-text)': { 94 | '@apply px-32 min-h-56': {}, 95 | }, 96 | }, 97 | 98 | // Button Icon/Sizes 99 | '.btn-icon': { 100 | fontSize: '0 !important', 101 | lineHeight: '0 !important', 102 | '@apply !p-0 !gap-0 aspect-square justify-center items-center': {}, 103 | }, 104 | } 105 | 106 | addComponents(buttons) 107 | }) 108 | -------------------------------------------------------------------------------- /config/tailwind/dialog.js: -------------------------------------------------------------------------------- 1 | import plugin from 'tailwindcss/plugin' 2 | 3 | export default plugin(({ addComponents }) => { 4 | addComponents({ 5 | '.dialog': { 6 | '@apply invisible opacity-0 fixed inset-24 overflow-hidden z-50 open:visible m-auto bg-white p-24 text-black dark:border dark:border-gray-500 dark:bg-gray-900 dark:text-white rounded': 7 | {}, 8 | '&[open]': { 9 | animation: 10 | 'dialog-in var(--dialog-transition-duration, 300ms) cubic-bezier(0.2, 0, 0.13, 1) forwards', 11 | }, 12 | '&::backdrop': { 13 | animation: 14 | 'dialog-backdrop-in var(--dialog-transition-duration, 300ms) cubic-bezier(0.2, 0, 0.13, 1) forwards', 15 | '@apply bg-black/80 backdrop-blur-sm': {}, 16 | }, 17 | '&[data-dialog-status="closing"]': { 18 | animation: 19 | 'dialog-out var(--dialog-transition-duration, 300ms) cubic-bezier(0.2, 0, 0.13, 1) forwards', 20 | 21 | '&::backdrop': { 22 | animation: 23 | 'dialog-backdrop-out var(--dialog-transition-duration, 300ms) cubic-bezier(0.2, 0, 0.13, 1) forwards', 24 | }, 25 | }, 26 | }, 27 | // Animation Keyframes 28 | '@keyframes dialog-in': { 29 | '0%': { transform: 'translateY(2rem)', opacity: '0' }, 30 | '100%': { transform: 'translateY(0px)', opacity: '1' }, 31 | }, 32 | '@keyframes dialog-out': { 33 | '0%': { transform: 'scale(1)', opacity: '1' }, 34 | '100%': { transform: 'scale(0.9)', opacity: '0' }, 35 | }, 36 | '@keyframes dialog-backdrop-in': { 37 | '0%': { opacity: '0' }, 38 | '100%': { opacity: '1' }, 39 | }, 40 | '@keyframes dialog-backdrop-out': { 41 | '0%': { opacity: '1' }, 42 | '100%': { opacity: '0' }, 43 | }, 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /config/tailwind/forms.js: -------------------------------------------------------------------------------- 1 | import plugin from 'tailwindcss/plugin' 2 | 3 | export default plugin(({ addComponents }) => { 4 | // Base styles 5 | const inputs = { 6 | '.field-group': { 7 | '@apply flex flex-col gap-8': {}, 8 | // label container 9 | '& label': { 10 | '@apply flex flex-col [&:has(.sr-only:last-child)]:sr-only': {}, 11 | }, 12 | // label 13 | '& .field-label': { 14 | '@apply text-gray-900 dark:text-white': {}, 15 | }, 16 | // sublabel & instructions 17 | '& .field-sublabel, & .field-instructions': { 18 | '@apply text-sm text-gray-700 dark:text-gray-300': {}, 19 | }, 20 | // core field styles 21 | '& input[type="text"], & input[type="password"], & input[type="email"], & input[type="number"], & input[type="tel"], & input[type="url"], & select, & textarea': 22 | { 23 | // base styles 24 | '@apply rounded-sm border-0 bg-white ring-1 outline-none ring-black/50 px-8 dark:bg-white/10 dark:text-white dark:ring-white/50': 25 | {}, 26 | // placeholder styles 27 | '@apply placeholder:text-black/40 dark:placeholder:text-white/50': {}, 28 | // hover styles 29 | '@apply hover:ring-black/75 dark:hover:ring-white/75': {}, 30 | // focus styles 31 | '@apply focus:ring-blue-500 focus:ring-2 dark:focus:ring-white/75': 32 | {}, 33 | // disabled styles 34 | '@apply disabled:bg-gray-500/10 disabled:ring-gray-500/20 disabled:text-black/75 disabled:cursor-not-allowed dark:disabled:ring-white/20 dark:disabled:bg-white/25 dark:disabled:text-white/50 dark:disabled:placeholder:text-white/35': 35 | {}, 36 | // Exclude textarea from fix height 37 | '&:not(textarea)': { 38 | '@apply h-40': {}, 39 | }, 40 | '&:is(input[type="checkbox"])': { 41 | '@apply size-20 border-0 text-blue-500 checked:bg-blue-500 min-h-0': 42 | {}, 43 | }, 44 | '&:is([aria-invalid="true"])': { 45 | '@apply ring-red-600 hover:ring-red-700 focus:ring-red-600 dark:ring-red-300 dark:hover:ring-red-400 dark:focus:ring-red-300': 46 | {}, 47 | }, 48 | }, 49 | // field specific styles 50 | '& textarea': { 51 | '@apply py-8': {}, 52 | }, 53 | '& select': { 54 | backgroundImage: `url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000000' d='M12 5.83 15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z'/%3E%3C/svg%3E")`, 55 | backgroundPosition: 'right .5rem center', 56 | backgroundSize: '1rem', 57 | backgroundRepeat: 'no-repeat', 58 | '@apply appearance-none pr-32': {}, 59 | 60 | '.dark &': { 61 | backgroundImage: `url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23ffffff' d='M12 5.83 15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z'/%3E%3C/svg%3E")`, 62 | }, 63 | '& option': { 64 | '@apply text-black': {}, 65 | }, 66 | }, 67 | // required field styles 68 | '&[data-required] label .field-label': { 69 | '&::after': { 70 | '@apply content-["*"] text-red-600 align-super text-xs ml-2 font-medium': 71 | {}, 72 | }, 73 | '.dark &::after': { 74 | '@apply text-red-300': {}, 75 | }, 76 | }, 77 | '&[data-required="long"] label .field-label::after': { 78 | '@apply content-["*Required"]': {}, 79 | }, 80 | // error message styles 81 | '.field-errors': { 82 | '@apply relative text-red-600 text-sm font-medium flex gap-10 flex-col pl-20 list-none dark:text-red-300': 83 | {}, 84 | }, 85 | }, 86 | } 87 | 88 | addComponents(inputs) 89 | }) 90 | -------------------------------------------------------------------------------- /config/tailwind/rich-text.js: -------------------------------------------------------------------------------- 1 | import plugin from 'tailwindcss/plugin' 2 | 3 | export default plugin(({ addComponents }) => { 4 | const richText = { 5 | '.rich-text': { 6 | '& strong, & b': { 7 | '@apply font-semibold': {}, 8 | }, 9 | '& p': { 10 | '@apply mb-16': {}, 11 | }, 12 | '& a': { 13 | '@apply text-sky-600 underline': {}, 14 | }, 15 | '& ol, & ul': { 16 | '@apply mt-20 mb-20 pl-20': {}, 17 | }, 18 | '& ol': { 19 | '@apply list-decimal': {}, 20 | }, 21 | '& ul': { 22 | '@apply list-disc': {}, 23 | }, 24 | '& li, & li > ol, & li > ul': { 25 | '@apply mt-8 mb-8': {}, 26 | }, 27 | '& blockquote': { 28 | '@apply italic text-lg border-l-2 border-sky-600 pl-16': {}, 29 | }, 30 | // Separate rich text classes let us adjust sizes without migrating existing content 31 | '& .rich-text-size-xlarge': { 32 | '@apply text-2xl': {}, 33 | }, 34 | '& .rich-text-size-large': { 35 | '@apply text-xl': {}, 36 | }, 37 | '& .rich-text-size-medium': { 38 | '@apply text-lg': {}, 39 | }, 40 | '& .rich-text-size-small': { 41 | '@apply text-sm': {}, 42 | }, 43 | }, 44 | } 45 | 46 | addComponents(richText) 47 | }) 48 | -------------------------------------------------------------------------------- /config/vite.php: -------------------------------------------------------------------------------- 1 | preg_replace('/:\d+$/', '', $host) . ':' . $httpsPort, 14 | 'serverPublic' => '/dist/', 15 | 'useDevServer' => App::env('CRAFT_ENVIRONMENT') === 'dev', 16 | 'manifestPath' => '@webroot/dist/.vite/manifest.json', 17 | ]; 18 | -------------------------------------------------------------------------------- /craft: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 14 | exit($exitCode); 15 | -------------------------------------------------------------------------------- /docs/block-call-to-action-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-call-to-action-admin.png -------------------------------------------------------------------------------- /docs/block-call-to-action-frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-call-to-action-frontend.png -------------------------------------------------------------------------------- /docs/block-card-grid-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-card-grid-admin.png -------------------------------------------------------------------------------- /docs/block-card-grid-frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-card-grid-frontend.png -------------------------------------------------------------------------------- /docs/block-heading-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-heading-admin.png -------------------------------------------------------------------------------- /docs/block-heading-frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-heading-frontend.png -------------------------------------------------------------------------------- /docs/block-page-hero-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-page-hero-admin.png -------------------------------------------------------------------------------- /docs/block-page-hero-frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-page-hero-frontend.png -------------------------------------------------------------------------------- /docs/block-rich-text-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-rich-text-admin.png -------------------------------------------------------------------------------- /docs/block-rich-text-frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-rich-text-frontend.png -------------------------------------------------------------------------------- /docs/block-text-with-media-image-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-text-with-media-image-admin.png -------------------------------------------------------------------------------- /docs/block-text-with-media-image-frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-text-with-media-image-frontend.png -------------------------------------------------------------------------------- /docs/block-text-with-media-video-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-text-with-media-video-admin.png -------------------------------------------------------------------------------- /docs/block-text-with-media-video-frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/block-text-with-media-video-frontend.png -------------------------------------------------------------------------------- /docs/building-with-site-starter.md: -------------------------------------------------------------------------------- 1 | # Building with Craft Site Starter 2 | 3 | ## Overview 4 | 5 |  6 | 7 | - Lives withing the broader ecosystem of Blueprint and WordPress Site Starter. 8 | - Blueprint is the common design and naming system across both Site Starter projects. 9 | - We aren't trying to have 100% parity with WordPress Site Starter. 10 | - Craft Site Starter leans into the strengths of Craft CMS and the Craft ecosystem. 11 | - Craft is more of a "blank slate" compared to WordPress. 12 | - However, the starter contains Blueprint Components, a feature rich & fully accessible Header and Footer, and the beginnings of a simple Matrix Field based block editor. 13 | 14 | ## For Design & UX 15 | 16 | ### Blueprint 17 | 18 | The Craft Site Starter's components library is based on Blueprint. 19 | 20 | [🔗 Blueprint Github repo](https://github.com/vigetlabs/blueprint) 21 | 22 | [🔗 Live Blueprint docs](https://staging.blueprint.viget.com/) 23 | 24 | - A component library that serves as a guide for both design and development. 25 | - It's meant to be customized, modified and adapted for projects. 26 | - Just because a component exists in Blueprint doesn't mean it's the only way to do something. However, there is added cost the further we venture outside the boundaries of Blueprint. 27 | - One of the biggest benefits of Blueprint is a shared example to use for design and development conversations. 28 | - Exampes: 29 | - "Instead of button style 'Outlined" we're namning it 'Secondary" and changing it in the following ways." 30 | - "We modified the card styles for this project, but it's still about 80% the same as the Blueprint card styles." 31 | - "We're heavily customizing the hero styles for this project, but components X, Y, and Z aren't changing at all." 32 | 33 | > See a common design pattern that's missing from Blueprint? [🔗 Open an issue](https://github.com/vigetlabs/blueprint/issues/new) 34 | 35 | ### Header, Navigation, & Footer 36 | 37 | There is an example of a fully accessible header and navigation built for the Craft Site Starter. 38 | 39 | Style & layout can be modified a good bit without breaking the core interactivity and accessibility. 40 | 41 | ### Block Editor 42 | 43 | The block editor uses Craft's Matrix field and contains the following Blueprint blocks: 44 | 45 | #### Page Hero 46 | 47 | | Admin | Frontend | 48 | | -------------------------------------- | ----------------------------------------- | 49 | |  |  | 50 | 51 | #### Call to Action 52 | 53 | | Admin | Frontend | 54 | | ------------------------------------------- | ---------------------------------------------- | 55 | |  |  | 56 | 57 | #### Card Grid 58 | 59 | | Admin | Frontend | 60 | | -------------------------------------- | ----------------------------------------- | 61 | |  |  | 62 | 63 | #### Heading 64 | 65 | | Admin | Frontend | 66 | | ------------------------------------ | --------------------------------------- | 67 | |  |  | 68 | 69 | #### Rich Text 70 | 71 | | Admin | Frontend | 72 | | -------------------------------------- | ----------------------------------------- | 73 | |  |  | 74 | 75 | #### Text with Media (Image) 76 | 77 | | Admin | Frontend | 78 | | -------------------------------------------------- | ----------------------------------------------------- | 79 | |  |  | 80 | 81 | #### Text with Media (Video) 82 | 83 | | Admin | Frontend | 84 | | -------------------------------------------------- | ----------------------------------------------------- | 85 | |  |  | 86 | 87 | - Unlike WordPress, the entire site won't be built with a "Gutenberg" like editor. 88 | - For some projects, budget can be reduced by planning for the majority of pages using the Matrix field block editor. 89 | - However, a large project would likely take a hybrid approach and use the block editor for some sections and Craft's typical custom field setup for others. 90 | 91 | ## For Developers (Platform & UI) 92 | 93 | - All components and Tailwind plugins are meant to be modified directly. 94 | - There is a pre-configured parts kit for building and testing components in isolation. 95 | - These components provide a solid starting point and consistent structure for creating new components. 96 | - Craft comes with commonly used plugins pre-installed and configured. 97 | - Build tooling such as Vite, Tailwind and Alpine.js are pre-configured. 98 | - Code quality and formatting tools such as Prettier, PHPStan and PHPECS run on every commit. 99 | -------------------------------------------------------------------------------- /docs/project-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/project-logo.png -------------------------------------------------------------------------------- /docs/release-qa-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/release-qa-1.png -------------------------------------------------------------------------------- /docs/release-qa-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/release-qa-2.png -------------------------------------------------------------------------------- /docs/site-starter-ecosystem.excalidraw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/docs/site-starter-ecosystem.excalidraw.png -------------------------------------------------------------------------------- /ecs.php: -------------------------------------------------------------------------------- 1 | parallel(); 10 | $ecsConfig->paths([ 11 | __DIR__ . '/modules', 12 | __DIR__ . '/install-scripts', 13 | __DIR__ . '/bootstrap.php', 14 | __DIR__ . '/web/index.php', 15 | __FILE__, 16 | ]); 17 | 18 | // TODO waiting on this PR or similar https://github.com/craftcms/ecs/pull/4 19 | $ecsConfig->sets([SetList::CRAFT_CMS_4]); // for Craft 4 projects 20 | }; 21 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import eslintConfigPrettier from 'eslint-config-prettier' 2 | import js from '@eslint/js' 3 | import globals from 'globals' 4 | 5 | export default [ 6 | js.configs.recommended, 7 | eslintConfigPrettier, 8 | 9 | { 10 | rules: { 11 | 'no-console': ['error', { allow: ['warn', 'error'] }], 12 | }, 13 | languageOptions: { 14 | globals: { 15 | ...globals.browser, 16 | }, 17 | }, 18 | }, 19 | ] 20 | -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This runs within the DDEV container 3 | * We have access to the appropriate PHP & Composer versions 4 | */ 5 | export default { 6 | '**/*.php': [ 7 | './vendor/bin/ecs check --ansi --fix', 8 | './vendor/bin/phpstan analyse --memory-limit=1G', 9 | ], 10 | '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --ignore-unknown --write'], 11 | // Negate the JS files above so there isn't a race condition 12 | // This runs prettier on every type of file other than the extensions listed below 13 | // https://github.com/lint-staged/lint-staged?tab=readme-ov-file#task-concurrency 14 | '!(*.js|*.jsx|*.ts|*.tsx)': 'prettier --ignore-unknown --write', 15 | } 16 | -------------------------------------------------------------------------------- /modules/todo.php: -------------------------------------------------------------------------------- 1 | ", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "lint": "eslint --fix src", 11 | "format": "prettier --write .", 12 | "prepare": "husky" 13 | }, 14 | "devDependencies": { 15 | "@eslint/js": "^9.21.0", 16 | "@tailwindcss/postcss": "^4.0.0", 17 | "cssnano": "^7.0.6", 18 | "eslint-config-prettier": "^10.0.2", 19 | "globals": "^16.0.0", 20 | "husky": "^9.1.7", 21 | "lint-staged": "^15.4.3", 22 | "postcss": "^8.5.3", 23 | "postcss-pxtorem": "^6.1.0", 24 | "prettier": "^3.5.2", 25 | "tailwindcss": "^4.0.0", 26 | "vite": "^6.3.5", 27 | "vite-plugin-static-copy": "^2.2.0" 28 | }, 29 | "dependencies": { 30 | "@alpinejs/collapse": "^3.14.1", 31 | "@alpinejs/focus": "^3.14.1", 32 | "alpinejs": "^3.14.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - vendor/craftcms/phpstan/phpstan.neon 3 | 4 | parameters: 5 | level: 5 6 | paths: 7 | - composer-scripts 8 | - modules 9 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | import process from 'process' 2 | 3 | export default { 4 | plugins: { 5 | '@tailwindcss/postcss': {}, 6 | 'postcss-pxtorem': { 7 | rootValue: 16, 8 | unitPrecision: 5, 9 | propList: ['*'], 10 | selectorBlackList: [], 11 | replace: true, 12 | mediaQuery: true, 13 | minPixelValue: 1, 14 | exclude: /node_modules/i, 15 | }, 16 | ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}), 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /src/css/app.css: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss'; 2 | 3 | /* Import plugins */ 4 | @plugin '../../config/tailwind/buttons.js'; 5 | @plugin '../../config/tailwind/dialog.js'; 6 | @plugin '../../config/tailwind/rich-text.js'; 7 | @plugin '../../config/tailwind/forms.js'; 8 | 9 | /* Configure Tailwind */ 10 | @theme { 11 | /* Custom Spacing */ 12 | --spacing-*: initial; /* Resets all spacing config */ 13 | --spacing-0: 0px; 14 | --spacing-1: 1px; 15 | --spacing-2: 2px; 16 | --spacing-4: 4px; 17 | --spacing-6: 6px; 18 | --spacing-8: 8px; 19 | --spacing-10: 10px; 20 | --spacing-12: 12px; 21 | --spacing-16: 16px; 22 | --spacing-20: 20px; 23 | --spacing-24: 24px; 24 | --spacing-28: 28px; 25 | --spacing-32: 32px; 26 | --spacing-36: 36px; 27 | --spacing-40: 40px; 28 | --spacing-44: 44px; 29 | --spacing-48: 48px; 30 | --spacing-52: 52px; 31 | --spacing-56: 56px; 32 | --spacing-60: 60px; 33 | --spacing-64: 64px; 34 | --spacing-80: 80px; 35 | --spacing-96: 96px; 36 | --spacing-112: 112px; 37 | --spacing-128: 128px; 38 | 39 | /* Add named z-index values */ 40 | --z-index-header: 100; 41 | --z-index-max: 9999; 42 | } 43 | 44 | /* Use selector based dark mode */ 45 | @custom-variant dark (&:where(.dark, .dark *)); 46 | 47 | /* Override the default Tailwind container class */ 48 | @utility container { 49 | /* Override the different max-widths at different breakpoints */ 50 | @apply max-w-[1240px]; 51 | /** Apply padding to the left and right and automatically center the container */ 52 | @apply mx-auto px-16 sm:px-32; 53 | } 54 | 55 | /* Base styles */ 56 | @layer base { 57 | @font-face { 58 | font-display: swap; 59 | font-family: 'Source Sans Pro'; 60 | font-style: normal; 61 | font-weight: 300; 62 | src: url('../fonts/sourcesanspro-light-webfont.woff2') format('woff2'); 63 | } 64 | 65 | @font-face { 66 | font-display: swap; 67 | font-family: 'Source Sans Pro'; 68 | font-style: normal; 69 | font-weight: 400; 70 | src: url('../fonts/sourcesanspro-regular-webfont.woff2') format('woff2'); 71 | } 72 | 73 | @font-face { 74 | font-display: swap; 75 | font-family: 'Source Sans Pro'; 76 | font-style: normal; 77 | font-weight: 600; 78 | src: url('../fonts/sourcesanspro-semibold-webfont.woff2') format('woff2'); 79 | } 80 | 81 | @font-face { 82 | font-display: swap; 83 | font-family: 'Source Sans Pro'; 84 | font-style: normal; 85 | font-weight: 700; 86 | src: url('../fonts/sourcesanspro-bold-webfont.woff2') format('woff2'); 87 | } 88 | 89 | body { 90 | font-family: 'Source Sans Pro', sans-serif; 91 | } 92 | 93 | strong { 94 | font-weight: 700; 95 | } 96 | 97 | [x-cloak] { 98 | display: none !important; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/fonts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/src/fonts/.gitkeep -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-bold-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/src/fonts/sourcesanspro-bold-webfont.woff2 -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-light-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/src/fonts/sourcesanspro-light-webfont.woff2 -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-regular-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/src/fonts/sourcesanspro-regular-webfont.woff2 -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-semibold-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/src/fonts/sourcesanspro-semibold-webfont.woff2 -------------------------------------------------------------------------------- /src/icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/chevron-down.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/icons/clock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/error.svg: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /src/icons/logo-mark.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/js/alpine/nav.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | /** @type {string[]} */ 3 | stack: [], 4 | popStack(popTimes = 1, focus = true) { 5 | const idToFocus = this.stack.at(-1 * popTimes) 6 | 7 | if (idToFocus && focus) { 8 | const elementToFocus = document.querySelector( 9 | `[aria-controls="${idToFocus}"]`, 10 | ) 11 | this.$focus.focus(elementToFocus) 12 | } 13 | 14 | this.stack = this.stack.slice(0, popTimes * -1) 15 | }, 16 | pushStack(id) { 17 | this.stack.push(id) 18 | 19 | const elementToFocus = document.getElementById(id) 20 | this.$focus.within(elementToFocus).first() 21 | }, 22 | resetStack() { 23 | this.stack = [] 24 | }, 25 | toggle(subnav) { 26 | if (!subnav) { 27 | this.resetStack() 28 | return 29 | } 30 | 31 | const level = parseInt(subnav.dataset.level, 10) 32 | const currentLevel = this.stack.length 33 | const shouldPush = !this.isInStack(subnav) 34 | 35 | if (level <= currentLevel) { 36 | // Remove everything down to the level you clicked. 37 | this.popStack(currentLevel - level + 1) 38 | } 39 | // If you clicked a toggle outside of the current stack, push it to the stack 40 | if (shouldPush) { 41 | this.pushStack(subnav.id) 42 | } 43 | }, 44 | shouldTrap(el) { 45 | // You could modify this to only trap at a mobile sized match media 46 | return this.isInStack(el) 47 | }, 48 | isInStack(el) { 49 | return this.stack.includes(el.id) 50 | }, 51 | /** 52 | * @param {KeyboardEvent} event 53 | */ 54 | handleEscape(event) { 55 | if (this.stack.length === 0) { 56 | return 57 | } 58 | // Prevent the event from bubbling up if we have nav to pop 59 | event.stopPropagation() 60 | 61 | this.popStack(1) 62 | }, 63 | handleTab() { 64 | const activeSubnavId = this.stack.at(-1) 65 | 66 | if (!activeSubnavId) { 67 | return 68 | } 69 | 70 | const activeSubnav = document.getElementById(activeSubnavId) 71 | 72 | if (!activeSubnav) { 73 | return 74 | } 75 | 76 | this.$nextTick(() => { 77 | const activeElement = document.activeElement 78 | 79 | // If document.activeElement is within activeSubnav, do nothing 80 | if (!activeElement || activeSubnav.contains(activeElement)) { 81 | return 82 | } 83 | 84 | // If document.activeElement is not within $root, reset the stack 85 | if (!this.$root.contains(activeElement)) { 86 | this.resetStack() 87 | return 88 | } 89 | 90 | // Focused toggle 91 | const idOfFocusedSubnav = activeElement.getAttribute('aria-controls') 92 | const focusedSubnavLevel = idOfFocusedSubnav 93 | ? document.getElementById(idOfFocusedSubnav)?.dataset.level 94 | : null 95 | 96 | // Edge case, we're still in the nav component, but somehow what we're focused on doesn't have subnav or level 97 | if (!focusedSubnavLevel) { 98 | this.popStack(1, false) 99 | return 100 | } 101 | 102 | // Pop everything down to the level of the focused subnav 103 | const currentLevel = this.stack.length 104 | this.popStack(currentLevel - parseInt(focusedSubnavLevel, 10) + 1, false) 105 | }) 106 | }, 107 | }) 108 | -------------------------------------------------------------------------------- /src/js/app.js: -------------------------------------------------------------------------------- 1 | import '../css/app.css' 2 | 3 | import Alpine from 'alpinejs' 4 | import focus from '@alpinejs/focus' 5 | import collapse from '@alpinejs/collapse' 6 | import nav from './alpine/nav' 7 | 8 | Alpine.plugin(focus) 9 | Alpine.plugin(collapse) 10 | 11 | // @ts-ignore 12 | window.Alpine = Alpine 13 | 14 | Alpine.data('nav', nav) 15 | Alpine.start() 16 | -------------------------------------------------------------------------------- /storage/.gitignore: -------------------------------------------------------------------------------- 1 | backups 2 | composer-backups 3 | config-backups 4 | logs 5 | runtime 6 | -------------------------------------------------------------------------------- /storage/config-deltas/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /templates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vigetlabs/craft-site-starter/9d8de11625fe21cb7ce5373a61b0749fc21e57a7/templates/.gitkeep -------------------------------------------------------------------------------- /templates/_blocks/_callToAction.twig: -------------------------------------------------------------------------------- 1 | {# @var \craft\elements\Entry|null block #} 2 | {% from '_components/call-to-action' import CallToAction %} 3 | 4 | {% set block = block ?? null %} 5 | 6 | {{ CallToAction({ 7 | title: block.title, 8 | text: block.richTextSimple, 9 | href: block.button.value, 10 | buttonText: block.button.label ?? null, 11 | newTab: block.button.target ?? null, 12 | }) }} 13 | -------------------------------------------------------------------------------- /templates/_blocks/_cardGrid.twig: -------------------------------------------------------------------------------- 1 | {# @var \craft\elements\Entry block #} 2 | {% from '_components/card-image' import CardImage %} 3 | {% from '_components/card-icon' import CardIcon %} 4 | 5 | {% set block = block ?? null %} 6 | 7 | {% set cardHeadingLevel = block.heading is not empty ? 3 : 2 %} 8 | 9 |{{ description }}
31 | {% endif %} 32 | 33 | {{ dismissible ? Button({ 34 | variant: 'subtle', 35 | size: 'sm', 36 | icon: 'close', 37 | iconOnly: true, 38 | class: 'absolute right-24 top-24', 39 | text: 'Close', 40 | attrs: { 41 | 'x-on:click': 'dismiss()', 42 | }, 43 | }) }} 44 |{{ description }}
61 | {% endif %} 62 |{{ description }}
68 | {% endif %} 69 |Hello World
10 |Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos.
11 | {% endset %} 12 | 13 | {# Dialogs are triggered by dispatching a custom event dialog:open with an id that matches the dialog's id #} 14 | {{ Button({ 15 | text: 'Open Dialog', 16 | attrs: { 17 | 'x-data': '', 18 | '@click': "$dispatch('dialog:open', { id: 'my-dialog' })" 19 | }, 20 | }) }} 21 | 22 | {{ Dialog({ 23 | content, 24 | id: 'my-dialog', 25 | hideClose: true, 26 | }) }} 27 | {% endblock %} 28 | -------------------------------------------------------------------------------- /templates/parts-kit/dialog/digalog-triggers-dialog.twig: -------------------------------------------------------------------------------- 1 | {% extends "viget-parts-kit/layout.twig" %} 2 | 3 | {% from '_components/button' import Button %} 4 | {% from '_components/dialog' import Dialog %} 5 | 6 | {% block main %} 7 | 8 | {% set dialog1Content %} 9 |Dialog 1
10 |Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos.
11 | 12 | {{ Button({ 13 | text: 'Open Dialog 2', 14 | attrs: { 15 | 'x-data': '', 16 | '@click': "$dispatch('dialog:open', { id: 'my-dialog-2' })" 17 | }, 18 | }) }} 19 | {% endset %} 20 | 21 | {% set dialog2Content %} 22 |Dialog 2
23 |Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos.
24 | 25 | 26 | {% endset %} 27 | 28 | {# Dialogs are triggered by dispatching a custom event dialog:open with an id that matches the dialog's id #} 29 | {{ Button({ 30 | text: 'Open Dialog 1', 31 | attrs: { 32 | 'x-data': '', 33 | '@click': "$dispatch('dialog:open', { id: 'my-dialog' })" 34 | }, 35 | }) }} 36 | 37 | {{ Dialog({ 38 | content: dialog1Content, 39 | id: 'my-dialog', 40 | }) }} 41 | 42 | {{ Dialog({ 43 | content: dialog2Content, 44 | id: 'my-dialog-2', 45 | }) }} 46 | 47 | 48 | {% endblock %} 49 | -------------------------------------------------------------------------------- /templates/parts-kit/forms/select.twig: -------------------------------------------------------------------------------- 1 | {% extends 'viget-parts-kit/layout.twig' %} 2 | 3 | {% from '_components/field-select' import FieldSelect %} 4 | 5 | {% block main %} 6 | 7 | {% set options = [ 8 | { label: 'Option 1', value: 'option-1' }, 9 | { label: 'Option 2', value: 'option-2' }, 10 | { label: 'Option 3', value: 'option-3' }, 11 | ] %} 12 | 13 | {% set fields %} 14 |14 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos. Focusable Content After Video 15 |
16 |