├── .github ├── CODE_OF_CONDUCT.md ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ └── feature_request.md └── pull_request_template.md ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── config └── statamic-peak-commands.php ├── phpunit.xml ├── resources ├── blocks │ ├── call_to_action │ │ ├── _call_to_action.antlers.html │ │ ├── call_to_action.yaml │ │ └── config.php │ ├── cards │ │ ├── _cards.antlers.html │ │ ├── cards.yaml │ │ └── config.php │ ├── collection │ │ ├── _collection.antlers.html │ │ ├── collection.yaml │ │ └── config.php │ ├── columns │ │ ├── _columns.antlers.html │ │ ├── columns.yaml │ │ └── config.php │ ├── divider │ │ ├── _divider.antlers.html │ │ ├── config.php │ │ └── divider.yaml │ ├── full_width_image │ │ ├── _full_width_image.antlers.html │ │ ├── config.php │ │ └── full_width_image.yaml │ ├── image_and_text │ │ ├── _image_and_text.antlers.html │ │ ├── config.php │ │ └── image_and_text.yaml │ ├── images_grid │ │ ├── _images_grid.antlers.html │ │ ├── config.php │ │ └── images_grid.yaml │ ├── index_content │ │ ├── _index_content.antlers.html │ │ ├── config.php │ │ └── index_content.yaml │ └── text_columns │ │ ├── _text_columns.antlers.html │ │ ├── config.php │ │ └── text_columns.yaml ├── presets │ ├── banner │ │ ├── config.php │ │ ├── content │ │ │ └── globals │ │ │ │ └── banner.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── globals │ │ │ │ └── banner.yaml │ │ │ ├── svg │ │ │ └── close.svg │ │ │ └── views │ │ │ └── layout │ │ │ └── _banner.antlers.html │ ├── breadcrumbs │ │ ├── config.php │ │ └── resources │ │ │ └── views │ │ │ └── navigation │ │ │ └── _breadcrumbs.antlers.html │ ├── business_hours │ │ ├── config.php │ │ ├── content │ │ │ └── globals │ │ │ │ └── business_hours.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── globals │ │ │ │ └── business_hours.yaml │ │ │ ├── svg │ │ │ └── phone.svg │ │ │ └── views │ │ │ ├── components │ │ │ ├── _business_hours.antlers.html │ │ │ └── _call_now.antlers.html │ │ │ └── snippets │ │ │ └── _business_hours.antlers.html │ ├── clients │ │ ├── config.php │ │ ├── content │ │ │ └── collections │ │ │ │ └── clients.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── collections │ │ │ │ └── clients │ │ │ │ └── clients.yaml │ │ │ ├── fieldsets │ │ │ └── clients.yaml │ │ │ └── views │ │ │ └── page_builder │ │ │ └── _clients.antlers.html │ ├── events │ │ ├── config.php │ │ ├── content │ │ │ └── collections │ │ │ │ ├── events.yaml │ │ │ │ └── pages │ │ │ │ └── events.md │ │ └── resources │ │ │ ├── blueprints │ │ │ └── collections │ │ │ │ └── events │ │ │ │ └── events.yaml │ │ │ ├── fieldsets │ │ │ ├── events.yaml │ │ │ └── index_content.yaml │ │ │ └── views │ │ │ ├── components │ │ │ └── _events_item.antlers.html │ │ │ ├── events │ │ │ ├── index.antlers.html │ │ │ └── show.antlers.html │ │ │ └── page_builder │ │ │ ├── _events.antlers.html │ │ │ └── _index_content.antlers.html │ ├── faq │ │ ├── config.php │ │ ├── content │ │ │ └── collections │ │ │ │ └── faq.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── collections │ │ │ │ └── faq │ │ │ │ └── faq.yaml │ │ │ ├── fieldsets │ │ │ └── faq.yaml │ │ │ └── views │ │ │ └── page_builder │ │ │ └── _faq.antlers.html │ ├── footer │ │ ├── config.php │ │ ├── content │ │ │ └── navigation │ │ │ │ ├── footer.yaml │ │ │ │ └── legal.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── navigation │ │ │ │ ├── footer.yaml │ │ │ │ └── legal.yaml │ │ │ └── views │ │ │ └── layout │ │ │ └── _footer.antlers.html │ ├── hero │ │ ├── config.php │ │ └── resources │ │ │ ├── fieldsets │ │ │ └── hero.yaml │ │ │ └── views │ │ │ └── layout │ │ │ └── _hero.antlers.html │ ├── image_credits │ │ ├── config.php │ │ └── resources │ │ │ ├── blueprints │ │ │ └── assets │ │ │ │ └── images.yaml │ │ │ ├── fieldsets │ │ │ └── image_credits.yaml │ │ │ └── views │ │ │ └── page_builder │ │ │ └── _image_credits.antlers.html │ ├── language_picker │ │ ├── config.php │ │ └── resources │ │ │ └── views │ │ │ └── navigation │ │ │ └── _language_picker.antlers.html │ ├── mega_menu │ │ ├── config.php │ │ ├── content │ │ │ └── navigation │ │ │ │ └── main.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── navigation │ │ │ │ └── main.yaml │ │ │ └── views │ │ │ └── navigation │ │ │ ├── _main_desktop.antlers.html │ │ │ └── _main_mobile.antlers.html │ ├── modal │ │ ├── config.php │ │ └── resources │ │ │ ├── fieldsets │ │ │ └── invoke_modal.yaml │ │ │ └── views │ │ │ └── components │ │ │ ├── _invoke_modal.antlers.html │ │ │ └── _modal.antlers.html │ ├── news │ │ ├── config.php │ │ ├── content │ │ │ └── collections │ │ │ │ ├── news.yaml │ │ │ │ └── pages │ │ │ │ └── news.md │ │ └── resources │ │ │ ├── blueprints │ │ │ └── collections │ │ │ │ └── news │ │ │ │ └── news.yaml │ │ │ ├── fieldsets │ │ │ ├── index_content.yaml │ │ │ └── news.yaml │ │ │ └── views │ │ │ ├── components │ │ │ └── _news_item.antlers.html │ │ │ ├── feed │ │ │ └── feed.antlers.xml │ │ │ ├── news │ │ │ ├── index.antlers.html │ │ │ └── show.antlers.html │ │ │ └── page_builder │ │ │ ├── _index_content.antlers.html │ │ │ └── _news.antlers.html │ ├── password_protection │ │ ├── config.php │ │ ├── content │ │ │ └── collections │ │ │ │ └── pages │ │ │ │ └── login.md │ │ └── resources │ │ │ ├── fieldsets │ │ │ ├── login.yaml │ │ │ └── protect.yaml │ │ │ └── views │ │ │ └── page_builder │ │ │ └── _login.antlers.html │ ├── pricing │ │ ├── app │ │ │ └── Scopes │ │ │ │ └── Multiselect.php │ │ ├── config.php │ │ ├── content │ │ │ ├── collections │ │ │ │ ├── features.yaml │ │ │ │ └── tiers.yaml │ │ │ └── taxonomies │ │ │ │ └── groups.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ ├── collections │ │ │ │ ├── features │ │ │ │ │ └── feature.yaml │ │ │ │ └── tiers │ │ │ │ │ └── tier.yaml │ │ │ └── taxonomies │ │ │ │ └── groups │ │ │ │ └── group.yaml │ │ │ ├── fieldsets │ │ │ ├── features.yaml │ │ │ └── tiers.yaml │ │ │ ├── svg │ │ │ ├── check.svg │ │ │ └── cross.svg │ │ │ └── views │ │ │ └── page_builder │ │ │ ├── _features.antlers.html │ │ │ └── _tiers.antlers.html │ ├── search │ │ ├── config.php │ │ └── resources │ │ │ └── views │ │ │ ├── components │ │ │ └── _search_form.antlers.html │ │ │ └── search.antlers.html │ ├── secure_downloads │ │ ├── app │ │ │ ├── Http │ │ │ │ └── Controllers │ │ │ │ │ └── DownloadController.php │ │ │ └── Tags │ │ │ │ └── Download.php │ │ ├── config.php │ │ ├── content │ │ │ └── assets │ │ │ │ └── downloads.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── assets │ │ │ │ └── downloads.yaml │ │ │ ├── fieldsets │ │ │ └── downloads.yaml │ │ │ └── views │ │ │ └── page_builder │ │ │ └── _downloads.antlers.html │ ├── team_members │ │ ├── config.php │ │ ├── content │ │ │ └── collections │ │ │ │ └── team_members.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── collections │ │ │ │ └── team_members │ │ │ │ └── team_members.yaml │ │ │ ├── fieldsets │ │ │ └── team_members.yaml │ │ │ └── views │ │ │ └── page_builder │ │ │ └── _team_members.antlers.html │ ├── testimonials │ │ ├── config.php │ │ ├── content │ │ │ └── collections │ │ │ │ └── testimonials.yaml │ │ └── resources │ │ │ ├── blueprints │ │ │ └── collections │ │ │ │ └── testimonials │ │ │ │ └── testimonials.yaml │ │ │ ├── fieldsets │ │ │ └── testimonials.yaml │ │ │ └── views │ │ │ └── page_builder │ │ │ └── _testimonials.antlers.html │ ├── theme_toggle │ │ ├── config.php │ │ └── resources │ │ │ └── views │ │ │ └── components │ │ │ └── _theme_toggle.antlers.html │ └── vacancies │ │ ├── config.php │ │ ├── content │ │ └── collections │ │ │ ├── pages │ │ │ └── vacancies.md │ │ │ └── vacancies.yaml │ │ └── resources │ │ ├── blueprints │ │ └── collections │ │ │ └── vacancies │ │ │ └── vacancies.yaml │ │ ├── fieldsets │ │ └── index_content.yaml │ │ └── views │ │ ├── components │ │ └── _vacancies_item.antlers.html │ │ ├── page_builder │ │ └── _index_content.antlers.html │ │ └── vacancies │ │ ├── index.antlers.html │ │ └── show.antlers.html ├── sets │ ├── read_more │ │ ├── _read_more.antlers.html │ │ ├── config.php │ │ └── read_more.yaml │ └── video_self_hosted │ │ ├── _video_self_hosted.antlers.html │ │ ├── config.php │ │ └── video_self_hosted.yaml └── stubs │ ├── block.antlers.html.stub │ ├── collection.yaml.stub │ ├── collection_blueprint_private.yaml.stub │ ├── collection_blueprint_private_dated.yaml.stub │ ├── collection_blueprint_private_dated_no_slug.yaml.stub │ ├── collection_blueprint_private_no_slug.yaml.stub │ ├── collection_blueprint_public.yaml.stub │ ├── collection_blueprint_public_dated.yaml.stub │ ├── collection_blueprint_public_dated_no_slug.yaml.stub │ ├── collection_blueprint_public_no_slug.yaml.stub │ ├── fieldset_block.yaml.stub │ ├── fieldset_set.yaml.stub │ ├── global.yaml.stub │ ├── global_blueprint.yaml.stub │ ├── home.md.stub │ ├── index.antlers.html.stub │ ├── navigation.yaml.stub │ ├── navigation_blueprint.yaml.stub │ ├── partial.antlers.html.stub │ ├── set.antlers.html.stub │ ├── show.antlers.html.stub │ ├── taxonomy.yaml.stub │ └── taxonomy_blueprint.yaml.stub ├── src ├── Commands │ ├── ClearSite.php │ ├── InstallBlock.php │ ├── InstallCommand.php │ ├── InstallPreset.php │ ├── InstallSet.php │ ├── MakeBlock.php │ ├── MakeCollection.php │ ├── MakeGlobal.php │ ├── MakeNav.php │ ├── MakePartial.php │ ├── MakeSet.php │ ├── MakeTaxonomy.php │ └── Traits │ │ ├── CanClearCache.php │ │ ├── HandleWithCatch.php │ │ └── NeedsValidLicense.php ├── Facades │ └── Registry.php ├── Models │ ├── Block.php │ ├── Collection.php │ ├── Globals.php │ ├── Installable.php │ ├── Nav.php │ ├── Partial.php │ ├── Set.php │ └── Taxonomy.php ├── Operations │ ├── AttachCollectionsToNavigation.php │ ├── AttachTaxonomyToCollections.php │ ├── Copy.php │ ├── Notify.php │ ├── Operation.php │ ├── Rename.php │ ├── Run.php │ ├── Traits │ │ └── CanPickIcon.php │ ├── UpdateArticleSets.php │ ├── UpdatePageBuilder.php │ └── UpdateRole.php ├── RegistryManager.php ├── ServiceProvider.php └── Updates │ ├── UpdateJSONldDateFormatting.php │ └── UpdateRSSFeed.php └── tests ├── Facades └── RegistryTest.php ├── Operations └── OperationTest.php └── TestCase.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: studio1902 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yaml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Fill out a bug report to help us improve Statamic. 3 | body: 4 | - type: textarea 5 | attributes: 6 | label: Bug description 7 | description: What happened? What did you expect to happen? Feel free to drop any screenshots in here. 8 | placeholder: I did this thing over here, and saw this error... 9 | validations: 10 | required: true 11 | - type: textarea 12 | attributes: 13 | label: How to reproduce 14 | description: List the steps so we're able to recreate this bug. Bonus points if you can provide an example GitHub repo with this bug reproduced. 15 | placeholder: Go here, Type this, Click that, Look over there. 16 | validations: 17 | required: true 18 | - type: textarea 19 | attributes: 20 | label: Logs 21 | description: You can paste any relevant logs here, they'll be automatically rendered in code blocks. You can find your logs in `storage/logs`. 22 | render: shell 23 | - type: textarea 24 | attributes: 25 | label: Environment 26 | description: | 27 | Details about your environment. Versions of Statamic, PHP, Laravel, any addons that are installed, etc. 28 | (Go ahead and just paste the output of the `php please support:details` command.) 29 | render: yaml # the format of the command is close to yaml and gets highlighted nicely 30 | validations: 31 | required: true 32 | - type: dropdown 33 | attributes: 34 | label: Installation 35 | description: How did you install Statamic? 36 | options: 37 | - Fresh statamic/statamic site via CLI 38 | - Starter Kit using via CLI 39 | - Existing Laravel app 40 | - Other (please explain) 41 | validations: 42 | required: true 43 | - type: dropdown 44 | attributes: 45 | label: Antlers Parser 46 | description: If using 3.3+, which Antlers Parser are you using? 47 | options: 48 | - regex (default) 49 | - runtime (new) 50 | validations: 51 | required: false 52 | - type: textarea 53 | attributes: 54 | label: Additional details 55 | description: Fancy setup? Anything else you need to share? 56 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Make sure you [discussed your idea](https://github.com/studio1902/statamic-peak-commands/discussions) before doing a PR. 2 | 3 | Fixes # . 4 | 5 | Changes proposed in this pull request: 6 | - 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | vendor 3 | mix-manifest.json 4 | composer.lock 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © Studio 1902. 2 | 3 | Permission is hereby granted to any person obtaining a copy of this software (the “Software”) to use, publish and/or distribute copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | 1. **Do not plagiarize.** The above copyright notice and this license shall be included in all copies or substantial portions of the Software. 6 | 7 | 2. **Do not use the same license on more than one project.** Each licensed copy of the Software shall be actively installed in no more than one production or development environment at a time. 8 | 9 | 3. **Do not alter the licensing features.** Software features related to licensing shall not be altered or circumvented in any way, including (but not limited to) license validation, feature or edition restrictions, and update eligibility. 10 | 11 | 4. **Not for reuse.** The Software and the proprietary code therein, not limited to but including designs, components, classes, and patterns, may not be reused in other projects without the express written consent of Studio 1902. 12 | 13 | 5. **Follow the law.** All use of the Software shall not violate any applicable law or regulation, nor infringe the rights of any other person or entity. 14 | 15 | Failure to comply with the foregoing conditions will automatically and immediately result in termination of the permission granted hereby. This license does not include any right to receive updates to the Software or technical support. Licensees bear all risk related to the quality and 16 | performance of the Software and any modifications made or obtained to it, including liability for actual and consequential harm, such as loss or corruption of data, and any necessary service, repair, or correction. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, INCLUDING SPECIAL, INCIDENTAL AND CONSEQUENTIAL DAMAGES, WHETHER IN 19 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Statamic Peak Logo 2 | 3 | # Statamic Peak Commands 4 | 5 | This is a paid addon for [Statamic Peak](https://github.com/studio1902/statamic-peak) that contains the various Peak CLI commands. The addon will only work when you have a valid license (also in development). 6 | 7 | * peak:clear-site 8 | * peak:install:block 9 | * peak:install:preset 10 | * peak:make:block 11 | * peak:make:collection 12 | * peak:make:global 13 | * peak:make:nav 14 | * peak:make:partial 15 | * peak:make:set 16 | * peak:make:taxonomy 17 | 18 | [Read the docs](https://peak.1902.studio/getting-started/commands.html). 19 | 20 | ## How to Install 21 | 22 | This addon is automatically installed when you install Peak via the Statamic CLI. If you want to install this addon manually on an older Peak install run: 23 | 24 | ``` bash 25 | composer require studio1902/statamic-peak-commands 26 | ``` 27 | 28 | ## Contributing 29 | Contributions and discussions are always welcome, no matter how large or small. Treat each other with respect. Read the [Code of Conduct](https://github.com/studio1902/statamic-peak-commands/blob/main/.github/CODE_OF_CONDUCT.md). 30 | 31 | Read more about [how you can contribute](https://peak.1902.studio/other/contributing.html) here. 32 | 33 | ## License 34 | Statamic Peak Commands is paid software with an open-source codebase. If you want to use it, you’ll need to buy a license from the Statamic Marketplace. The license is valid for only one project. Statamic itself is commercial software and has its' own license. 35 | 36 | [The Agency Sponsorship](https://github.com/sponsors/studio1902) tier grants you unlimited licenses for the duration of your sponsorship. 37 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "studio1902/statamic-peak-commands", 3 | "autoload": { 4 | "psr-4": { 5 | "Studio1902\\PeakCommands\\": "src" 6 | } 7 | }, 8 | "autoload-dev": { 9 | "psr-4": { 10 | "Studio1902\\PeakCommands\\Tests\\": "tests" 11 | } 12 | }, 13 | "extra": { 14 | "statamic": { 15 | "name": "Statamic Peak Commands", 16 | "description": "Statamic Peak Commands addon" 17 | }, 18 | "laravel": { 19 | "providers": [ 20 | "Studio1902\\PeakCommands\\ServiceProvider" 21 | ] 22 | } 23 | }, 24 | "require": { 25 | "php": "^8.2", 26 | "statamic/cms": "^5.0" 27 | }, 28 | "require-dev": { 29 | "spatie/laravel-ray": "^1.39", 30 | "orchestra/testbench": "^9.0", 31 | "laravel/pint": "^1.22" 32 | }, 33 | "config": { 34 | "allow-plugins": { 35 | "pixelfear/composer-dist-plugin": true 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /config/statamic-peak-commands.php: -------------------------------------------------------------------------------- 1 | [ 9 | 'blocks' => [ 10 | base_path('vendor/studio1902/statamic-peak-commands/resources/blocks'), 11 | ], 12 | 'presets' => [ 13 | base_path('vendor/studio1902/statamic-peak-commands/resources/presets'), 14 | ], 15 | 'sets' => [ 16 | base_path('vendor/studio1902/statamic-peak-commands/resources/sets'), 17 | ], 18 | ], 19 | 20 | /** 21 | * Here you can configure the namespaces in which the commands addon 22 | * searches for available operations to run. 23 | */ 24 | 'namespaces' => [ 25 | '\Studio1902\PeakCommands\Operations', 26 | ], 27 | ]; 28 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ./tests 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resources/blocks/call_to_action/_call_to_action.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Call to action 3 | @desc The call to action page builder block. 4 | @set page.page_builder.call_to_action 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ partial:typography/h2 class="mb-4" :content="block:title" }} 11 | {{ partial:typography/p class="mb-4" :content="block:text" }} 12 | {{ block:buttons ?= { partial:components/buttons } }} 13 |
14 | {{ /partial:page_builder/block }} 15 | 16 | -------------------------------------------------------------------------------- /resources/blocks/call_to_action/call_to_action.yaml: -------------------------------------------------------------------------------- 1 | title: 'Call to action' 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | type: text 8 | localizable: true 9 | listable: hidden 10 | display: Title 11 | validate: 12 | - required 13 | - 14 | handle: text 15 | field: common.text_plain 16 | config: 17 | validate: 18 | - required 19 | - 20 | import: buttons 21 | -------------------------------------------------------------------------------- /resources/blocks/call_to_action/config.php: -------------------------------------------------------------------------------- 1 | 'call_to_action', 5 | 'name' => 'Call to action', 6 | 'description' => 'Show a call to action.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_call_to_action.antlers.html', 11 | 'output' => 'resources/views/page_builder/_call_to_action.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'call_to_action.yaml', 16 | 'output' => 'resources/fieldsets/call_to_action.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Call to action', 22 | 'instructions' => 'Show a call to action.', 23 | 'icon' => 'alert-alarm-bell', 24 | 'handle' => 'call_to_action', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/cards/_cards.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Cards 3 | @desc The Cards page builder block. 4 | @set page.page_builder.cards 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block class="gap-y-8" }} 9 | {{ if block:title }} 10 |
11 | {{ partial:typography/h2 :content="block:title" class="md:col-start-3 md:col-span-8 text-center" }} 12 |
13 | {{ /if }} 14 | 15 | 50 | {{ /partial:page_builder/block }} 51 | 52 | -------------------------------------------------------------------------------- /resources/blocks/cards/cards.yaml: -------------------------------------------------------------------------------- 1 | title: Cards 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | type: text 8 | localizable: true 9 | listable: hidden 10 | display: Title 11 | - 12 | handle: cards 13 | field: 14 | reorderable: true 15 | type: replicator 16 | localizable: true 17 | listable: hidden 18 | display: Cards 19 | replicator_preview: false 20 | instructions_position: above 21 | visibility: visible 22 | collapse: accordion 23 | previews: true 24 | fullscreen: true 25 | button_label: 'Add card' 26 | sets: 27 | cards: 28 | display: Cards 29 | instructions: null 30 | icon: null 31 | sets: 32 | card: 33 | display: Card 34 | instructions: null 35 | icon: null 36 | fields: 37 | - 38 | handle: title 39 | field: 40 | input_type: text 41 | type: text 42 | localizable: true 43 | listable: hidden 44 | validate: required 45 | display: Title 46 | - 47 | handle: text 48 | field: common.text_plain 49 | config: 50 | display: Text 51 | - 52 | handle: button 53 | field: buttons.buttons 54 | config: 55 | display: Button 56 | max_rows: 1 57 | hide_display: true 58 | -------------------------------------------------------------------------------- /resources/blocks/cards/config.php: -------------------------------------------------------------------------------- 1 | 'cards', 5 | 'name' => 'Cards', 6 | 'description' => 'Cards that link using the button fieldset.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_cards.antlers.html', 11 | 'output' => 'resources/views/page_builder/_cards.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'cards.yaml', 16 | 'output' => 'resources/fieldsets/cards.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Cards', 22 | 'instructions' => 'Cards that link using the button fieldset.', 23 | 'icon' => 'link', 24 | 'handle' => 'cards', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/collection/_collection.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Collection 3 | @desc The collection page builder block. 4 | @set page.page_builder.collection 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ partial:typography/h2 class="mb-4" :content="block:title" }} 11 | 20 |
21 | {{ /partial:page_builder/block }} 22 | 23 | -------------------------------------------------------------------------------- /resources/blocks/collection/collection.yaml: -------------------------------------------------------------------------------- 1 | title: Collection entries 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | type: text 8 | localizable: true 9 | listable: hidden 10 | display: Title 11 | validate: 12 | - required 13 | - 14 | handle: collection 15 | field: 16 | mode: default 17 | type: entries 18 | localizable: true 19 | listable: hidden 20 | display: Collection 21 | instructions: 'The entries you want to link to.' 22 | validate: required 23 | -------------------------------------------------------------------------------- /resources/blocks/collection/config.php: -------------------------------------------------------------------------------- 1 | 'collection', 5 | 'name' => 'Collection', 6 | 'description' => 'Show collection entries.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_collection.antlers.html', 11 | 'output' => 'resources/views/page_builder/_collection.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'collection.yaml', 16 | 'output' => 'resources/fieldsets/collection.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Collection', 22 | 'instructions' => 'Show collection entries.', 23 | 'icon' => 'file-content-list', 24 | 'handle' => 'collection', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/columns/_columns.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Columns 3 | @desc The Columns page builder block. 4 | @set page.page_builder.columns 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ block:columns }} 11 |
20 | {{ partial 21 | src="statamic-peak-tools::components/picture" 22 | sizes=" 23 | { switch( 24 | (total_results == 1) => '(min-width: 1280px) 1150px, 90vw', 25 | (total_results == 2) => '(min-width: 1280px) 640px, (min-width: 768px) 50vw, 90vw', 26 | (total_results >= 3) => '(min-width: 1280px) 430px, (min-width: 768px) 33vw, 90vw', 27 | )} 28 | " 29 | aspect_ratio="{ total_results > 1 ?= 'large:4/3' }" 30 | :image="image" 31 | class="mb-6" 32 | lazy="true" 33 | }} 34 | 35 | {{ partial:typography/prose as="div" class="{ buttons ?= 'mb-6' }" }} 36 | {{ text }} 37 | {{ /partial:typography/prose }} 38 | 39 | {{ partial:components/buttons }} 40 |
41 | {{ /block:columns }} 42 |
43 | {{ /partial:page_builder/block }} 44 | 45 | -------------------------------------------------------------------------------- /resources/blocks/columns/columns.yaml: -------------------------------------------------------------------------------- 1 | title: Columns 2 | fields: 3 | - 4 | handle: columns 5 | field: 6 | reorderable: true 7 | type: replicator 8 | localizable: true 9 | listable: hidden 10 | display: 'Columns' 11 | replicator_preview: false 12 | instructions_position: above 13 | visibility: visible 14 | collapse: accordion 15 | previews: true 16 | fullscreen: true 17 | button_label: 'Add column' 18 | sets: 19 | columns: 20 | display: Columns 21 | instructions: null 22 | icon: null 23 | sets: 24 | column: 25 | display: Column 26 | instructions: null 27 | icon: null 28 | fields: 29 | - 30 | handle: image 31 | field: common.image 32 | - 33 | handle: text 34 | field: common.text_rich 35 | config: 36 | validate: 37 | - required 38 | - 39 | import: buttons 40 | hide_display: true 41 | -------------------------------------------------------------------------------- /resources/blocks/columns/config.php: -------------------------------------------------------------------------------- 1 | 'columns', 5 | 'name' => 'Columns', 6 | 'description' => 'Text columns with optional images and buttons.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_columns.antlers.html', 11 | 'output' => 'resources/views/page_builder/_columns.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'columns.yaml', 16 | 'output' => 'resources/fieldsets/columns.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Columns', 22 | 'instructions' => 'Text columns with optional images and buttons.', 23 | 'icon' => 'layout-two-columns', 24 | 'handle' => 'columns', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/divider/_divider.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Divider 3 | @desc The Divider page builder block. 4 | @set page.page_builder.divider 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ /partial:page_builder/block }} 11 | 12 | -------------------------------------------------------------------------------- /resources/blocks/divider/config.php: -------------------------------------------------------------------------------- 1 | 'divider', 5 | 'name' => 'Divider', 6 | 'description' => 'A visual divider between blocks.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_divider.antlers.html', 11 | 'output' => 'resources/views/page_builder/_divider.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'divider.yaml', 16 | 'output' => 'resources/fieldsets/divider.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Divider', 22 | 'instructions' => 'A visual divider between blocks.', 23 | 'icon' => 'layout-table-row-insert', 24 | 'handle' => 'divider', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/divider/divider.yaml: -------------------------------------------------------------------------------- 1 | title: 'Divider' 2 | fields: [ ] 3 | -------------------------------------------------------------------------------- /resources/blocks/full_width_image/_full_width_image.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Full width image 3 | @desc The Full width image page builder block. 4 | @set page.page_builder.full_width_image 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block class="min-h-[14rem]" }} 9 |
10 | {{ partial:statamic-peak-tools::components/picture :image="block:image" aspect_ratio="2/1 large:3/1" cover="true" lazy="true" sizes="100vw" }} 11 |
12 | 13 | {{ if block:title || block:text || block:buttons }} 14 | 16 | {{ /if }} 17 | 18 |
19 | {{ title ?= { partial:typography/h2 :content="block:title" color="text-white" class="text-center" } }} 20 | {{ text ?= { partial:typography/p :content="block:text" color="text-white" class="text-center" } }} 21 | {{ partial:components/buttons inverted="true" class="justify-center" }} 22 |
23 | {{ /partial:page_builder/block }} 24 | 25 | -------------------------------------------------------------------------------- /resources/blocks/full_width_image/config.php: -------------------------------------------------------------------------------- 1 | 'full_width_image', 5 | 'name' => 'Full width image', 6 | 'description' => 'A full width image with optional text and button(s).', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_full_width_image.antlers.html', 11 | 'output' => 'resources/views/page_builder/_full_width_image.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'full_width_image.yaml', 16 | 'output' => 'resources/fieldsets/full_width_image.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Full width image', 22 | 'instructions' => 'A full width image with optional text and button(s).', 23 | 'icon' => 'media-image-picture-orientation', 24 | 'handle' => 'full_width_image', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/full_width_image/full_width_image.yaml: -------------------------------------------------------------------------------- 1 | title: 'Full width image' 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: Title 9 | type: text 10 | icon: text 11 | listable: hidden 12 | instructions_position: above 13 | visibility: visible 14 | always_save: false 15 | - 16 | handle: text 17 | field: common.text_plain 18 | - 19 | import: buttons 20 | - 21 | handle: image 22 | field: common.image 23 | config: 24 | display: 'Background image' 25 | width: 50 26 | validate: 27 | - required 28 | -------------------------------------------------------------------------------- /resources/blocks/image_and_text/_image_and_text.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Image and text 3 | @desc The Image and text page builder block. 4 | @set page.page_builder.image_and_text 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block class="gap-y-8 items-center grid-flow-col" }} 9 |
10 | {{ block:title ?= { partial:typography/h2 :content="block:title" } }} 11 | 12 | {{ partial:typography/prose }} 13 | {{ block:text }} 14 | {{ /partial:typography/prose }} 15 | 16 | {{ partial:components/buttons }} 17 |
18 | 19 |
20 | {{ partial:statamic-peak-tools::components/picture :image="block:image" cover="true" sizes="(min-width: 1280px) 640px, (min-width: 768px) 50vw, 90vw" }} 21 |
22 | {{ /partial:page_builder/block }} 23 | 24 | -------------------------------------------------------------------------------- /resources/blocks/image_and_text/config.php: -------------------------------------------------------------------------------- 1 | 'image_and_text', 5 | 'name' => 'Image and text', 6 | 'description' => 'An image and text side by side.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_image_and_text.antlers.html', 11 | 'output' => 'resources/views/page_builder/_image_and_text.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'image_and_text.yaml', 16 | 'output' => 'resources/fieldsets/image_and_text.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Image and text', 22 | 'instructions' => 'An image and text side by side.', 23 | 'icon' => 'text-formatting-image-left', 24 | 'handle' => 'image_and_text', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/image_and_text/image_and_text.yaml: -------------------------------------------------------------------------------- 1 | title: 'Image and text' 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: Title 9 | type: text 10 | icon: text 11 | listable: hidden 12 | instructions_position: above 13 | visibility: visible 14 | always_save: false 15 | - 16 | handle: text 17 | field: common.text_basic 18 | config: 19 | buttons: 20 | - bold 21 | - italic 22 | - unorderedlist 23 | - orderedlist 24 | - removeformat 25 | - anchor 26 | display: Text 27 | validate: 28 | - required 29 | - 30 | import: buttons 31 | - 32 | handle: image 33 | field: common.image 34 | config: 35 | width: 50 36 | validate: 37 | - required 38 | - 39 | handle: image_position 40 | field: 41 | options: 42 | left: Left 43 | right: Right 44 | default: right 45 | display: 'Image position' 46 | type: button_group 47 | icon: button_group 48 | replicator_preview: false 49 | width: 50 50 | listable: hidden 51 | instructions_position: above 52 | visibility: visible 53 | always_save: false 54 | validate: 55 | - required 56 | -------------------------------------------------------------------------------- /resources/blocks/images_grid/_images_grid.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Images grid 3 | @desc The Images grid page builder block. 4 | @set page.page_builder.images_grid 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ block:rows }} 11 | {{ images }} 12 |
19 | {{ partial 20 | src="statamic-peak-tools::components/picture" 21 | :image="url" 22 | sizes=" 23 | { switch( 24 | (total_results == 1) => '(min-width: 1280px) 1150px, 90vw', 25 | (total_results == 2) => '(min-width: 1280px) 640px, (min-width: 768px) 50vw, 90vw', 26 | (total_results == 3) => '(min-width: 1280px) 430px, (min-width: 768px) 33vw, 90vw', 27 | )} 28 | " 29 | aspect_ratio="{ total_results > 1 ?= 'large:4/3' }" 30 | cover="{ total_results == 1 ? false : true }" 31 | lazy="true" 32 | }} 33 |
34 | {{ /images }} 35 | {{ /block:rows }} 36 |
37 | {{ /partial:page_builder/block }} 38 | 39 | -------------------------------------------------------------------------------- /resources/blocks/images_grid/config.php: -------------------------------------------------------------------------------- 1 | 'images_grid', 5 | 'name' => 'Images grid', 6 | 'description' => 'A multi row image grid.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_images_grid.antlers.html', 11 | 'output' => 'resources/views/page_builder/_images_grid.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'images_grid.yaml', 16 | 'output' => 'resources/fieldsets/images_grid.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Images grid', 22 | 'instructions' => 'A multi row image grid.', 23 | 'icon' => 'layout-grid-dots', 24 | 'handle' => 'images_grid', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/images_grid/images_grid.yaml: -------------------------------------------------------------------------------- 1 | title: 'Images grid' 2 | fields: 3 | - 4 | handle: rows 5 | field: 6 | fields: 7 | - 8 | handle: images 9 | field: 10 | mode: list 11 | container: images 12 | restrict: false 13 | allow_uploads: true 14 | show_filename: true 15 | max_files: 3 16 | display: Images 17 | type: assets 18 | icon: assets 19 | listable: hidden 20 | instructions_position: above 21 | visibility: visible 22 | always_save: false 23 | validate: 24 | - required 25 | mode: table 26 | add_row: 'Add image row' 27 | reorderable: true 28 | display: Rows 29 | type: grid 30 | icon: grid 31 | listable: hidden 32 | instructions_position: above 33 | replicator_preview: false 34 | visibility: visible 35 | always_save: false 36 | -------------------------------------------------------------------------------- /resources/blocks/index_content/_index_content.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Index content 3 | @desc The Index content page builder block. 4 | @set page.page_builder.index_content 5 | #}} 6 | 7 | {{ partial:page_builder/block }} 8 | {{ yield:index_content }} 9 | {{ /partial:page_builder/block }} 10 | -------------------------------------------------------------------------------- /resources/blocks/index_content/config.php: -------------------------------------------------------------------------------- 1 | 'index_content', 5 | 'name' => 'Index content', 6 | 'description' => 'Render the currently mounted entries if available.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_index_content.antlers.html', 11 | 'output' => 'resources/views/page_builder/_index_content.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'index_content.yaml', 16 | 'output' => 'resources/fieldsets/index_content.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Index content', 22 | 'instructions' => 'Render the currently mounted entries if available.', 23 | 'icon' => 'file-content-list', 24 | 'handle' => 'index_content', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/index_content/index_content.yaml: -------------------------------------------------------------------------------- 1 | title: 'Index content' 2 | fields: [ ] 3 | -------------------------------------------------------------------------------- /resources/blocks/text_columns/_text_columns.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Text columns 3 | @desc The Text columns page builder block. 4 | @set page.page_builder.text_columns 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ block:title ?= { partial:typography/h3 as="h2" :content="block:title" class="mb-2 md:max-w-[1/2]" } }} 11 | 12 | {{ partial:typography/prose class="md:columns-2 gap-6 md:[&>ul]:inline-block md:[&>ul]:!mt-0 md:[&>ul]:mb-5 md:[&>ul]:break-inside-avoid md:[&>ol]:inline-block md:[&>ol]:!mt-0 md:[&>ol]:mb-5 md:[&>ol]:break-inside-avoid md:[&>p]:!mt-0 13 | " }} 14 | {{ block:text }} 15 | {{ /partial:typography/prose }} 16 |
17 | {{ /partial:page_builder/block }} 18 | 19 | -------------------------------------------------------------------------------- /resources/blocks/text_columns/config.php: -------------------------------------------------------------------------------- 1 | 'text_columns', 5 | 'name' => 'Text columns', 6 | 'description' => 'Text wrapping in two columns.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_text_columns.antlers.html', 11 | 'output' => 'resources/views/page_builder/_text_columns.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'text_columns.yaml', 16 | 'output' => 'resources/fieldsets/text_columns.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_page_builder', 20 | 'block' => [ 21 | 'name' => 'Text columns', 22 | 'instructions' => 'Text wrapping in two columns.', 23 | 'icon' => 'layout-three-columns', 24 | 'handle' => 'text_columns', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/blocks/text_columns/text_columns.yaml: -------------------------------------------------------------------------------- 1 | title: 'Text columns' 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: Title 9 | type: text 10 | icon: text 11 | listable: hidden 12 | instructions_position: above 13 | visibility: visible 14 | always_save: false 15 | - 16 | handle: text 17 | field: common.text_rich 18 | config: 19 | buttons: 20 | - bold 21 | - italic 22 | - unorderedlist 23 | - orderedlist 24 | - removeformat 25 | - anchor 26 | validate: 27 | - required 28 | -------------------------------------------------------------------------------- /resources/presets/banner/config.php: -------------------------------------------------------------------------------- 1 | 'banner', 5 | 'name' => 'Banner', 6 | 'description' => 'A banner on top of your site users can click to hide.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/blueprints/globals/banner.yaml', 11 | 'output' => 'resources/blueprints/globals/banner.yaml', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'content/globals/banner.yaml', 16 | 'output' => 'content/globals/banner.yaml', 17 | ], 18 | [ 19 | 'type' => 'copy', 20 | 'input' => 'resources/views/layout/_banner.antlers.html', 21 | 'output' => 'resources/views/layout/_banner.antlers.html', 22 | ], 23 | [ 24 | 'type' => 'copy', 25 | 'input' => 'resources/svg/close.svg', 26 | 'output' => 'resources/svg/close.svg', 27 | ], 28 | [ 29 | 'type' => 'update_role', 30 | 'role' => 'editor', 31 | 'permissions' => ['edit banner globals'], 32 | ], 33 | [ 34 | 'type' => 'notify', 35 | 'content' => 'Make sure to add `{{ partial:layout/banner }}` to your layout file after opening the ``.', 36 | ], 37 | [ 38 | 'type' => 'notify', 39 | 'content' => "Add this to your `lang/locale/strings.php` file:\n\n// Banner\n'banner_close' => 'Close banner',", 40 | ], 41 | ], 42 | ]; 43 | -------------------------------------------------------------------------------- /resources/presets/banner/content/globals/banner.yaml: -------------------------------------------------------------------------------- 1 | use_banner: false 2 | -------------------------------------------------------------------------------- /resources/presets/banner/resources/blueprints/globals/banner.yaml: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: Banner 7 | fields: 8 | - 9 | handle: use_banner 10 | field: 11 | display: 'Use banner' 12 | type: toggle 13 | localizable: true 14 | - 15 | handle: text 16 | field: common.text_basic 17 | config: 18 | localizable: true 19 | inline: true 20 | validate: 21 | - 'required_if:use_banner,true' 22 | -------------------------------------------------------------------------------- /resources/presets/banner/resources/svg/close.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/presets/banner/resources/views/layout/_banner.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Banner 3 | @desc The sites optional banner rendered on each page. 4 | #}} 5 | 6 | 7 | {{ if banner:use_banner }} 8 |
15 |
16 | {{ partial:typography/prose as="article" class="prose-invert" }} 17 | {{ banner:text }} 18 | {{ /partial:typography/prose }} 19 | 20 | 23 |
24 |
25 | {{ /if }} 26 | 27 | -------------------------------------------------------------------------------- /resources/presets/breadcrumbs/config.php: -------------------------------------------------------------------------------- 1 | 'breadcrumbs', 5 | 'name' => 'Breadcrumbs', 6 | 'description' => 'A breadcrumbs partial.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/views/navigation/_breadcrumbs.antlers.html', 11 | 'output' => 'resources/views/navigation/_breadcrumbs.antlers.html', 12 | ], 13 | ], 14 | ]; 15 | -------------------------------------------------------------------------------- /resources/presets/breadcrumbs/resources/views/navigation/_breadcrumbs.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Breadcrumbs 3 | @desc Breadcrumbs display the current page in it's page hierarcy. 4 | #}} 5 | 6 | 7 | 25 | 26 | -------------------------------------------------------------------------------- /resources/presets/business_hours/config.php: -------------------------------------------------------------------------------- 1 | 'business_hours', 5 | 'name' => 'Business hours', 6 | 'description' => 'Configure and list business hours, live open/closed component', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/blueprints/globals/business_hours.yaml', 11 | 'output' => 'resources/blueprints/globals/business_hours.yaml', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'content/globals/business_hours.yaml', 16 | 'output' => 'content/globals/business_hours.yaml', 17 | ], 18 | [ 19 | 'type' => 'copy', 20 | 'input' => 'resources/views/snippets/_business_hours.antlers.html', 21 | 'output' => 'resources/views/snippets/_business_hours.antlers.html', 22 | ], 23 | [ 24 | 'type' => 'copy', 25 | 'input' => 'resources/views/components/_business_hours.antlers.html', 26 | 'output' => 'resources/views/components/_business_hours.antlers.html', 27 | ], 28 | [ 29 | 'type' => 'copy', 30 | 'input' => 'resources/views/components/_call_now.antlers.html', 31 | 'output' => 'resources/views/components/_call_now.antlers.html', 32 | ], 33 | [ 34 | 'type' => 'copy', 35 | 'input' => 'resources/svg/phone.svg', 36 | 'output' => 'resources/svg/phone.svg', 37 | ], 38 | [ 39 | 'type' => 'notify', 40 | 'content' => 'Make sure to set the correct timezone in your environment file.', 41 | ], 42 | [ 43 | 'type' => 'notify', 44 | 'content' => 'Import the following partials where needed: `{{ partial:components/business_hours }}` and `{{ partial:components/call_now }}`.', 45 | ], 46 | [ 47 | 'type' => 'notify', 48 | 'content' => "Add this to your `lang/locale/strings.php` file:\n\n// Business hours\n'business_hours_can_reach' => 'Available now',\n'business_hours_cant_reach' => 'Not available now',\n'business_hours_closed' => 'Closed',\n'business_hours_open_now' => 'Open now',\n'business_hours_closed_now' => 'Closed now',\n'business_hours_monday' => 'Monday',\n'business_hours_tuesday' => 'Tuesday',\n'business_hours_wednesday' => 'Wednesday',\n'business_hours_thursday' => 'Thursday',\n'business_hours_friday' => 'Friday',\n'business_hours_saturday' => 'Saturday',\n'business_hours_sunday' => 'Sunday',", 49 | ], 50 | ], 51 | ]; 52 | -------------------------------------------------------------------------------- /resources/presets/business_hours/content/globals/business_hours.yaml: -------------------------------------------------------------------------------- 1 | title: 'Business hours' 2 | data: 3 | dates: 4 | - 5 | id: KcwMv4Y3 6 | weekday: monday 7 | open: true 8 | start_time: '08:30' 9 | end_time: '17:00' 10 | - 11 | id: RwZ13bUE 12 | weekday: tuesday 13 | open: true 14 | start_time: '08:30' 15 | end_time: '17:00' 16 | - 17 | id: AlCrWZYJ 18 | weekday: wednesday 19 | open: true 20 | start_time: '08:30' 21 | end_time: '17:00' 22 | - 23 | id: OdYNnHKv 24 | weekday: thursday 25 | open: true 26 | start_time: '08:30' 27 | end_time: '17:00' 28 | - 29 | id: vbusJ5GT 30 | weekday: friday 31 | open: true 32 | start_time: '08:30' 33 | end_time: '17:00' 34 | - 35 | id: 3HjTxO3Y 36 | weekday: saturday 37 | open: false 38 | - 39 | id: YKXcMIJA 40 | weekday: sunday 41 | open: false 42 | phone_number: '06 12 34 56 78' 43 | -------------------------------------------------------------------------------- /resources/presets/business_hours/resources/svg/phone.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/presets/business_hours/resources/views/components/_business_hours.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Business hours 3 | @desc The list business hours component tied to the business hours global. 4 | #}} 5 | 6 | 7 |
8 |
9 | 10 | 11 | 19 |
20 | 21 | {{ business_hours:dates }} 22 | 23 | 24 | 31 | 32 | {{ /business_hours:dates }} 33 |
{{ trans:strings.business_hours_{weekday} }} 25 | {{ if open }} 26 | {{ start_time }} - {{ end_time }} 27 | {{ else }} 28 | {{ trans:strings.business_hours_closed }} 29 | {{ /if }} 30 |
34 | {{ partial:snippets/business_hours }} 35 |
36 | 37 | -------------------------------------------------------------------------------- /resources/presets/clients/config.php: -------------------------------------------------------------------------------- 1 | 'clients', 5 | 'name' => 'Clients', 6 | 'singular_name' => 'Client', 7 | 'description' => 'A renamable client/partner collection.', 8 | 'operations' => [ 9 | [ 10 | 'type' => 'rename', 11 | ], 12 | [ 13 | 'type' => 'copy', 14 | 'input' => 'resources/blueprints/collections/clients/clients.yaml', 15 | 'output' => 'resources/blueprints/collections/{{ handle }}/{{ handle }}.yaml', 16 | ], 17 | [ 18 | 'type' => 'copy', 19 | 'input' => 'content/collections/clients.yaml', 20 | 'output' => 'content/collections/{{ handle }}.yaml', 21 | ], 22 | [ 23 | 'type' => 'copy', 24 | 'input' => 'resources/views/page_builder/_clients.antlers.html', 25 | 'output' => 'resources/views/page_builder/_{{ handle }}.antlers.html', 26 | ], 27 | [ 28 | 'type' => 'copy', 29 | 'input' => 'resources/fieldsets/clients.yaml', 30 | 'output' => 'resources/fieldsets/{{ handle }}.yaml', 31 | ], 32 | [ 33 | 'type' => 'update_page_builder', 34 | 'block' => [ 35 | 'name' => '{{ name }}', 36 | 'instructions' => 'A {{ name }} logo cloud.', 37 | 'icon' => 'favorite-award', 38 | 'handle' => '{{ handle }}', 39 | ], 40 | ], 41 | [ 42 | 'type' => 'update_role', 43 | 'role' => 'editor', 44 | 'permissions' => ['view {{ handle }} entries', 'edit {{ handle }} entries', 'create {{ handle }} entries', 'delete {{ handle }} entries', 'publish {{ handle }} entries', 'reorder {{ handle }} entries', 'edit other authors {{ handle }} entries', 'publish other authors {{ handle }} entries', 'delete other authors {{ handle }} entries'], 45 | ], 46 | [ 47 | 'type' => 'notify', 48 | 'content' => "Add this to your `lang/locale/strings.php` file:\n\n'clients_sr' => 'A list of the following clients',", 49 | ], 50 | [ 51 | 'type' => 'notify', 52 | 'content' => "Add this to your `config/statamic/cp.php` widgets array:\n\n[\n\t'type' => 'collection',\n\t'collection' => '{{ handle }}',\n\t'width' => 50\n],", 53 | ], 54 | ], 55 | ]; 56 | -------------------------------------------------------------------------------- /resources/presets/clients/content/collections/clients.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | template: default 3 | layout: layout 4 | revisions: false 5 | slugs: false 6 | sort_dir: asc 7 | date_behavior: 8 | past: public 9 | future: private 10 | preview_targets: 11 | - 12 | label: Entry 13 | url: '{permalink}' 14 | structure: 15 | root: false 16 | max_depth: 1 17 | -------------------------------------------------------------------------------- /resources/presets/clients/resources/blueprints/collections/clients/clients.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | handle: website 22 | field: 23 | input_type: url 24 | antlers: false 25 | display: Website 26 | type: text 27 | icon: text 28 | listable: hidden 29 | instructions_position: above 30 | visibility: visible 31 | always_save: false 32 | validate: 33 | - required 34 | - 35 | handle: logo 36 | field: common.image 37 | config: 38 | mode: grid 39 | listable: true 40 | display: Logo 41 | instructions_position: below 42 | instructions: 'This should be an `svg` file.' 43 | validate: 44 | - required 45 | - 'mimes:svg' 46 | -------------------------------------------------------------------------------- /resources/presets/clients/resources/fieldsets/clients.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: Title 9 | type: text 10 | icon: text 11 | listable: hidden 12 | instructions_position: above 13 | visibility: visible 14 | always_save: false 15 | - 16 | handle: {{ handle }} 17 | field: 18 | mode: default 19 | create: true 20 | collections: 21 | - {{ handle }} 22 | display: {{ name }} 23 | type: entries 24 | icon: entries 25 | instructions: 'Select entries or leave empty to show all.' 26 | listable: hidden 27 | instructions_position: below 28 | visibility: visible 29 | always_save: false 30 | -------------------------------------------------------------------------------- /resources/presets/clients/resources/views/page_builder/_clients.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} 3 | @desc The {{ name }} page builder block. 4 | @set page.page_builder.{{ handle }} 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ block:title ?= { partial:typography/h2 :content="block:title" class="col-span-2 md:col-span-10" } }} 11 | 12 | {{ 13 | {{ handle }} = block:{{ handle }} 14 | ? block:{{ handle }} 15 | : { collection:{{ handle }} sort="order" } 16 | }} 17 | 18 |

{{ trans:strings.clients_sr }}: {{ {{ handle }} | pluck('title') | sentence_list }}.

19 | 20 | {{ {{ handle }} }} 21 | 22 | {{ partial:statamic-peak-tools::components/picture :image="logo" class="grayscale group-focus-visible:grayscale-0 group-hover:grayscale-0 motion-safe:transition" }} 23 | 24 | {{ /{{ handle }} }} 25 |
26 | {{ /partial:page_builder/block }} 27 | 28 | -------------------------------------------------------------------------------- /resources/presets/events/content/collections/events.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | template: {{ handle }}/show 3 | layout: layout 4 | revisions: false 5 | route: '/{mount}/{slug}' 6 | date: true 7 | sort_dir: asc 8 | date_behavior: 9 | past: public 10 | future: private 11 | mount: ba821fde-cfa2-428d-b5c4-191f9c8e973d 12 | preview_targets: 13 | - 14 | label: Entry 15 | url: '{permalink}' 16 | refresh: false 17 | -------------------------------------------------------------------------------- /resources/presets/events/content/collections/pages/events.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: ba821fde-cfa2-428d-b5c4-191f9c8e973d 3 | blueprint: page 4 | title: {{ name }} 5 | template: {{ handle }}/index 6 | page_builder: 7 | - 8 | type: index_content 9 | enabled: true 10 | --- 11 | -------------------------------------------------------------------------------- /resources/presets/events/resources/fieldsets/events.yaml: -------------------------------------------------------------------------------- 1 | title: '{{ name }}' 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: Title 9 | type: text 10 | icon: text 11 | listable: hidden 12 | instructions_position: above 13 | visibility: visible 14 | always_save: false 15 | -------------------------------------------------------------------------------- /resources/presets/events/resources/fieldsets/index_content.yaml: -------------------------------------------------------------------------------- 1 | title: 'Index content' 2 | fields: [ ] 3 | -------------------------------------------------------------------------------- /resources/presets/events/resources/views/components/_events_item.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} item 3 | @desc A {{ name }} item component. 4 | @param class Add optional CSS classes. 5 | #}} 6 | 7 | 8 |
9 |
10 | {{ partial:statamic-peak-tools::components/picture :image="image" sizes="(min-width: 1280px) 430px, (min-width: 768px) 30vw, 90vw" aspect_ratio="3/2" lazy="true" cover="true" class="aspect-[3/2]" }} 11 |
12 | 13 |
14 | 22 | 23 | 24 | {{ partial:typography/h3 :content="title" class="underline decoration-primary decoration-2 underline-offset-2 group-hover:text-primary motion-safe:transition-colors" }} 25 | 26 | 27 | {{ partial:typography/p :content="teaser" }} 28 |
29 |
30 | 31 | -------------------------------------------------------------------------------- /resources/presets/events/resources/views/events/index.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} index 3 | @desc The {{ name }} index template. 4 | #}} 5 | 6 | 7 |
8 | {{ page_builder scope="block" }} 9 | {{ partial src="page_builder/{type}" }} 10 | {{ /page_builder }} 11 |
12 | 13 | 14 | {{ section:index_content }} 15 | 16 |
17 | {{ partial:typography/h1 as="h2" :content="title" class="md:col-span-12" }} 18 | {{ collection:{{ handle }} sort="{{ singular_handle }}_date_start:asc" {{ singular_handle }}_date_end:is_after="{ today }" paginate="true" limit="12" as="items" }} 19 | {{ unless no_results }} 20 | {{ items }} 21 | {{ partial:components/{{ handle }}_item class="md:col-span-4" }} 22 | {{ /items }} 23 | {{ else }} 24 |
25 | {{ trans:strings.no_results }} 26 |
27 | {{ /unless }} 28 | 29 | {{ partial:statamic-peak-tools::components/pagination class="md:col-span-12" }} 30 | {{ /collection:{{ handle }} }} 31 |
32 | 33 | {{ /section:index_content }} 34 | -------------------------------------------------------------------------------- /resources/presets/events/resources/views/page_builder/_events.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} 3 | @desc The {{ name }} page builder block. 4 | @set page.page_builder.{{ handle }} 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
10 | {{ title ?= { partial:typography/h1 as="h2" :content="title" class="md:col-span-12" } }} 11 | 12 | {{ collection:{{ handle }} sort="{{ singular_handle }}_date_start:asc" {{ singular_handle }}_date_end:is_after="{ today | modify_date('+1 day') }" limit="3" as="items" }} 13 | {{ unless no_results }} 14 | {{ items }} 15 | {{ partial:components/{{ handle }}_item class="md:col-span-4" }} 16 | {{ /items }} 17 | {{ else }} 18 |
19 | {{ trans:strings.no_results }} 20 |
21 | {{ /unless }} 22 | {{ /collection:{{ handle }} }} 23 | 24 | 27 |
28 | {{ /partial:page_builder/block }} 29 | 30 | -------------------------------------------------------------------------------- /resources/presets/events/resources/views/page_builder/_index_content.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Index content 3 | @desc The Index content page builder block. 4 | @set page.page_builder.index_content 5 | #}} 6 | 7 | {{ partial:page_builder/block }} 8 | {{ yield:index_content }} 9 | {{ /partial:page_builder/block }} 10 | -------------------------------------------------------------------------------- /resources/presets/faq/config.php: -------------------------------------------------------------------------------- 1 | 'faq', 5 | 'name' => 'FAQ', 6 | 'description' => 'A FAQ collection.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/blueprints/collections/faq/faq.yaml', 11 | 'output' => 'resources/blueprints/collections/faq/faq.yaml', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'content/collections/faq.yaml', 16 | 'output' => 'content/collections/faq.yaml', 17 | ], 18 | [ 19 | 'type' => 'copy', 20 | 'input' => 'resources/fieldsets/faq.yaml', 21 | 'output' => 'resources/fieldsets/faq.yaml', 22 | ], 23 | [ 24 | 'type' => 'copy', 25 | 'input' => 'resources/views/page_builder/_faq.antlers.html', 26 | 'output' => 'resources/views/page_builder/_faq.antlers.html', 27 | ], 28 | [ 29 | 'type' => 'update_page_builder', 30 | 'block' => [ 31 | 'name' => 'FAQ', 32 | 'instructions' => 'List frequently asked questions in an accordion.', 33 | 'icon' => 'alert-help-question', 34 | 'handle' => 'faq', 35 | ], 36 | ], 37 | [ 38 | 'type' => 'update_role', 39 | 'role' => 'editor', 40 | 'permissions' => ['view faq entries', 'edit faq entries', 'create faq entries', 'delete faq entries', 'publish faq entries', 'reorder faq entries', 'edit other authors faq entries', 'publish other authors faq entries', 'delete other authors faq entries'], 41 | ], 42 | [ 43 | 'type' => 'notify', 44 | 'content' => "\nAdd this to your `config/statamic/cp.php` widgets array:\n\n[\n\t'type' => 'collection',\n\t'collection' => 'faq',\n\t'width' => 50\n],\n", 45 | ], 46 | ], 47 | ]; 48 | -------------------------------------------------------------------------------- /resources/presets/faq/content/collections/faq.yaml: -------------------------------------------------------------------------------- 1 | title: FAQ 2 | template: default 3 | layout: layout 4 | revisions: false 5 | slugs: false 6 | sort_dir: asc 7 | date_behavior: 8 | past: public 9 | future: private 10 | preview_targets: 11 | - 12 | label: Entry 13 | url: '{permalink}' 14 | -------------------------------------------------------------------------------- /resources/presets/faq/resources/blueprints/collections/faq/faq.yaml: -------------------------------------------------------------------------------- 1 | title: FAQ 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | validate: 15 | - required 16 | instructions_position: above 17 | listable: true 18 | visibility: visible 19 | always_save: false 20 | input_type: text 21 | antlers: false 22 | - 23 | handle: text 24 | field: common.text_rich 25 | config: 26 | buttons: 27 | - h3 28 | - bold 29 | - italic 30 | - unorderedlist 31 | - orderedlist 32 | - removeformat 33 | - anchor 34 | fullscreen: false 35 | allow_source: false 36 | display: Text 37 | validate: 38 | - required 39 | -------------------------------------------------------------------------------- /resources/presets/faq/resources/fieldsets/faq.yaml: -------------------------------------------------------------------------------- 1 | title: FAQ 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: Title 9 | type: text 10 | icon: text 11 | listable: hidden 12 | instructions_position: above 13 | visibility: visible 14 | always_save: false 15 | - 16 | handle: text 17 | field: common.text_plain 18 | - 19 | handle: questions 20 | field: 21 | mode: default 22 | create: true 23 | collections: 24 | - faq 25 | display: Questions 26 | type: entries 27 | icon: entries 28 | listable: hidden 29 | instructions_position: above 30 | visibility: visible 31 | always_save: false 32 | validate: 33 | - required 34 | -------------------------------------------------------------------------------- /resources/presets/footer/config.php: -------------------------------------------------------------------------------- 1 | 'footer', 5 | 'name' => 'Footer', 6 | 'description' => 'A mega footer with multiple navigations.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/views/layout/_footer.antlers.html', 11 | 'output' => 'resources/views/layout/_footer.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'content/navigation/footer.yaml', 16 | 'output' => 'content/navigation/footer.yaml', 17 | ], 18 | [ 19 | 'type' => 'copy', 20 | 'input' => 'content/navigation/legal.yaml', 21 | 'output' => 'content/navigation/legal.yaml', 22 | ], 23 | [ 24 | 'type' => 'copy', 25 | 'input' => 'resources/blueprints/navigation/footer.yaml', 26 | 'output' => 'resources/blueprints/navigation/footer.yaml', 27 | ], 28 | [ 29 | 'type' => 'copy', 30 | 'input' => 'resources/blueprints/navigation/legal.yaml', 31 | 'output' => 'resources/blueprints/navigation/legal.yaml', 32 | ], 33 | [ 34 | 'type' => 'copy', 35 | 'input' => 'resources/blueprints/navigation/footer.yaml', 36 | 'output' => 'resources/blueprints/navigation/footer.yaml', 37 | ], 38 | [ 39 | 'type' => 'update_role', 40 | 'role' => 'editor', 41 | 'permissions' => ['view footer nav', 'edit footer nav', 'view legal nav', 'edit legal nav'], 42 | ], 43 | [ 44 | 'type' => 'notify', 45 | 'content' => "Add this to your `lang/locale/strings.php` file:\n\n// Footer\n'privacy_statement' => 'Privacy statement',\n'cookie_notice' => 'Cookie notice',", 46 | ], 47 | ], 48 | ]; 49 | -------------------------------------------------------------------------------- /resources/presets/footer/content/navigation/footer.yaml: -------------------------------------------------------------------------------- 1 | title: Footer 2 | collections: 3 | - pages 4 | max_depth: 2 5 | -------------------------------------------------------------------------------- /resources/presets/footer/content/navigation/legal.yaml: -------------------------------------------------------------------------------- 1 | title: Legal 2 | collections: 3 | - pages 4 | max_depth: 1 5 | -------------------------------------------------------------------------------- /resources/presets/footer/resources/blueprints/navigation/footer.yaml: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: General 7 | -------------------------------------------------------------------------------- /resources/presets/footer/resources/blueprints/navigation/legal.yaml: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: General 7 | -------------------------------------------------------------------------------- /resources/presets/hero/config.php: -------------------------------------------------------------------------------- 1 | 'hero', 5 | 'name' => 'Hero', 6 | 'description' => 'A hero layout component.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/fieldsets/hero.yaml', 11 | 'output' => 'resources/fieldsets/hero.yaml', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'resources/views/layout/_hero.antlers.html', 16 | 'output' => 'resources/views/layout/_hero.antlers.html', 17 | ], 18 | [ 19 | 'type' => 'notify', 20 | 'content' => "Add this to each collection blueprint you want to render a hero on:\n\nhero:\n\tsections:\n\t\t-\n\t\t\tdisplay: Hero\n\t\t\tfields:\n\t\t\t\t-\n\t\t\t\t\timport: hero\n\t\t\t\t\tprefix: hero_", 21 | ], 22 | [ 23 | 'type' => 'notify', 24 | 'content' => "Add this to your `resources/views/layout.antlers.html`:\n\n{{ partial:layout/hero :when=\"hero_render\" }}", 25 | ], 26 | ], 27 | ]; 28 | -------------------------------------------------------------------------------- /resources/presets/hero/resources/fieldsets/hero.yaml: -------------------------------------------------------------------------------- 1 | title: Hero 2 | fields: 3 | - 4 | handle: render 5 | field: 6 | display: 'Render hero' 7 | type: toggle 8 | always_save: false 9 | - 10 | handle: heading 11 | field: 12 | display: Heading 13 | type: text 14 | validate: 15 | - 'required_if:render,true' 16 | if: 17 | render: 'equals true' 18 | - 19 | handle: subheading 20 | field: 21 | display: 'Subheading' 22 | type: text 23 | if: 24 | render: 'equals true' 25 | - 26 | handle: buttons 27 | field: buttons.buttons 28 | config: 29 | max_rows: 2 30 | if: 31 | render: 'equals true' 32 | -------------------------------------------------------------------------------- /resources/presets/hero/resources/views/layout/_hero.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Hero 3 | @desc The hero optionally rendered on each page. 4 | #}} 5 | 6 | 7 |
8 |
9 |

10 | {{ hero_heading }} 11 |

12 | 13 | {{ if hero_subheading }} 14 |

{{ hero_subheading }}

15 | {{ /if }} 16 | 17 | {{ partial:components/buttons :buttons="hero_buttons" class="stack-space-8 justify-center" }} 18 |
19 |
20 | 21 | -------------------------------------------------------------------------------- /resources/presets/image_credits/config.php: -------------------------------------------------------------------------------- 1 | 'image_credits', 5 | 'name' => 'Image credits', 6 | 'description' => 'List images and their credits.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/views/page_builder/_image_credits.antlers.html', 11 | 'output' => 'resources/views/page_builder/_image_credits.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'resources/fieldsets/image_credits.yaml', 16 | 'output' => 'resources/fieldsets/image_credits.yaml', 17 | ], 18 | [ 19 | 'type' => 'copy', 20 | 'input' => 'resources/blueprints/assets/images.yaml', 21 | 'output' => 'resources/blueprints/assets/images.yaml', 22 | ], 23 | [ 24 | 'type' => 'update_page_builder', 25 | 'block' => [ 26 | 'name' => 'Image credits', 27 | 'instructions' => 'List images with their credits.', 28 | 'icon' => 'content-book-open', 29 | 'handle' => 'image_credits', 30 | ], 31 | ], 32 | ], 33 | ]; 34 | -------------------------------------------------------------------------------- /resources/presets/image_credits/resources/blueprints/assets/images.yaml: -------------------------------------------------------------------------------- 1 | title: Image 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: 'Alternative text' 8 | instructions: "Alt texts are important for users who depend on assistive technology." 9 | fields: 10 | - 11 | handle: alt 12 | field: 13 | display: 'Alt Text' 14 | type: textarea 15 | instructions: 'Description of the image' 16 | instructions_position: below 17 | focus: true 18 | - 19 | handle: exempt_from_alt 20 | field: 21 | inline_label: "This image doesn't need an alt text." 22 | default: false 23 | type: toggle 24 | display: Exempt 25 | icon: toggle 26 | listable: hidden 27 | instructions_position: below 28 | visibility: visible 29 | replicator_preview: true 30 | hide_display: false 31 | instructions: "When enabled, this image won't show up in the control panel dashboard as an image that misses alt text. Images without an alt text will automatically be hidden for screen readers." 32 | - 33 | display: 'Copyright' 34 | instructions: "Copyright information for use in the image credits block." 35 | fields: 36 | - 37 | handle: copyright 38 | field: 39 | mode: keyed 40 | keys: 41 | name: Name 42 | url: URL 43 | display: Copyright 44 | type: array 45 | icon: array 46 | instructions_position: above 47 | visibility: visible 48 | instructions: 'This image will be automatically added to the sites credits when this data is provided.' 49 | -------------------------------------------------------------------------------- /resources/presets/image_credits/resources/fieldsets/image_credits.yaml: -------------------------------------------------------------------------------- 1 | title: "Image credits" 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | type: text 8 | localizable: true 9 | listable: hidden 10 | display: Title 11 | - 12 | handle: text 13 | field: common.text_plain 14 | -------------------------------------------------------------------------------- /resources/presets/image_credits/resources/views/page_builder/_image_credits.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Image credits 3 | @desc The Image credits page builder block. 4 | @set page.page_builder.image_credits 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 | {{ if block:title || block:text }} 10 |
11 | {{ block:title ?= { partial:typography/h2 :content="block:title" } }} 12 | {{ block:text ?= { partial:typography/p :content="block:text" } }} 13 |
14 | {{ /if }} 15 | 16 |
17 | {{ assets container="images" as="images" }} 18 | {{ images where (copyright.name !== null) orderby (copyright.name 'asc') }} 19 |
20 |
21 | {{ partial:statamic-peak-tools::components/picture :image="url" sizes="(min-width: 1280px) 1280px, (min-width: 768px) 20vw, 50vw" aspect_ratio="1/1" cover="true" }} 22 |
23 |
24 | {{ if copyright:url }} 25 | {{ partial:components/button :label="copyright:name" button_type="inline" link_type="url" :url="copyright:url" target_blank="true" }} 26 | {{ else }} 27 | {{ copyright:name }} 28 | {{ /if }} 29 |
30 |
31 | {{ /images }} 32 | {{ /assets }} 33 |
34 | {{ /partial:page_builder/block }} 35 | 36 | -------------------------------------------------------------------------------- /resources/presets/language_picker/config.php: -------------------------------------------------------------------------------- 1 | 'language_picker', 5 | 'name' => 'Language picker', 6 | 'description' => 'A multisite language picker.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/views/navigation/_language_picker.antlers.html', 11 | 'output' => 'resources/views/navigation/_language_picker.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'notify', 15 | 'content' => 'Add `{{ partial:navigation/language_picker }}` as the last list item in the main ul in `resources/views/navigation/_main.antlers.html`.', 16 | ], 17 | [ 18 | 'type' => 'notify', 19 | 'content' => "Add this to your `lang/locale/strings.php` file:\n\n// Language picker\n'language_open' => 'Open language picker. Current language is :current_language',\n'language_close' => 'Close language picker',", 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /resources/presets/language_picker/resources/views/navigation/_language_picker.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Language picker 3 | @desc A language picker when you use multisite. To enable this do the following: 4 | 1. Add `{{ partial:navigation/language_picker }}` as the last list item in the main ul in `resources/views/navigation/_main.antlers.html`. 5 | #}} 6 | 7 | 8 |
  • 15 | 24 | {{ site:short_locale }} 25 | 31 | 32 | 51 |
  • 52 | 53 | -------------------------------------------------------------------------------- /resources/presets/mega_menu/config.php: -------------------------------------------------------------------------------- 1 | 'mega_menu', 5 | 'name' => 'Mega Menu', 6 | 'description' => 'A three level deep mega dropdown menu.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'notify', 10 | 'content' => 'This preset assumes you still have a navigation called `main`, separated into the two default Peak templates: mobile and desktop.', 11 | ], 12 | [ 13 | 'type' => 'copy', 14 | 'input' => 'content/navigation/main.yaml', 15 | 'output' => 'content/navigation/main.yaml', 16 | ], 17 | [ 18 | 'type' => 'copy', 19 | 'input' => 'resources/blueprints/navigation/main.yaml', 20 | 'output' => 'resources/blueprints/navigation/main.yaml', 21 | ], 22 | [ 23 | 'type' => 'copy', 24 | 'input' => 'resources/views/navigation/_main_desktop.antlers.html', 25 | 'output' => 'resources/views/navigation/_main_desktop.antlers.html', 26 | ], 27 | [ 28 | 'type' => 'copy', 29 | 'input' => 'resources/views/navigation/_main_mobile.antlers.html', 30 | 'output' => 'resources/views/navigation/_main_mobile.antlers.html', 31 | ], 32 | [ 33 | 'type' => 'notify', 34 | 'content' => 'Make sure to add items, section headers and pages with descriptions to your navigation first.', 35 | ], 36 | ], 37 | ]; 38 | -------------------------------------------------------------------------------- /resources/presets/mega_menu/content/navigation/main.yaml: -------------------------------------------------------------------------------- 1 | title: Main 2 | collections: 3 | - pages 4 | max_depth: 3 5 | -------------------------------------------------------------------------------- /resources/presets/mega_menu/resources/blueprints/navigation/main.yaml: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: General 7 | fields: 8 | - 9 | handle: description 10 | field: 11 | antlers: true 12 | type: textarea 13 | display: Description 14 | character_limit: '75' 15 | validate: 16 | - 'max:75' 17 | if: 18 | depth: '> 2' 19 | - 20 | handle: html_depth_1 21 | field: 22 | html: '

    Items on this depth will either be rendered as links or toggle''s for a mega-menu style dropdown.

    ' 23 | type: html 24 | display: 'Depth 1' 25 | if: 26 | depth: 'equals 1' 27 | - 28 | handle: html_depth_2 29 | field: 30 | html: '

    Items on this depth will be rendered as a section header and not as a link.

    ' 31 | type: html 32 | display: 'Depth 2' 33 | if: 34 | depth: 'equals 2' 35 | - 36 | handle: html_depth_3 37 | field: 38 | html: '

    Items on this depth will be rendered as actual links with a description.

    ' 39 | type: html 40 | display: 'Depth 3' 41 | if: 42 | depth: 'equals 3' 43 | -------------------------------------------------------------------------------- /resources/presets/modal/config.php: -------------------------------------------------------------------------------- 1 | 'modal', 5 | 'name' => 'Modal', 6 | 'description' => 'A re-usable modal.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/views/components/_modal.antlers.html', 11 | 'output' => 'resources/views/components/_modal.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'resources/views/components/_invoke_modal.antlers.html', 16 | 'output' => 'resources/views/components/_invoke_modal.antlers.html', 17 | ], 18 | [ 19 | 'type' => 'copy', 20 | 'input' => 'resources/fieldsets/invoke_modal.yaml', 21 | 'output' => 'resources/fieldsets/invoke_modal.yaml', 22 | ], 23 | [ 24 | 'type' => 'update_article_sets', 25 | 'set' => [ 26 | 'name' => 'Invoke modal', 27 | 'icon' => 'alert-warning-exclamation-mark', 28 | 'instructions' => 'Invokes a modal.', 29 | 'handle' => 'invoke_modal', 30 | ], 31 | ], 32 | [ 33 | 'type' => 'notify', 34 | 'content' => 'Make sure to `{{ yield:modal }}` in your layout file before closing the ``.', 35 | ], 36 | ], 37 | ]; 38 | -------------------------------------------------------------------------------- /resources/presets/modal/resources/fieldsets/invoke_modal.yaml: -------------------------------------------------------------------------------- 1 | title: 'Invoke modal' 2 | fields: 3 | - 4 | handle: label_open 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: 'Label open' 9 | type: text 10 | icon: text 11 | localizable: true 12 | width: 50 13 | listable: hidden 14 | instructions_position: above 15 | visibility: visible 16 | always_save: false 17 | validate: 18 | - required 19 | - 20 | handle: label_close 21 | field: 22 | input_type: text 23 | antlers: false 24 | display: 'Label close' 25 | type: text 26 | icon: text 27 | localizable: true 28 | width: 50 29 | listable: hidden 30 | instructions_position: above 31 | visibility: visible 32 | always_save: false 33 | validate: 34 | - required 35 | - 36 | handle: label_aria 37 | field: 38 | input_type: text 39 | antlers: false 40 | display: 'Label aria' 41 | type: text 42 | icon: text 43 | localizable: true 44 | listable: hidden 45 | instructions_position: above 46 | visibility: visible 47 | always_save: false 48 | validate: 49 | - required 50 | - 51 | handle: text 52 | field: common.text_rich 53 | config: 54 | buttons: 55 | - h2 56 | - h3 57 | - bold 58 | - italic 59 | - unorderedlist 60 | - orderedlist 61 | - removeformat 62 | - anchor 63 | fullscreen: false 64 | allow_source: false 65 | display: Text 66 | validate: 67 | - required 68 | -------------------------------------------------------------------------------- /resources/presets/modal/resources/views/components/_invoke_modal.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Invoke modal 3 | @desc The Invoke modal component. 4 | @set page.article.invoke_modal 5 | #}} 6 | 7 | 8 |
    9 | {{ partial:components/modal :label_open="label_open" :label_close="label_close" :label_aria="label_aria" }} 10 | {{ slot:content }} 11 | {{ partial:typography/prose }} 12 | {{ text }} 13 | {{ /partial:typography/prose }} 14 | {{ /slot:content }} 15 | {{ /partial:components/modal }} 16 |
    17 | 18 | -------------------------------------------------------------------------------- /resources/presets/news/content/collections/news.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | route: '/{mount}/{slug}' 3 | layout: layout 4 | template: {{ handle }}/show 5 | revisions: false 6 | date: true 7 | sort_dir: desc 8 | date_behavior: 9 | past: public 10 | future: private 11 | mount: d11a5ec8-9915-4528-8cfe-e282362ef9ee 12 | preview_targets: 13 | - 14 | label: Entry 15 | url: '{permalink}' 16 | refresh: false 17 | -------------------------------------------------------------------------------- /resources/presets/news/content/collections/pages/news.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: d11a5ec8-9915-4528-8cfe-e282362ef9ee 3 | blueprint: page 4 | title: {{ name }} 5 | template: {{ handle }}/index 6 | page_builder: 7 | - 8 | type: index_content 9 | enabled: true 10 | --- 11 | -------------------------------------------------------------------------------- /resources/presets/news/resources/fieldsets/index_content.yaml: -------------------------------------------------------------------------------- 1 | title: 'Index content' 2 | fields: [ ] 3 | -------------------------------------------------------------------------------- /resources/presets/news/resources/fieldsets/news.yaml: -------------------------------------------------------------------------------- 1 | title: '{{ name }}' 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | antlers: false 8 | display: Title 9 | type: text 10 | icon: text 11 | listable: hidden 12 | instructions_position: above 13 | visibility: visible 14 | always_save: false 15 | -------------------------------------------------------------------------------- /resources/presets/news/resources/views/components/_news_item.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} item 3 | @desc A {{ name }} item component. 4 | @param class Add optional CSS classes. 5 | #}} 6 | 7 | 8 |
    9 |
    10 | {{ partial:statamic-peak-tools::components/picture :image="image" sizes="(min-width: 1280px) 430px, (min-width: 768px) 30vw, 90vw" aspect_ratio="3/2" lazy="true" cover="true" class="aspect-[3/2]" }} 11 |
    12 | 13 |
    14 | {{ partial:typography/time :content="date" class="text-sm" }} 15 | 16 | 17 | {{ partial:typography/h3 :content="title" class="underline decoration-primary decoration-2 underline-offset-2 group-hover:text-primary motion-safe:transition-colors" }} 18 | 19 | 20 | {{ partial:typography/p :content="teaser" }} 21 |
    22 |
    23 | 24 | -------------------------------------------------------------------------------- /resources/presets/news/resources/views/feed/feed.antlers.xml: -------------------------------------------------------------------------------- 1 | {{ xml_header }} 2 | 3 | 4 | {{ get_content from="{mount_url:{{ handle }}}" }} 5 | {{ seo:site_name ? seo:site_name : config:app:name }} {{ seo:title_separator ? seo:title_separator : " | " }} {{ title }} 6 | {{ permalink }} 7 | 8 | {{ if seo_description }}{{ seo_description | strip_tags | entities | trim }}{{ elseif seo:collection_defaults }}{{ partial:statamic-peak-seo::snippets/fallback_description }}{{ /if }} 9 | {{ /get_content }} 10 | {{ site:locale | replace('_', '-') }} 11 | {{ now | format('r') }} 12 | {{ collection:{{ handle }} sort="date:desc" limit="50" }} 13 | 14 | {{ title }} 15 | {{ permalink }} 16 | {{ permalink }} 17 |

    {{ teaser | nl2br }}

    {{ trans:strings.{{ handle }}_read_more }}]]>
    18 | {{ date | format('r') }} 19 |
    20 | {{ /collection:{{ handle }} }} 21 |
    22 |
    23 | -------------------------------------------------------------------------------- /resources/presets/news/resources/views/news/index.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} index 3 | @desc The {{ name }} index template. 4 | #}} 5 | 6 | 7 |
    8 | {{ page_builder scope="block" }} 9 | {{ partial src="page_builder/{type}" }} 10 | {{ /page_builder }} 11 |
    12 | 13 | 14 | {{ section:index_content }} 15 | 16 |
    17 | {{ partial:typography/h1 as="h2" :content="title" class="md:col-span-12" }} 18 | {{ collection:{{ handle }} sort="date:desc" paginate="true" limit="12" as="items" }} 19 | {{ unless no_results }} 20 | {{ items }} 21 | {{ partial:components/{{ handle }}_item class="md:col-span-4" }} 22 | {{ /items }} 23 | {{ else }} 24 |
    25 | {{ trans:strings.no_results }} 26 |
    27 | {{ /unless }} 28 | 29 | {{ partial:statamic-peak-tools::components/pagination class="md:col-span-12" }} 30 | {{ /collection:{{ handle }} }} 31 |
    32 | 33 | {{ /section:index_content }} 34 | -------------------------------------------------------------------------------- /resources/presets/news/resources/views/page_builder/_index_content.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Index content 3 | @desc The Index content page builder block. 4 | @set page.page_builder.index_content 5 | #}} 6 | 7 | {{ partial:page_builder/block }} 8 | {{ yield:index_content }} 9 | {{ /partial:page_builder/block }} 10 | -------------------------------------------------------------------------------- /resources/presets/news/resources/views/page_builder/_news.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} 3 | @desc The {{ name }} page builder block. 4 | @set page.page_builder.{{ handle }} 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
    10 | {{ title ?= { partial:typography/h1 as="h2" :content="title" class="md:col-span-12" } }} 11 | 12 | {{ collection:{{ handle }} sort="date:desc" limit="3" as="items" }} 13 | {{ unless no_results }} 14 | {{ items }} 15 | {{ partial:components/{{ handle }}_item class="md:col-span-4" }} 16 | {{ /items }} 17 | {{ else }} 18 |
    19 | {{ trans:strings.no_results }} 20 |
    21 | {{ /if }} 22 | {{ /collection:{{ handle }} }} 23 | 24 | 27 |
    28 | {{ /partial:page_builder/block }} 29 | 30 | -------------------------------------------------------------------------------- /resources/presets/password_protection/content/collections/pages/login.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: 2f6436c7-36cd-4863-9288-8ffa28528d7a 3 | blueprint: page 4 | title: Login 5 | seo_noindex: true 6 | seo_nofollow: false 7 | seo_canonical_type: entry 8 | sitemap_change_frequency: weekly 9 | sitemap_priority: 0.5 10 | protect_entry: false 11 | page_builder: 12 | - 13 | id: m6ulso0w 14 | type: login 15 | enabled: true 16 | --- 17 | -------------------------------------------------------------------------------- /resources/presets/password_protection/resources/fieldsets/login.yaml: -------------------------------------------------------------------------------- 1 | title: Login 2 | fields: [] 3 | -------------------------------------------------------------------------------- /resources/presets/password_protection/resources/fieldsets/protect.yaml: -------------------------------------------------------------------------------- 1 | title: Login 2 | fields: 3 | - 4 | handle: protect_entry 5 | field: 6 | type: toggle 7 | display: Protect 8 | instructions: 'Optionally protect this page with a password.' 9 | instructions_position: below 10 | listable: true 11 | - 12 | handle: protect 13 | field: 14 | default: password 15 | type: hidden 16 | display: Protect 17 | if: 18 | protect_entry: 'equals true' 19 | - 20 | handle: password 21 | field: 22 | type: text 23 | display: Password 24 | instructions: 'Protect this page with password.' 25 | instructions_position: below 26 | validate: 27 | - sometimes 28 | - required 29 | if: 30 | protect_entry: 'equals true' 31 | -------------------------------------------------------------------------------- /resources/presets/password_protection/resources/views/page_builder/_login.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Login 3 | @desc The Login page builder block. 4 | @set page.page_builder.login 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
    10 | {{ protect:password_form }} 11 | {{ if no_token }} 12 | {{ 404 }} 13 | {{ else }} 14 |
    15 |
    16 | 19 | 20 | 21 | 22 | {{ errors:password }} 23 | {{ trans:strings.password_invalid }} 24 | {{ /errors:password }} 25 |
    26 | 27 | {{ partial:components/button as="button" button_type="button" class="self-end" label="{ trans:strings.password_login }" }} 28 |
    29 | {{ /if }} 30 | {{ /protect:password_form }} 31 |
    32 | {{ /partial:page_builder/block }} 33 | 34 | -------------------------------------------------------------------------------- /resources/presets/pricing/app/Scopes/Multiselect.php: -------------------------------------------------------------------------------- 1 | get('query_scope').':'; 20 | $filters = collect($values)->filter(function ($value, $key) use ($prefix) { 21 | return Str::startsWith($key, $prefix); 22 | })->mapWithKeys(function ($value, $key) use ($prefix) { 23 | $newKey = Str::after($key, $prefix); 24 | 25 | return [$newKey => explode('|', $value)]; 26 | })->all(); 27 | 28 | $field = array_key_first($filters); 29 | 30 | return $query->whereJsonContains($field, $filters[$field]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/presets/pricing/content/collections/features.yaml: -------------------------------------------------------------------------------- 1 | title: Features 2 | template: default 3 | layout: layout 4 | revisions: false 5 | slugs: false 6 | sort_dir: asc 7 | date_behavior: 8 | past: public 9 | future: private 10 | preview_targets: 11 | - 12 | label: Entry 13 | url: '{permalink}' 14 | refresh: true 15 | structure: 16 | root: false 17 | max_depth: 1 18 | -------------------------------------------------------------------------------- /resources/presets/pricing/content/collections/tiers.yaml: -------------------------------------------------------------------------------- 1 | title: 'Tiers' 2 | template: default 3 | layout: layout 4 | revisions: false 5 | slugs: false 6 | sort_dir: asc 7 | date_behavior: 8 | past: public 9 | future: private 10 | preview_targets: 11 | - 12 | label: Entry 13 | url: '{permalink}' 14 | refresh: true 15 | structure: 16 | root: false 17 | max_depth: 1 18 | -------------------------------------------------------------------------------- /resources/presets/pricing/content/taxonomies/groups.yaml: -------------------------------------------------------------------------------- 1 | title: Groups 2 | -------------------------------------------------------------------------------- /resources/presets/pricing/resources/blueprints/collections/features/feature.yaml: -------------------------------------------------------------------------------- 1 | title: Feature 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: Feature 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | handle: explanation 22 | field: common.text_basic 23 | config: 24 | display: Explanation 25 | sidebar: 26 | display: Sidebar 27 | sections: 28 | - 29 | display: Meta 30 | fields: 31 | - 32 | handle: group 33 | field: 34 | max_items: 1 35 | mode: default 36 | create: true 37 | taxonomies: 38 | - groups 39 | type: terms 40 | display: Group 41 | listable: true 42 | instructions_position: above 43 | visibility: visible 44 | replicator_preview: true 45 | hide_display: false 46 | validate: 47 | - required 48 | - 49 | handle: list_as 50 | field: 51 | input_type: text 52 | antlers: false 53 | type: text 54 | display: 'List as' 55 | instructions: "If you don't want this feature listed as a checkmark icon, you can specify custom text here." 56 | listable: true 57 | instructions_position: below 58 | visibility: visible 59 | replicator_preview: true 60 | hide_display: false 61 | - 62 | display: Tiers 63 | fields: 64 | - 65 | handle: tiers 66 | field: 67 | mode: default 68 | create: true 69 | collections: 70 | - tiers 71 | type: entries 72 | display: Tiers 73 | listable: true 74 | instructions_position: above 75 | visibility: visible 76 | replicator_preview: true 77 | hide_display: false 78 | -------------------------------------------------------------------------------- /resources/presets/pricing/resources/blueprints/taxonomies/groups/group.yaml: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: Group 7 | fields: 8 | - 9 | handle: slug 10 | field: 11 | type: slug 12 | required: true 13 | validate: 14 | - required 15 | - 'max:200' 16 | display: Slug 17 | instructions_position: above 18 | listable: hidden 19 | visibility: hidden 20 | replicator_preview: true 21 | from: title 22 | generate: true 23 | show_regenerate: false 24 | hide_display: false 25 | - 26 | handle: title 27 | field: 28 | type: text 29 | required: true 30 | validate: 31 | - required 32 | title: Group 33 | -------------------------------------------------------------------------------- /resources/presets/pricing/resources/fieldsets/features.yaml: -------------------------------------------------------------------------------- 1 | title: Features 2 | fields: 3 | - 4 | handle: tiers 5 | field: 6 | mode: default 7 | create: true 8 | collections: 9 | - tiers 10 | type: entries 11 | display: Tiers 12 | listable: hidden 13 | instructions_position: above 14 | visibility: visible 15 | replicator_preview: true 16 | hide_display: false 17 | validate: 18 | - required 19 | -------------------------------------------------------------------------------- /resources/presets/pricing/resources/fieldsets/tiers.yaml: -------------------------------------------------------------------------------- 1 | title: Tiers 2 | fields: 3 | - 4 | handle: tiers 5 | field: 6 | mode: default 7 | create: true 8 | collections: 9 | - tiers 10 | type: entries 11 | display: Tiers 12 | listable: hidden 13 | instructions_position: above 14 | visibility: visible 15 | replicator_preview: true 16 | hide_display: false 17 | validate: 18 | - required 19 | -------------------------------------------------------------------------------- /resources/presets/pricing/resources/svg/check.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/presets/pricing/resources/svg/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/presets/pricing/resources/views/page_builder/_tiers.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Tiers 3 | @desc The Tiers page builder block. 4 | @set page.page_builder.tiers 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
    10 | {{ block:tiers }} 11 |
    18 |

    19 | {{ title }} 20 |

    21 | 22 |
    23 | {{ if pricing === 'fixed' }} 24 | €{{ price ?? custom }} 25 | {{ else }} 26 | {{ custom }} 27 | {{ /if }} 28 |
    29 | 30 | {{ detail }} 31 | 32 | {{ partial:components/buttons }} 33 | 34 | {{ if benefits_title }} 35 |

    {{ benefits_title }}

    36 | {{ /if }} 37 | 38 | {{ partial:typography/prose :if="benefits" class="stack-space-2 prose-sm" }} 39 | {{ if benefits }} 40 | 45 | {{ /if }} 46 | {{ /partial:typography/prose }} 47 |
    48 | {{ /block:tiers }} 49 |
    50 | {{ /partial:page_builder/block }} 51 | 52 | -------------------------------------------------------------------------------- /resources/presets/search/config.php: -------------------------------------------------------------------------------- 1 | 'search', 5 | 'name' => 'Search', 6 | 'description' => 'Search form and search results.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/views/search.antlers.html', 11 | 'output' => 'resources/views/search.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'resources/views/components/_search_form.antlers.html', 16 | 'output' => 'resources/views/components/_search_form.antlers.html', 17 | ], 18 | [ 19 | 'type' => 'notify', 20 | 'content' => "Add this to your `lang/locale/strings.php` file:\n\n// Search\n'search' => 'Search',\n'search_close' => 'Close search',\n'search_open' => 'Open search',\n'search_no_results' => 'No results found',\n'search_results_for' => 'Results for',", 21 | ], 22 | [ 23 | 'type' => 'notify', 24 | 'content' => 'Add `{{ partial:components/search_form }}` as the last list item in the main ul in `resources/views/navigation/_main.antlers.html`.', 25 | ], 26 | [ 27 | 'type' => 'notify', 28 | 'content' => "Add the following route to `routes/web.php`:\n\n// The Search route to display search results with `views/search.antlers.html`.\nRoute::statamic('/search', 'search');", 29 | ], 30 | [ 31 | 'type' => 'notify', 32 | 'content' => 'Add fields you want indexed to the index in config/statamic/search.php. The page_builder field is added by default.', 33 | ], 34 | [ 35 | 'type' => 'notify', 36 | 'content' => 'Update the search index by running php please search:update --all.', 37 | ], 38 | [ 39 | 'type' => 'notify', 40 | 'content' => 'Make sure you add the update command to your deployment script.', 41 | ], 42 | ], 43 | ]; 44 | -------------------------------------------------------------------------------- /resources/presets/search/resources/views/components/_search_form.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Search form 3 | @desc The search form component for search functionality. To enable this do the following: 4 | 1. Add `{{ partial:components/search_form }}` as the last list item in the main ul in `resources/views/navigation/_main.antlers.html`. 5 | 2. Uncomment the search results route in routes/web.php. 6 | 3. Add fields you want indexed to the index in config/statamic/search.php. The page_builder field is added by default. 7 | 4. Update the search index by running php please search:update --all. 8 | 5. Make sure you add the update command to your deployment script. 9 | #}} 10 | 11 | 12 |
  • 21 | 31 | 32 | 56 |
  • 57 | 58 | -------------------------------------------------------------------------------- /resources/presets/search/resources/views/search.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Search 3 | @desc The search template showing search results, if you enable the search form partial in `views/navigation/_main.antlers.html` and the route in `routes/web.php`. 4 | #}} 5 | 6 | {{# Yield a title to the SEO partial. #}} 7 | {{ section:seo_title }} 8 | {{ trans:strings.search }} 9 | {{ /section:seo_title }} 10 | 11 | 12 |
    13 |
    14 |
    15 | {{ partial:typography/h1 class="mb-2" content="{trans:strings.search_results_for} “{get:q}”" }} 16 |
    17 | 18 | 25 | 26 | {{ search:results }} 27 | {{ if no_results }} 28 |
    29 | {{ partial:typography/p content="{trans:strings.search_no_results}" }} 30 |
    31 | {{ else }} 32 | 42 | {{ /if }} 43 | {{ /search:results }} 44 |
    45 |
    46 | 47 | -------------------------------------------------------------------------------- /resources/presets/secure_downloads/app/Http/Controllers/DownloadController.php: -------------------------------------------------------------------------------- 1 | hasValidSignature()) { 15 | abort(403); 16 | } 17 | 18 | return response()->download(Path::assemble(AssetContainer::find($request->input('container'))->diskPath(), $request->input('file'))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/presets/secure_downloads/app/Tags/Download.php: -------------------------------------------------------------------------------- 1 | addMinutes(5), 15 | [ 16 | 'file' => $this->params->get('file'), 17 | 'container' => $this->params->get('container') 18 | ] 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/presets/secure_downloads/content/assets/downloads.yaml: -------------------------------------------------------------------------------- 1 | title: Downloads 2 | disk: downloads 3 | allow_uploads: true 4 | allow_downloading: true 5 | allow_renaming: true 6 | allow_moving: true 7 | create_folders: true 8 | warm_presets: false 9 | -------------------------------------------------------------------------------- /resources/presets/secure_downloads/resources/blueprints/assets/downloads.yaml: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: Download 7 | fields: 8 | - 9 | handle: title 10 | field: 11 | input_type: text 12 | antlers: false 13 | type: text 14 | display: Title 15 | icon: text 16 | localizable: false 17 | listable: hidden 18 | instructions_position: above 19 | visibility: visible 20 | hide_display: false 21 | - 22 | handle: description 23 | field: common.text_basic 24 | config: 25 | display: Description 26 | -------------------------------------------------------------------------------- /resources/presets/secure_downloads/resources/fieldsets/downloads.yaml: -------------------------------------------------------------------------------- 1 | title: Downloads 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | display: Title 7 | type: text 8 | always_save: false 9 | - 10 | handle: downloads 11 | field: 12 | min_files: 1 13 | container: downloads 14 | show_set_alt: false 15 | type: assets 16 | display: Downloads 17 | validate: 18 | - required 19 | -------------------------------------------------------------------------------- /resources/presets/secure_downloads/resources/views/page_builder/_downloads.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Downloads 3 | @desc The Downloads page builder block. 4 | @set page.page_builder.downloads 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 |
    10 | {{ block:title ?= { partial:typography/h1 as="h2" :content="block:title" class="md:col-span-12" } }} 11 | 12 | {{ block:downloads }} 13 |
    14 |
    15 | {{ partial:typography/h3 :content="title" }} 16 | 17 | 18 | {{ extension }} - {{ size }} 19 | 20 | 21 | {{ partial:typography/prose :when="description" class="prose-sm" as="div" }} 22 | {{ description }} 23 | {{ /partial:typography/prose }} 24 |
    25 | 26 | {{ nocache }} 27 | {{ trans:strings.download }} 28 | {{ /nocache }} 29 |
    30 | {{ /block:downloads }} 31 |
    32 | {{ /partial:page_builder/block }} 33 | 34 | -------------------------------------------------------------------------------- /resources/presets/team_members/config.php: -------------------------------------------------------------------------------- 1 | 'team_members', 5 | 'name' => 'Team members', 6 | 'singular_name' => 'Member', 7 | 'description' => 'A renamable team member collection.', 8 | 'operations' => [ 9 | [ 10 | 'type' => 'rename', 11 | ], 12 | [ 13 | 'type' => 'copy', 14 | 'input' => 'resources/blueprints/collections/team_members/team_members.yaml', 15 | 'output' => 'resources/blueprints/collections/{{ handle }}/{{ handle }}.yaml', 16 | ], 17 | [ 18 | 'type' => 'copy', 19 | 'input' => 'content/collections/team_members.yaml', 20 | 'output' => 'content/collections/{{ handle }}.yaml', 21 | ], 22 | [ 23 | 'type' => 'copy', 24 | 'input' => 'resources/views/page_builder/_team_members.antlers.html', 25 | 'output' => 'resources/views/page_builder/_{{ handle }}.antlers.html', 26 | ], 27 | [ 28 | 'type' => 'copy', 29 | 'input' => 'resources/fieldsets/team_members.yaml', 30 | 'output' => 'resources/fieldsets/{{ handle }}.yaml', 31 | ], 32 | [ 33 | 'type' => 'update_page_builder', 34 | 'block' => [ 35 | 'name' => '{{ name }}', 36 | 'instructions' => 'List {{ name }}.', 37 | 'icon' => 'user-multiple', 38 | 'handle' => '{{ handle }}', 39 | ], 40 | ], 41 | [ 42 | 'type' => 'update_role', 43 | 'role' => 'editor', 44 | 'permissions' => ['view {{ handle }} entries', 'edit {{ handle }} entries', 'create {{ handle }} entries', 'delete {{ handle }} entries', 'publish {{ handle }} entries', 'reorder {{ handle }} entries', 'edit other authors {{ handle }} entries', 'publish other authors {{ handle }} entries', 'delete other authors {{ handle }} entries'], 45 | ], 46 | [ 47 | 'type' => 'notify', 48 | 'content' => "Add this to your `config/statamic/cp.php` widgets array:\n\n[\n\t'type' => 'collection',\n\t'collection' => '{{ handle }}',\n\t'width' => 50\n],", 49 | ], 50 | ], 51 | ]; 52 | -------------------------------------------------------------------------------- /resources/presets/team_members/content/collections/team_members.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | template: default 3 | layout: layout 4 | revisions: false 5 | title_format: '{first_name} {last_name}' 6 | slugs: false 7 | sort_dir: asc 8 | structure: 9 | root: false 10 | max_depth: 1 11 | -------------------------------------------------------------------------------- /resources/presets/team_members/resources/blueprints/collections/team_members/team_members.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: first_name 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: First name 18 | width: 50 19 | validate: 20 | - required 21 | - 22 | handle: last_name 23 | field: 24 | type: text 25 | required: true 26 | input_type: text 27 | localizable: true 28 | listable: true 29 | display: Last name 30 | width: 50 31 | validate: 32 | - required 33 | - 34 | handle: function 35 | field: 36 | type: text 37 | required: true 38 | input_type: text 39 | localizable: true 40 | listable: true 41 | display: Function 42 | validate: 43 | - required 44 | sidebar: 45 | display: Sidebar 46 | sections: 47 | - 48 | display: Meta 49 | fields: 50 | - 51 | handle: image 52 | field: common.image 53 | config: 54 | listable: true 55 | instructions_position: below 56 | validate: 57 | - required 58 | -------------------------------------------------------------------------------- /resources/presets/team_members/resources/fieldsets/team_members.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | fields: 3 | - 4 | handle: title 5 | field: 6 | input_type: text 7 | type: text 8 | localizable: true 9 | listable: hidden 10 | display: Title 11 | - 12 | handle: text 13 | field: common.text_plain 14 | - 15 | handle: {{ handle }} 16 | field: 17 | mode: default 18 | create: true 19 | collections: 20 | - {{ handle }} 21 | display: {{ name }} 22 | type: entries 23 | icon: entries 24 | listable: hidden 25 | instructions_position: below 26 | instructions: 'Select entries or leave empty to show all.' 27 | visibility: visible 28 | always_save: false 29 | -------------------------------------------------------------------------------- /resources/presets/team_members/resources/views/page_builder/_team_members.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} 3 | @desc The {{ name }} page builder block. 4 | @set page.page_builder.{{ handle }} 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block class="gap-y-8" }} 9 | {{ if block:title or block:text }} 10 |
    11 | {{ block:title ?= { partial:typography/h2 :content="block:title" } }} 12 | {{ block:text ?= { partial:typography/p :content="block:text" } }} 13 |
    14 | {{ /if }} 15 | 16 |
    17 | {{ 18 | {{ handle }} = block:{{ handle }} 19 | ? block:{{ handle }} 20 | : { collection:{{ handle }} sort="order" } 21 | }} 22 | 23 | {{ {{ handle }} scope="{{ singular_handle }}" }} 24 |
    25 | {{ partial 26 | src="statamic-peak-tools::components/picture" 27 | :image="{{ singular_handle }}:image:url" 28 | aspect_ratio="4/3" 29 | sizes="(min-width: 1280px) 430px, (min-width: 768px) 33vw, 90vw" 30 | cover="true" 31 | lazy="true" 32 | }} 33 |
    34 | {{ {{ singular_handle }}:function }} 35 | {{ {{ singular_handle }}:title }} 36 |
    37 |
    38 | {{ /{{ handle }} }} 39 |
    40 | {{ /partial:page_builder/block }} 41 | 42 | -------------------------------------------------------------------------------- /resources/presets/testimonials/config.php: -------------------------------------------------------------------------------- 1 | 'testimonials', 5 | 'name' => 'Testimonials', 6 | 'singular_name' => 'Testimonial', 7 | 'description' => 'A renamable testimonial collection.', 8 | 'operations' => [ 9 | [ 10 | 'type' => 'rename', 11 | ], 12 | [ 13 | 'type' => 'copy', 14 | 'input' => 'content/collections/testimonials.yaml', 15 | 'output' => 'content/collections/{{ handle }}.yaml', 16 | ], 17 | [ 18 | 'type' => 'copy', 19 | 'input' => 'resources/blueprints/collections/testimonials/testimonials.yaml', 20 | 'output' => 'resources/blueprints/collections/{{ handle }}/{{ handle }}.yaml', 21 | ], 22 | [ 23 | 'type' => 'copy', 24 | 'input' => 'resources/fieldsets/testimonials.yaml', 25 | 'output' => 'resources/fieldsets/{{ handle }}.yaml', 26 | ], 27 | [ 28 | 'type' => 'copy', 29 | 'input' => 'resources/views/page_builder/_testimonials.antlers.html', 30 | 'output' => 'resources/views/page_builder/_{{ handle }}.antlers.html', 31 | ], 32 | [ 33 | 'type' => 'update_page_builder', 34 | 'block' => [ 35 | 'name' => '{{ name }}', 36 | 'instructions' => 'List a selection or random {{ name }}.', 37 | 'icon' => 'text-formatting-quotation', 38 | 'handle' => '{{ handle }}', 39 | ], 40 | ], 41 | [ 42 | 'type' => 'update_role', 43 | 'role' => 'editor', 44 | 'permissions' => ['view {{ handle }} entries', 'edit {{ handle }} entries', 'create {{ handle }} entries', 'delete {{ handle }} entries', 'publish {{ handle }} entries', 'reorder {{ handle }} entries', 'edit other authors {{ handle }} entries', 'publish other authors {{ handle }} entries', 'delete other authors {{ handle }} entries'], 45 | ], 46 | [ 47 | 'type' => 'notify', 48 | 'content' => "Add this to your `config/statamic/cp.php` widgets array:\n\n[\n\t'type' => 'collection',\n\t'collection' => '{{ handle }}',\n\t'width' => 50\n],", 49 | ], 50 | ], 51 | ]; 52 | -------------------------------------------------------------------------------- /resources/presets/testimonials/content/collections/testimonials.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | template: default 3 | layout: layout 4 | revisions: false 5 | title_format: '{author}' 6 | slugs: false 7 | sort_dir: asc 8 | preview_targets: 9 | - 10 | label: Entry 11 | url: '{permalink}' 12 | refresh: true 13 | -------------------------------------------------------------------------------- /resources/presets/testimonials/resources/blueprints/collections/testimonials/testimonials.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: hidden 13 | required: false 14 | display: Title 15 | - 16 | handle: testimonial 17 | field: 18 | type: textarea 19 | display: Testimonial 20 | validate: 21 | - required 22 | - 23 | handle: author 24 | field: 25 | type: text 26 | display: Author 27 | width: 33 28 | validate: 29 | - required 30 | - 31 | handle: function 32 | field: 33 | type: text 34 | display: Function 35 | width: 33 36 | - 37 | handle: company 38 | field: 39 | type: text 40 | display: Company 41 | width: 33 42 | sidebar: 43 | display: Sidebar 44 | sections: 45 | - 46 | display: Image 47 | fields: 48 | - 49 | handle: image 50 | field: common.image 51 | config: 52 | width: 100 53 | mode: grid 54 | listable: true 55 | -------------------------------------------------------------------------------- /resources/presets/testimonials/resources/fieldsets/testimonials.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | fields: 3 | - 4 | handle: heading 5 | field: 6 | type: text 7 | localizable: true 8 | display: Heading 9 | - 10 | handle: {{ handle }} 11 | field: 12 | max_items: 3 13 | mode: default 14 | create: true 15 | collections: 16 | - {{ handle }} 17 | display: {{ name }} 18 | type: entries 19 | icon: entries 20 | instructions: 'Select entries or leave empty to show all.' 21 | listable: hidden 22 | instructions_position: below 23 | -------------------------------------------------------------------------------- /resources/presets/testimonials/resources/views/page_builder/_testimonials.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} 3 | @desc The {{ name }} page builder block. 4 | @set page.page_builder.{{ handle }} 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block class="gap-y-8" }} 9 | {{ if block:heading }} 10 |
    11 | {{ partial:typography/h2 :content="block:heading" }} 12 |
    13 | {{ /if }} 14 | 15 | {{ 16 | {{ handle }} = block:{{ handle }} 17 | ? block:{{ handle }} 18 | : { collection:{{ handle }} sort="random" limit="3" } 19 | }} 20 | 21 | 51 | {{ /partial:page_builder/block }} 52 | 53 | -------------------------------------------------------------------------------- /resources/presets/theme_toggle/config.php: -------------------------------------------------------------------------------- 1 | 'theme_toggle', 5 | 'name' => 'Theme toggle', 6 | 'description' => 'Theme toggle for dark mode.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => 'resources/views/components/_theme_toggle.antlers.html', 11 | 'output' => 'resources/views/components/_theme_toggle.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'notify', 15 | 'content' => 'Add `@variant dark (&:where(.dark, .dark *));` to `resources/css/site.css`.', 16 | ], 17 | [ 18 | 'type' => 'notify', 19 | 'content' => 'Add `{{ partial:components/theme_toggle }}` as the last list item in the main ul in `resources/views/navigation/_main_desktop.antlers.html`. The `section:theme_toggle` is automatically yielded in `resources/views/snippets/_browser_appearance.antlers.html`.', 20 | ], 21 | [ 22 | 'type' => 'notify', 23 | 'content' => "Add this to your `lang/locale/strings.php` file:\n'theme_toggle_dark' => 'Use dark theme.',\n'theme_toggle_light' => 'Use light theme.',\n'theme_toggle_system' => 'Use system preference.',\n'theme_toggle_dark_short' => 'Dark',\n'theme_toggle_light_short' => 'Light',\n'theme_toggle_system_short' => 'System',\n'theme_toggle_dark_toggle_open' => 'Dark theme: open site theme picker.',\n'theme_toggle_dark_toggle_close' => 'Dark theme: close site theme picker.',\n'theme_toggle_light_toggle_open' => 'Light theme: open site theme picker.',\n'theme_toggle_light_toggle_close' => 'Light theme: close site theme picker.',\n'theme_toggle_system_toggle_open' => 'System (Default): open site theme picker.',\n'theme_toggle_system_toggle_close' => 'System (Default): close site theme picker.'", 24 | ], 25 | [ 26 | 'type' => 'notify', 27 | 'content' => 'Optionally, add the classes `scheme-light dark:scheme-dark` your HTML element in `resources/views/layout.antlers.html`.', 28 | ], 29 | ], 30 | ]; 31 | -------------------------------------------------------------------------------- /resources/presets/vacancies/content/collections/pages/vacancies.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: ee4ff0e0-8170-425c-be27-1de5c3ec4e2f 3 | blueprint: page 4 | title: {{ name }} 5 | template: {{ handle }}/index 6 | page_builder: 7 | - 8 | type: index_content 9 | enabled: true 10 | --- 11 | -------------------------------------------------------------------------------- /resources/presets/vacancies/content/collections/vacancies.yaml: -------------------------------------------------------------------------------- 1 | title: {{ name }} 2 | route: '/{mount}/{slug}' 3 | layout: layout 4 | template: {{ handle }}/show 5 | revisions: false 6 | date: true 7 | sort_dir: desc 8 | date_behavior: 9 | past: public 10 | future: private 11 | mount: ee4ff0e0-8170-425c-be27-1de5c3ec4e2f 12 | preview_targets: 13 | - 14 | label: Entry 15 | url: '{permalink}' 16 | refresh: false 17 | -------------------------------------------------------------------------------- /resources/presets/vacancies/resources/fieldsets/index_content.yaml: -------------------------------------------------------------------------------- 1 | title: 'Index content' 2 | fields: [ ] 3 | -------------------------------------------------------------------------------- /resources/presets/vacancies/resources/views/components/_vacancies_item.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} item 3 | @desc A {{ name }} item component. 4 | @param class Add optional CSS classes. 5 | #}} 6 | 7 | 8 |
    9 |
    10 | {{ partial:statamic-peak-tools::components/picture :image="image" sizes="(min-width: 1280px) 430px, (min-width: 768px) 30vw, 90vw" aspect_ratio="3/2" lazy="true" cover="true" }} 11 |
    12 | 13 |
    14 | 15 | {{ partial:typography/h3 content="{ title } - { hours } { trans:strings.{{ handle }}_hours }" class="mb-4 underline decoration-primary decoration-2 underline-offset-2 group-hover:text-primary motion-safe:transition-colors" }} 16 | 17 | 18 |
    19 | {{ trans:strings.{{ handle }}_published }}: {{ partial:typography/time :content="date" }} 20 | {{ trans:strings.{{ handle }}_expires }}: {{ partial:typography/time :content="expires" }} 21 |
    22 | 23 | {{ partial:typography/p :content="teaser" }} 24 |
    25 |
    26 | 27 | -------------------------------------------------------------------------------- /resources/presets/vacancies/resources/views/page_builder/_index_content.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Index content 3 | @desc The Index content page builder block. 4 | @set page.page_builder.index_content 5 | #}} 6 | 7 | {{ partial:page_builder/block }} 8 | {{ yield:index_content }} 9 | {{ /partial:page_builder/block }} 10 | -------------------------------------------------------------------------------- /resources/presets/vacancies/resources/views/vacancies/index.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} index 3 | @desc The {{ name }} index template. 4 | #}} 5 | 6 | 7 |
    8 | {{ page_builder scope="block" }} 9 | {{ partial src="page_builder/{type}" }} 10 | {{ /page_builder }} 11 |
    12 | 13 | 14 | {{ section:index_content }} 15 | 16 |
    17 | {{ collection:{{ handle }} sort="date:desc" paginate="true" limit="12" as="items" expires:is_after="{today}" }} 18 | {{ unless no_results }} 19 | {{ items }} 20 | {{ partial:components/{{ handle }}_item class="md:col-span-6" }} 21 | {{ /items }} 22 | {{ else }} 23 |
    24 | {{ trans:strings.no_results }} 25 |
    26 | {{ /unless }} 27 | {{ partial:statamic-peak-tools::components/pagination class="md:col-span-12" }} 28 | {{ /collection:{{ handle }} }} 29 |
    30 | 31 | {{ /section:index_content }} 32 | 33 | -------------------------------------------------------------------------------- /resources/sets/read_more/_read_more.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Read more 3 | @desc The Read more component. 4 | @set page.article.read_more 5 | #}} 6 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /resources/sets/read_more/config.php: -------------------------------------------------------------------------------- 1 | 'read_more', 5 | 'name' => 'Read more', 6 | 'description' => 'Link to a related article.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_read_more.antlers.html', 11 | 'output' => 'resources/views/components/_read_more.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'read_more.yaml', 16 | 'output' => 'resources/fieldsets/read_more.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_article_sets', 20 | 'set' => [ 21 | 'name' => 'Read more', 22 | 'icon' => 'content-book-open', 23 | 'instructions' => 'Link to a related article.', 24 | 'handle' => 'read_more', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/sets/read_more/read_more.yaml: -------------------------------------------------------------------------------- 1 | title: 'Read more' 2 | fields: 3 | - 4 | handle: entry 5 | field: common.entry 6 | config: 7 | width: 66 8 | -------------------------------------------------------------------------------- /resources/sets/video_self_hosted/_video_self_hosted.antlers.html: -------------------------------------------------------------------------------- 1 | {{# 2 | @name Video self hosted 3 | @desc The Video self hosted component. 4 | @set page.article.video_self_hosted 5 | #}} 6 | 7 | 8 |
    19 | 31 | 32 | {{ partial:typography/caption }} 33 |
    34 | 35 | -------------------------------------------------------------------------------- /resources/sets/video_self_hosted/config.php: -------------------------------------------------------------------------------- 1 | 'video_self_hosted', 5 | 'name' => 'Video self hosted', 6 | 'description' => 'Add a self hosted video.', 7 | 'operations' => [ 8 | [ 9 | 'type' => 'copy', 10 | 'input' => '_video_self_hosted.antlers.html', 11 | 'output' => 'resources/views/components/_video_self_hosted.antlers.html', 12 | ], 13 | [ 14 | 'type' => 'copy', 15 | 'input' => 'video_self_hosted.yaml', 16 | 'output' => 'resources/fieldsets/video_self_hosted.yaml', 17 | ], 18 | [ 19 | 'type' => 'update_article_sets', 20 | 'set' => [ 21 | 'name' => 'Video self hosted', 22 | 'icon' => 'media-webcam-video', 23 | 'instructions' => 'Add a self hosted video.', 24 | 'handle' => 'video_self_hosted', 25 | ], 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /resources/sets/video_self_hosted/video_self_hosted.yaml: -------------------------------------------------------------------------------- 1 | title: 'Video self hosted' 2 | fields: 3 | - 4 | handle: size 5 | field: common.size 6 | config: 7 | localizable: true 8 | width: 100 9 | - 10 | handle: sources 11 | field: 12 | min_rows: 1 13 | add_row: 'Add video source' 14 | type: grid 15 | display: Sources 16 | fields: 17 | - 18 | handle: file 19 | field: 20 | max_files: 1 21 | min_files: 1 22 | container: images 23 | show_set_alt: false 24 | type: assets 25 | display: File 26 | width: 50 27 | validate: 28 | - required 29 | - 30 | handle: query 31 | field: 32 | placeholder: '(max-width: 599px)' 33 | type: text 34 | display: 'Media query' 35 | instructions: "Use optional media queries to deliver responsive video's." 36 | width: 50 37 | - 38 | handle: controls 39 | field: 40 | type: toggle 41 | display: Controls 42 | instructions: 'Show video UI controls' 43 | width: 50 44 | instructions_position: below 45 | - 46 | handle: plays_inline 47 | field: 48 | type: toggle 49 | display: 'Plays inline' 50 | instructions: "Play the video in it's inline area." 51 | width: 50 52 | instructions_position: below 53 | - 54 | handle: autoplay 55 | field: 56 | type: toggle 57 | display: Autoplay 58 | instructions: 'Autoplay the video, you might also want to enable muted.' 59 | width: 50 60 | instructions_position: below 61 | - 62 | handle: muted 63 | field: 64 | type: toggle 65 | display: Muted 66 | instructions: "Mute the video. Often required for autoplaying video's." 67 | width: 50 68 | instructions_position: below 69 | - 70 | handle: loop 71 | field: 72 | type: toggle 73 | display: Loop 74 | instructions: 'Loop the video.' 75 | width: 50 76 | instructions_position: below 77 | - 78 | handle: disablepictureinpicture 79 | field: 80 | type: toggle 81 | display: 'Disable PiP' 82 | instructions: 'Disable Picture in Picture.' 83 | width: 50 84 | instructions_position: below 85 | - 86 | handle: caption 87 | field: 88 | type: text 89 | localizable: true 90 | display: Caption 91 | -------------------------------------------------------------------------------- /resources/stubs/block.antlers.html.stub: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} 3 | @desc The {{ name }} page builder block. 4 | @set page.page_builder.{{ filepath_dotted }}{{ filename }} 5 | #}} 6 | 7 | 8 | {{ partial:page_builder/block }} 9 | {{ partial:typography/h3 content="🔧
    {{ name }}" class="span-content text-center" }} 10 | {{ /partial:page_builder/block }} 11 | 12 | -------------------------------------------------------------------------------- /resources/stubs/collection.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | route: '{{ route }}' 3 | layout: {{ layout }} 4 | template: {{ template }} 5 | revisions: {{ revisions }} 6 | date: {{ dated }} 7 | sort_dir: {{ sort_dir }} 8 | date_behavior: 9 | past: {{ date_past }} 10 | future: {{ date_future }} 11 | mount: {{ mount }} 12 | slugs: {{ slugs }} 13 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_private.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | sidebar: 26 | display: Sidebar 27 | sections: 28 | - 29 | display: Meta 30 | fields: 31 | - 32 | handle: slug 33 | field: 34 | type: slug 35 | localizable: true 36 | generate: true 37 | listable: hidden 38 | display: Slug 39 | validate: 40 | - required 41 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_private_dated.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | sidebar: 26 | display: Sidebar 27 | sections: 28 | - 29 | display: Meta 30 | fields: 31 | - 32 | handle: slug 33 | field: 34 | type: slug 35 | localizable: true 36 | generate: true 37 | listable: hidden 38 | display: Slug 39 | validate: 40 | - required 41 | - 42 | handle: date 43 | field: 44 | type: date 45 | listable: true 46 | required: true 47 | validate: 48 | - required 49 | display: Date 50 | mode: single 51 | time_enabled: false 52 | time_required: false 53 | earliest_date: '2021-01-01' 54 | full_width: false 55 | inline: false 56 | columns: 1 57 | rows: 1 58 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_private_dated_no_slug.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | sidebar: 26 | display: Sidebar 27 | sections: 28 | - 29 | display: Meta 30 | fields: 31 | - 32 | handle: date 33 | field: 34 | type: date 35 | listable: true 36 | required: true 37 | validate: 38 | - required 39 | display: Date 40 | mode: single 41 | time_enabled: false 42 | time_required: false 43 | earliest_date: '2021-01-01' 44 | full_width: false 45 | inline: false 46 | columns: 1 47 | rows: 1 48 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_private_no_slug.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_public.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | seo: 26 | display: SEO 27 | sections: 28 | - 29 | display: Basic 30 | instructions: 'Basic SEO settings.' 31 | fields: 32 | - 33 | import: 'statamic-peak-seo::seo_basic' 34 | - 35 | display: Advanced 36 | instructions: 'Advanced SEO settings.' 37 | fields: 38 | - 39 | import: 'statamic-peak-seo::seo_advanced' 40 | - 41 | display: 'Open Graph' 42 | instructions: 'Open Graph meta tags for social sharing.' 43 | fields: 44 | - 45 | import: 'statamic-peak-seo::seo_open_graph' 46 | - 47 | display: Sitemap 48 | instructions: 'Sitemap configuration.' 49 | fields: 50 | - 51 | import: 'statamic-peak-seo::seo_sitemap' 52 | - 53 | display: 'JSON-ld Schema' 54 | instructions: 'Custom JSON-ld schema objects.' 55 | fields: 56 | - 57 | import: 'statamic-peak-seo::seo_jsonld' 58 | sidebar: 59 | display: Sidebar 60 | sections: 61 | - 62 | display: Meta 63 | fields: 64 | - 65 | handle: slug 66 | field: 67 | type: slug 68 | localizable: true 69 | generate: true 70 | listable: hidden 71 | display: Slug 72 | validate: 73 | - required 74 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_public_dated.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | seo: 26 | display: SEO 27 | sections: 28 | - 29 | display: Basic 30 | instructions: 'Basic SEO settings.' 31 | fields: 32 | - 33 | import: 'statamic-peak-seo::seo_basic' 34 | - 35 | display: Advanced 36 | instructions: 'Advanced SEO settings.' 37 | fields: 38 | - 39 | import: 'statamic-peak-seo::seo_advanced' 40 | - 41 | display: 'Open Graph' 42 | instructions: 'Open Graph meta tags for social sharing.' 43 | fields: 44 | - 45 | import: 'statamic-peak-seo::seo_open_graph' 46 | - 47 | display: Sitemap 48 | instructions: 'Sitemap configuration.' 49 | fields: 50 | - 51 | import: 'statamic-peak-seo::seo_sitemap' 52 | - 53 | display: 'JSON-ld Schema' 54 | instructions: 'Custom JSON-ld schema objects.' 55 | fields: 56 | - 57 | import: 'statamic-peak-seo::seo_jsonld' 58 | sidebar: 59 | display: Sidebar 60 | sections: 61 | - 62 | display: Meta 63 | fields: 64 | - 65 | handle: slug 66 | field: 67 | type: slug 68 | localizable: true 69 | generate: true 70 | listable: hidden 71 | display: Slug 72 | validate: 73 | - required 74 | - 75 | handle: date 76 | field: 77 | type: date 78 | listable: true 79 | required: true 80 | validate: 81 | - required 82 | display: Date 83 | mode: single 84 | time_enabled: false 85 | time_required: false 86 | earliest_date: '2021-01-01' 87 | full_width: false 88 | inline: false 89 | columns: 1 90 | rows: 1 91 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_public_dated_no_slug.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | seo: 26 | display: SEO 27 | sections: 28 | - 29 | display: Basic 30 | instructions: 'Basic SEO settings.' 31 | fields: 32 | - 33 | import: 'statamic-peak-seo::seo_basic' 34 | - 35 | display: Advanced 36 | instructions: 'Advanced SEO settings.' 37 | fields: 38 | - 39 | import: 'statamic-peak-seo::seo_advanced' 40 | - 41 | display: 'Open Graph' 42 | instructions: 'Open Graph meta tags for social sharing.' 43 | fields: 44 | - 45 | import: 'statamic-peak-seo::seo_open_graph' 46 | - 47 | display: Sitemap 48 | instructions: 'Sitemap configuration.' 49 | fields: 50 | - 51 | import: 'statamic-peak-seo::seo_sitemap' 52 | - 53 | display: 'JSON-ld Schema' 54 | instructions: 'Custom JSON-ld schema objects.' 55 | fields: 56 | - 57 | import: 'statamic-peak-seo::seo_jsonld' 58 | sidebar: 59 | display: Sidebar 60 | sections: 61 | - 62 | display: Meta 63 | fields: 64 | - 65 | handle: date 66 | field: 67 | type: date 68 | listable: true 69 | required: true 70 | validate: 71 | - required 72 | display: Date 73 | mode: single 74 | time_enabled: false 75 | time_required: false 76 | earliest_date: '2021-01-01' 77 | full_width: false 78 | inline: false 79 | columns: 1 80 | rows: 1 81 | -------------------------------------------------------------------------------- /resources/stubs/collection_blueprint_public_no_slug.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ collection_name }} 2 | tabs: 3 | main: 4 | display: Main 5 | sections: 6 | - 7 | display: General 8 | fields: 9 | - 10 | handle: title 11 | field: 12 | type: text 13 | required: true 14 | input_type: text 15 | localizable: true 16 | listable: true 17 | display: Title 18 | validate: 19 | - required 20 | - 21 | display: 'Page builder' 22 | fields: 23 | - 24 | import: page_builder 25 | seo: 26 | display: SEO 27 | sections: 28 | - 29 | display: Basic 30 | instructions: 'Basic SEO settings.' 31 | fields: 32 | - 33 | import: 'statamic-peak-seo::seo_basic' 34 | - 35 | display: Advanced 36 | instructions: 'Advanced SEO settings.' 37 | fields: 38 | - 39 | import: 'statamic-peak-seo::seo_advanced' 40 | - 41 | display: 'Open Graph' 42 | instructions: 'Open Graph meta tags for social sharing.' 43 | fields: 44 | - 45 | import: 'statamic-peak-seo::seo_open_graph' 46 | - 47 | display: Sitemap 48 | instructions: 'Sitemap configuration.' 49 | fields: 50 | - 51 | import: 'statamic-peak-seo::seo_sitemap' 52 | - 53 | display: 'JSON-ld Schema' 54 | instructions: 'Custom JSON-ld schema objects.' 55 | fields: 56 | - 57 | import: 'statamic-peak-seo::seo_jsonld' 58 | -------------------------------------------------------------------------------- /resources/stubs/fieldset_block.yaml.stub: -------------------------------------------------------------------------------- 1 | title: "{{ name }}" 2 | fields: [ ] 3 | -------------------------------------------------------------------------------- /resources/stubs/fieldset_set.yaml.stub: -------------------------------------------------------------------------------- 1 | title: '{{ name }}' 2 | fields: 3 | - 4 | handle: size 5 | field: common.size 6 | config: 7 | instructions: 'The size in which the {{ name }} should be displayed.' 8 | -------------------------------------------------------------------------------- /resources/stubs/global.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ global_name }} 2 | -------------------------------------------------------------------------------- /resources/stubs/global_blueprint.yaml.stub: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: {{ global_name }} 7 | fields: [ ] 8 | -------------------------------------------------------------------------------- /resources/stubs/home.md.stub: -------------------------------------------------------------------------------- 1 | --- 2 | id: home 3 | blueprint: page 4 | title: Home 5 | updated_by: fd779fda-9c01-4b82-9fad-6f6cedfe03cb 6 | updated_at: 1661203932 7 | seo_noindex: false 8 | seo_nofollow: false 9 | seo_canonical_type: entry 10 | sitemap_change_frequency: weekly 11 | sitemap_priority: 0.5 12 | published: true 13 | --- 14 | -------------------------------------------------------------------------------- /resources/stubs/index.antlers.html.stub: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ collection_name }} index 3 | @desc The {{ collection_name }} index template. 4 | #}} 5 | 6 | 7 |
    8 | {{ page_builder scope="block" }} 9 | {{ partial src="page_builder/{type}" }} 10 | {{ /page_builder }} 11 |
    12 | 13 | 14 | {{ section:index_content }} 15 | 16 |
    17 | {{ collection:{{ handle }} sort="{{ sort }}" paginate="true" limit="10" as="items" }} 18 | {{ unless no_results }} 19 | {{ items }} 20 |
    21 | {{ title }} 22 |
    23 | {{ /items }} 24 | {{ else }} 25 |
    26 | {{ trans:strings.no_results }} 27 |
    28 | {{ /unless }} 29 | {{ partial:statamic-peak-tools::components/pagination class="col-span-12" }} 30 | {{ /collection:{{ handle }} }} 31 |
    32 | 33 | {{ /section:index_content }} 34 | -------------------------------------------------------------------------------- /resources/stubs/navigation.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ navigation_name }} 2 | max_depth: {{ max_depth }} 3 | -------------------------------------------------------------------------------- /resources/stubs/navigation_blueprint.yaml.stub: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: General 7 | -------------------------------------------------------------------------------- /resources/stubs/partial.antlers.html.stub: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ partial_name }} 3 | @desc {{ partial_description }} 4 | #}} 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/stubs/set.antlers.html.stub: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ name }} 3 | @desc The {{ name }} component. 4 | @set page.article.{{ filepath_dotted }}{{ filename }} 5 | #}} 6 | 7 | 8 |
    19 |

    🔧
    {{ name }}

    20 |
    21 | 22 | -------------------------------------------------------------------------------- /resources/stubs/show.antlers.html.stub: -------------------------------------------------------------------------------- 1 | {{# 2 | @name {{ collection_name }} show 3 | @desc The {{ collection_name }} show template. 4 | #}} 5 | 6 | 7 |
    8 |
    9 | {{ partial:typography/h1 :content="title" class="span-content" }} 10 |
    11 | 12 | {{ page_builder scope="block" }} 13 | {{ partial src="page_builder/{type}" }} 14 | {{ /page_builder }} 15 |
    16 | 17 | -------------------------------------------------------------------------------- /resources/stubs/taxonomy.yaml.stub: -------------------------------------------------------------------------------- 1 | title: {{ taxonomy_name }} 2 | layout: layout 3 | -------------------------------------------------------------------------------- /resources/stubs/taxonomy_blueprint.yaml.stub: -------------------------------------------------------------------------------- 1 | tabs: 2 | main: 3 | display: Main 4 | sections: 5 | - 6 | display: General 7 | fields: 8 | - 9 | handle: title 10 | field: 11 | type: text 12 | required: true 13 | validate: 14 | - required 15 | - 16 | handle: slug 17 | field: 18 | type: slug 19 | required: true 20 | validate: 21 | - required 22 | - 'max:200' 23 | visibility: hidden 24 | title: {{ taxonomy_name }} 25 | -------------------------------------------------------------------------------- /src/Commands/InstallBlock.php: -------------------------------------------------------------------------------- 1 | handleInstallation( 24 | label: 'Which blocks do you want to install into your page builder?', 25 | emptyValidation: 'Please select at least one block. (Space)', 26 | successMessage: fn (Installable $installable) => info("[✓] Peak page builder block '$installable->name' installed.") 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Commands/InstallPreset.php: -------------------------------------------------------------------------------- 1 | handleInstallation( 24 | label: 'Which presets do you want to install into your site?', 25 | emptyValidation: 'Please select at least one preset. (Space)', 26 | successMessage: fn (Installable $installable) => info("[✓] Peak preset '$installable->name' installed.") 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Commands/InstallSet.php: -------------------------------------------------------------------------------- 1 | handleInstallation( 24 | label: 'Which sets do you want to install into your article field?', 25 | emptyValidation: 'Please select at least one set. (Space)', 26 | successMessage: fn (Installable $installable) => info("[✓] Peak Article Set '$installable->name' installed.") 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Commands/MakeBlock.php: -------------------------------------------------------------------------------- 1 | checkLicense(); 30 | 31 | $this->createModel(); 32 | $this->createTemplate(); 33 | $this->createFieldset(); 34 | $this->updatePageBuilder(); 35 | 36 | $this->runOperations(); 37 | 38 | info("[✓] Peak page builder block '{$this->model->name}' added."); 39 | } 40 | 41 | protected function createModel(): void 42 | { 43 | $this->model = app(Block::class); 44 | } 45 | 46 | protected function createTemplate(): void 47 | { 48 | $this->operations[] = [ 49 | 'type' => 'copy', 50 | 'input' => 'stubs/block.antlers.html.stub', 51 | 'output' => 'resources/views/page_builder/{{ filepath }}_{{ handle }}.antlers.html', 52 | ]; 53 | } 54 | 55 | protected function createFieldset(): void 56 | { 57 | $this->operations[] = [ 58 | 'type' => 'copy', 59 | 'input' => 'stubs/fieldset_block.yaml.stub', 60 | 'output' => 'resources/fieldsets/{{ filepath }}{{ handle }}.yaml', 61 | ]; 62 | } 63 | 64 | protected function updatePageBuilder(): void 65 | { 66 | $this->operations[] = [ 67 | 'type' => 'update_page_builder', 68 | 'block' => $this->model->toArray(), 69 | ]; 70 | } 71 | 72 | protected function runOperations(): void 73 | { 74 | app(Installable::class, [ 75 | 'config' => [ 76 | 'name' => $this->model->name, 77 | 'handle' => $this->model->handle, 78 | 'operations' => $this->operations, 79 | 'base_path' => base_path('vendor/studio1902/statamic-peak-commands/resources'), 80 | ], 81 | ])->install(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Commands/MakePartial.php: -------------------------------------------------------------------------------- 1 | checkLicense(); 29 | 30 | $this->createModel(); 31 | $this->createTemplate(); 32 | 33 | $this->runOperations(); 34 | 35 | info("[✓] {$this->model->type} '{$this->model->filename}' added."); 36 | } 37 | 38 | protected function createModel(): void 39 | { 40 | $this->model = app(Partial::class); 41 | } 42 | 43 | protected function createTemplate(): void 44 | { 45 | $this->operations[] = [ 46 | 'type' => 'copy', 47 | 'input' => 'stubs/partial.antlers.html.stub', 48 | 'output' => "resources/views/{$this->model->folder}/_{$this->model->filename}.antlers.html", 49 | 'replacements' => [ 50 | '{{ partial_name }}' => $this->model->name, 51 | '{{ partial_description }}' => $this->model->description, 52 | '{{ folder }}' => $this->model->folder, 53 | ], 54 | ]; 55 | } 56 | 57 | protected function runOperations(): void 58 | { 59 | app(Installable::class, [ 60 | 'config' => [ 61 | 'name' => $this->model->name, 62 | 'handle' => $this->model->filename, 63 | 'operations' => $this->operations, 64 | 'base_path' => base_path('vendor/studio1902/statamic-peak-commands/resources'), 65 | ], 66 | ])->install(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Commands/MakeSet.php: -------------------------------------------------------------------------------- 1 | checkLicense(); 30 | 31 | $this->createModel(); 32 | $this->createTemplate(); 33 | $this->createFieldset(); 34 | $this->updateArticleSets(); 35 | 36 | $this->runOperations(); 37 | 38 | info("[✓] Peak page builder Article set '{$this->model->name}' added."); 39 | } 40 | 41 | protected function createModel(): void 42 | { 43 | $this->model = app(Set::class); 44 | } 45 | 46 | protected function createTemplate(): void 47 | { 48 | $this->operations[] = [ 49 | 'type' => 'copy', 50 | 'input' => 'stubs/set.antlers.html.stub', 51 | 'output' => 'resources/views/components/{{ filepath }}_{{ handle }}.antlers.html', 52 | ]; 53 | } 54 | 55 | protected function createFieldset(): void 56 | { 57 | $this->operations[] = [ 58 | 'type' => 'copy', 59 | 'input' => 'stubs/fieldset_set.yaml.stub', 60 | 'output' => 'resources/fieldsets/{{ filepath }}{{ handle }}.yaml', 61 | ]; 62 | } 63 | 64 | protected function updateArticleSets(): void 65 | { 66 | $this->operations[] = [ 67 | 'type' => 'update_article_sets', 68 | 'set' => $this->model->toArray(), 69 | ]; 70 | } 71 | 72 | protected function runOperations(): void 73 | { 74 | app(Installable::class, [ 75 | 'config' => [ 76 | 'name' => $this->model->name, 77 | 'handle' => $this->model->handle, 78 | 'operations' => $this->operations, 79 | 'base_path' => base_path('vendor/studio1902/statamic-peak-commands/resources'), 80 | ], 81 | ])->install(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Commands/Traits/CanClearCache.php: -------------------------------------------------------------------------------- 1 | handleWithCatch(); 13 | } catch (\Exception $exception) { 14 | error($exception->getMessage()); 15 | exit(1); 16 | } 17 | } 18 | 19 | abstract public function handleWithCatch(); 20 | } 21 | -------------------------------------------------------------------------------- /src/Commands/Traits/NeedsValidLicense.php: -------------------------------------------------------------------------------- 1 | first(fn ($addonLicense) => $addonLicense->addon()->id() === 'studio1902/statamic-peak-commands'); 17 | 18 | static::$licensed = $addonLicense && $addonLicense->valid(); 19 | 20 | if (! static::$licensed) { 21 | alert('You need a valid license to use this command.'); 22 | info('You can support Peak and buy one here: https://statamic.com/addons/studio1902/peak-commands'); 23 | exit; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Facades/Registry.php: -------------------------------------------------------------------------------- 1 | name = Arr::get($config, 'name') ?? $this->promptForName(); 27 | $this->handle = Arr::get($config, 'handle') ?? $this->promptForHandle(); 28 | $this->instructions = Arr::get($config, 'instructions') ?? $this->promptForInstructions(); 29 | $this->icon = Arr::get($config, 'icon') ?? $this->promptForIcon(); 30 | } 31 | 32 | public function toArray(): array 33 | { 34 | return [ 35 | 'name' => $this->name, 36 | 'handle' => $this->handle, 37 | 'instructions' => $this->instructions, 38 | 'icon' => $this->icon, 39 | ]; 40 | } 41 | 42 | protected function promptForName(): string 43 | { 44 | return text( 45 | label: 'What should be the name for this block?', 46 | placeholder: 'E.g. Text and image', 47 | required: true 48 | ); 49 | } 50 | 51 | protected function promptForHandle(): string 52 | { 53 | return text( 54 | label: 'What should be the handle for this block?', 55 | default: Stringy::slugify($this->name, '_', Config::getShortLocale()), 56 | required: true 57 | ); 58 | } 59 | 60 | protected function promptForInstructions(): string 61 | { 62 | return text( 63 | label: 'What should be the instructions for this block?', 64 | placeholder: 'E.g. Renders text and an image.', 65 | required: true 66 | ); 67 | } 68 | 69 | protected function promptForIcon(): string 70 | { 71 | return $this->pickIcon('Which icon do you want to use for this block?'); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Models/Globals.php: -------------------------------------------------------------------------------- 1 | name = Arr::get($config, 'name') ?? $this->promptForName(); 23 | $this->grantPermissions = Arr::get($config, 'permissions') ?? $this->promptForPermissions(); 24 | $this->filename = $this->generateFilename(); 25 | } 26 | 27 | protected function promptForName(): string 28 | { 29 | return text( 30 | label: 'What should be the name for this global?', 31 | placeholder: 'E.g. Contact data', 32 | required: true 33 | ); 34 | } 35 | 36 | protected function generateFilename(): string 37 | { 38 | return Stringy::slugify($this->name, '_', Config::getShortLocale()); 39 | } 40 | 41 | protected function promptForPermissions(): bool 42 | { 43 | return confirm( 44 | label: 'Grant edit permissions to editor role?', 45 | default: true 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Models/Installable.php: -------------------------------------------------------------------------------- 1 | name = Arr::get($config, 'name'); 36 | $this->handle = Arr::get($config, 'handle'); 37 | $this->basePath = Arr::get($config, 'base_path'); 38 | $this->operations = Arr::get($config, 'operations'); 39 | $this->singularName = Arr::get($config, 'singular_name', ''); 40 | 41 | // Extract filepath if handle contains directory 42 | $this->extractFilepath(); 43 | 44 | // Apply fallbacks 45 | $this->renameName = $this->name; 46 | $this->renameHandle = $this->handle; 47 | $this->renameSingularName = $this->singularName; 48 | $this->renameSingularHandle = Str::slug($this->renameSingularName, '_', Config::getShortLocale()); 49 | } 50 | 51 | public function install(): self 52 | { 53 | return collect($this->operations) 54 | ->map(fn (array $operation) => Registry::resolveOperation(Arr::get($operation, 'type'), $operation)) 55 | ->reduce(fn (Installable $installable, Operation $operation) => $operation->hydrate($installable)->run(), $this); 56 | } 57 | 58 | protected function extractFilepath(): void 59 | { 60 | $full = collect(explode('/', $this->handle)); 61 | 62 | $this->handle = $full->pop(); 63 | 64 | $this->filepath = $full->count() > 0 ? $full->join('/').'/' : ''; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Models/Nav.php: -------------------------------------------------------------------------------- 1 | name = Arr::get($config, 'name') ?? $this->promptForName(); 30 | $this->maxDepth = Arr::get($config, 'max_depth') ?? $this->promptForMaxDepth(); 31 | $this->collections = Arr::get($config, 'collections') ?? $this->promptForCollections(); 32 | $this->grantPermissions = Arr::get($config, 'permissions') ?? $this->promptForPermissions(); 33 | $this->filename = $this->generateFilename(); 34 | } 35 | 36 | protected function promptForName(): string 37 | { 38 | return text( 39 | label: 'What should be the name for this navigation?', 40 | placeholder: 'E.g. Actions', 41 | required: true 42 | ); 43 | } 44 | 45 | protected function generateFilename(): string 46 | { 47 | return Stringy::slugify($this->name, '_', Config::getShortLocale()); 48 | } 49 | 50 | protected function promptForCollections(): array 51 | { 52 | $options = collect(Collection::all())->pluck('title', 'handle'); 53 | 54 | return multisearch( 55 | label: 'Enable linking to entries from these collections:', 56 | options: fn (string $value) => strlen($value) > 0 57 | ? $options->filter(fn (string $item) => Str::contains($item, $value, true))->toArray() 58 | : $options->toArray(), 59 | scroll: 15 60 | ); 61 | } 62 | 63 | protected function promptForPermissions(): bool 64 | { 65 | return confirm( 66 | label: 'Grant edit permissions to editor role?', 67 | default: true 68 | ); 69 | } 70 | 71 | protected function promptForMaxDepth(): int 72 | { 73 | return (int) text( 74 | label: 'What should be the max depth for this navigation?', 75 | placeholder: '2', 76 | validate: ['name' => 'required|int|numeric'] 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Models/Partial.php: -------------------------------------------------------------------------------- 1 | type = Arr::get($config, 'type') ?? $this->promptForType(); 27 | $this->name = Arr::get($config, 'name') ?? $this->promptForName(); 28 | $this->description = Arr::get($config, 'description') ?? $this->promptForDescription(); 29 | $this->filename = $this->generateFilename(); 30 | $this->folder = $this->generateFolderName(); 31 | } 32 | 33 | protected function promptForName(): string 34 | { 35 | return text( 36 | label: 'What should be the name for this partial?', 37 | placeholder: 'E.g. Card', 38 | required: true 39 | ); 40 | } 41 | 42 | protected function promptForDescription(): string 43 | { 44 | return text( 45 | label: 'What should be the description for this partial?', 46 | placeholder: 'E.g. A card component.', 47 | required: true 48 | ); 49 | } 50 | 51 | protected function generateFilename(): string 52 | { 53 | return Stringy::slugify($this->name, '_', Config::getShortLocale()); 54 | } 55 | 56 | protected function promptForType(): string 57 | { 58 | return select( 59 | label: 'What type of partial do you want to add?', 60 | options: ['Component', 'Layout', 'Snippet', 'Typography'], 61 | default: 'Component' 62 | ); 63 | } 64 | 65 | protected function generateFolderName(): string 66 | { 67 | $folder = strtolower($this->type); 68 | 69 | if (in_array($folder, ['component', 'snippet'])) { 70 | $folder = $folder.'s'; 71 | } 72 | 73 | return $folder; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Models/Set.php: -------------------------------------------------------------------------------- 1 | name = Arr::get($config, 'name') ?? $this->promptForName(); 27 | $this->handle = Arr::get($config, 'handle') ?? $this->promptForHandle(); 28 | $this->instructions = Arr::get($config, 'instructions') ?? $this->promptForInstructions(); 29 | $this->icon = Arr::get($config, 'icon') ?? $this->promptForIcon(); 30 | } 31 | 32 | public function toArray(): array 33 | { 34 | return [ 35 | 'name' => $this->name, 36 | 'handle' => $this->handle, 37 | 'instructions' => $this->instructions, 38 | 'icon' => $this->icon, 39 | ]; 40 | } 41 | 42 | protected function promptForName(): string 43 | { 44 | return text( 45 | label: 'What should be the name for this set?', 46 | placeholder: 'E.g. Card', 47 | required: true 48 | ); 49 | } 50 | 51 | protected function promptForHandle(): string 52 | { 53 | return text( 54 | label: 'What should be the handle for this set?', 55 | default: Stringy::slugify($this->name, '_', Config::getShortLocale()), 56 | required: true 57 | ); 58 | } 59 | 60 | protected function promptForInstructions(): string 61 | { 62 | return text( 63 | label: 'What should be the instructions for this set?', 64 | placeholder: 'E.g. Lead text that renders big and bold.', 65 | required: true 66 | ); 67 | } 68 | 69 | protected function promptForIcon(): string 70 | { 71 | return $this->pickIcon('Which icon do you want to use for this set?'); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Models/Taxonomy.php: -------------------------------------------------------------------------------- 1 | name = Arr::get($config, 'name') ?? $this->promptForName(); 28 | $this->collections = Arr::get($config, 'collections') ?? $this->promptForCollections(); 29 | $this->grantPermissions = Arr::get($config, 'permissions') ?? $this->promptForPermissions(); 30 | $this->filename = $this->generateFilename(); 31 | } 32 | 33 | protected function promptForName(): string 34 | { 35 | return text( 36 | label: 'What should be the name for this taxonomy?', 37 | placeholder: 'E.g. Tags', 38 | required: true 39 | ); 40 | } 41 | 42 | protected function generateFilename(): string 43 | { 44 | return Stringy::slugify($this->name, '_', Config::getShortLocale()); 45 | } 46 | 47 | protected function promptForCollections(): array 48 | { 49 | $options = collect(Collection::all())->pluck('title', 'handle'); 50 | 51 | return multisearch( 52 | label: "Which collection(s) do you want to attach $this->name to?", 53 | options: fn (string $value) => strlen($value) > 0 54 | ? $options->filter(fn (string $item) => Str::contains($item, $value, true))->toArray() 55 | : $options->toArray(), 56 | scroll: 15 57 | ); 58 | } 59 | 60 | protected function promptForPermissions(): bool 61 | { 62 | return confirm( 63 | label: 'Grant edit permissions to editor role?', 64 | default: true 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Operations/AttachCollectionsToNavigation.php: -------------------------------------------------------------------------------- 1 | navigation = Arr::get($config, 'navigation'); 21 | $this->collections = Arr::get($config, 'collections'); 22 | } 23 | 24 | public function run(): Installable 25 | { 26 | if (! $this->collections) { 27 | return $this->installable; 28 | } 29 | 30 | $navigation = Yaml::parseFile(base_path("content/navigation/{$this->navigation}.yaml")); 31 | $existingCollections = Arr::get($navigation, 'collections', []); 32 | 33 | $collections = Arr::sort(array_merge($existingCollections, $this->collections)); 34 | 35 | Arr::set($navigation, 'collections', $collections); 36 | 37 | File::put(base_path("content/navigation/{$this->navigation}.yaml"), Yaml::dump($navigation, 99, 2)); 38 | 39 | note("Collections attached to '{$this->navigation}' navigation."); 40 | 41 | return $this->installable; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Operations/AttachTaxonomyToCollections.php: -------------------------------------------------------------------------------- 1 | taxonomy = Arr::get($config, 'taxonomy'); 21 | $this->collections = Arr::get($config, 'collections'); 22 | } 23 | 24 | public function run(): Installable 25 | { 26 | if (! $this->collections) { 27 | return $this->installable; 28 | } 29 | 30 | collect($this->collections)->each(function ($collectionHandle) { 31 | $collection = Yaml::parseFile(base_path("content/collections/{$collectionHandle}.yaml")); 32 | $existingTaxonomies = Arr::get($collection, 'taxonomies', []); 33 | 34 | $taxonomies = Arr::sort(array_merge($existingTaxonomies, [$this->taxonomy])); 35 | 36 | Arr::set($collection, 'taxonomies', array_values($taxonomies)); 37 | 38 | File::put(base_path("content/collections/{$collectionHandle}.yaml"), Yaml::dump($collection, 99, 2)); 39 | 40 | note("Taxonomy '{$this->taxonomy}' attached to '{$collectionHandle}' collection."); 41 | }); 42 | 43 | return $this->installable; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Operations/Notify.php: -------------------------------------------------------------------------------- 1 | content = Arr::get($config, 'content'); 19 | } 20 | 21 | public function run(): Installable 22 | { 23 | $message = (string) Str::of($this->content) 24 | ->replace('{{ handle }}', $this->installable->renameHandle) 25 | ->replace('{{ name }}', $this->installable->renameName); 26 | 27 | warning("\n".$message."\n"); 28 | 29 | pause('Follow the instructions and press ENTER to continue.'); 30 | 31 | return $this->installable; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Operations/Operation.php: -------------------------------------------------------------------------------- 1 | installable = $installable; 14 | 15 | return $this; 16 | } 17 | 18 | abstract public function run(): Installable; 19 | } 20 | -------------------------------------------------------------------------------- /src/Operations/Rename.php: -------------------------------------------------------------------------------- 1 | installable->renameName = text( 18 | label: "What should be the collection name for '{$this->installable->name}'?", 19 | placeholder: "E.g. '{$this->installable->name}'", 20 | required: true 21 | ); 22 | 23 | $this->installable->renameHandle = Str::slug($this->installable->renameName, '_', Config::getShortLocale()); 24 | 25 | $this->installable->renameSingularName = ucfirst(text( 26 | label: "What is the singular name for this '{$this->installable->renameName}' collection?", 27 | placeholder: "E.g. '{$this->installable->singularName}'", 28 | required: true 29 | )); 30 | 31 | $this->installable->renameSingularHandle = Str::slug($this->installable->renameSingularName, Config::getShortLocale()); 32 | 33 | return $this->installable; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Operations/Run.php: -------------------------------------------------------------------------------- 1 | command = Arr::get($config, 'command'); 33 | $this->processingMessage = Arr::get($config, 'processing_message', ''); 34 | $this->successMessage = Arr::get($config, 'success_message', ''); 35 | $this->errorMessage = Arr::get($config, 'error_message', ''); 36 | $this->tty = Arr::get($config, 'tty', false); 37 | $this->spinner = Arr::get($config, 'spinner', true); 38 | $this->timeout = Arr::get($config, 'timeout', 120); 39 | } 40 | 41 | public function run(): Installable 42 | { 43 | $process = new Process(explode(' ', $this->command)); 44 | $process->setTimeout($this->timeout); 45 | $process->setTty($this->tty); 46 | 47 | try { 48 | $this->spinner ? 49 | $this->withSpinner( 50 | fn () => $process->mustRun(), 51 | $this->processingMessage, 52 | $this->successMessage 53 | ) : 54 | $this->withoutSpinner( 55 | fn () => $process->mustRun(), 56 | $this->successMessage 57 | ); 58 | 59 | return $this->installable; 60 | } catch (ProcessFailedException $exception) { 61 | error($this->errorMessage ?: $exception->getMessage()); 62 | exit(); 63 | } 64 | } 65 | 66 | protected function withSpinner(callable $callback, string $processingMessage = '', string $successMessage = ''): void 67 | { 68 | spin($callback, $processingMessage); 69 | 70 | if ($successMessage) { 71 | note($successMessage); 72 | } 73 | } 74 | 75 | protected function withoutSpinner(callable $callback, string $successMessage = ''): void 76 | { 77 | $callback(); 78 | 79 | if ($successMessage) { 80 | note($successMessage); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Operations/Traits/CanPickIcon.php: -------------------------------------------------------------------------------- 1 | getStaticPropertyValue('iconsDirectory') ?? base_path('/vendor/statamic/cms/resources/svg/icons'); 18 | $iconsFolder = $reflection->getStaticPropertyValue('iconsFolder'); 19 | 20 | $icons = collect(File::allFiles("$iconsDirectory/$iconsFolder")) 21 | ->map(fn ($file) => str_replace('.svg', '', $file->getBasename('.'.$file->getExtension()))); 22 | 23 | if (DIRECTORY_SEPARATOR === '\\') { 24 | return $icons->first(); 25 | } 26 | 27 | return search( 28 | label: $label, 29 | options: function (string $value) use ($icons) { 30 | if (! $value) { 31 | return $icons 32 | ->values() 33 | ->all(); 34 | } 35 | 36 | return $icons 37 | ->filter(fn (string $item) => Str::contains($item, $value, true)) 38 | ->values() 39 | ->all(); 40 | }, 41 | placeholder: 'file-content-list', 42 | scroll: 10, 43 | required: true 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operations/UpdateRole.php: -------------------------------------------------------------------------------- 1 | role = Arr::get($config, 'role'); 21 | $this->permissions = Arr::get($config, 'permissions'); 22 | } 23 | 24 | public function run(): Installable 25 | { 26 | $roles = Yaml::parseFile(base_path('resources/users/roles.yaml')); 27 | 28 | $existingPermissions = Arr::get($roles, "$this->role.permissions"); 29 | $permissions = array_merge($existingPermissions, str_replace('{{ handle }}', $this->installable->renameHandle, $this->permissions)); 30 | 31 | Arr::set($roles, "$this->role.permissions", $permissions); 32 | 33 | File::put(base_path('resources/users/roles.yaml'), Yaml::dump($roles, 99, 2)); 34 | 35 | note("Permissions updated for '{$this->role}' role."); 36 | 37 | return $this->installable; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | registerPublishableStubs(); 31 | } 32 | 33 | protected function registerPublishableStubs(): void 34 | { 35 | $this->publishes([ 36 | __DIR__.'/../resources/stubs' => resource_path('stubs/vendor/statamic-peak-commands'), 37 | ], 'statamic-peak-commands-stubs'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Updates/UpdateJSONldDateFormatting.php: -------------------------------------------------------------------------------- 1 | isUpdatingTo('4.4.0'); 14 | } 15 | 16 | public function update() 17 | { 18 | $disk = Storage::build([ 19 | 'driver' => 'local', 20 | 'root' => resource_path('/views'), 21 | ]); 22 | 23 | collect($disk->allFiles()) 24 | ->filter(function($file) use ($disk) { 25 | return Str::contains($disk->get($file), 'format="Y-m-d\TH:i:s"'); 26 | }) 27 | ->each(function ($file) use ($disk) { 28 | $contents = Str::of($disk->get($file)) 29 | ->replace('format="Y-m-d\TH:i:s"', "| format('c')"); 30 | 31 | $disk->put($file, $contents); 32 | 33 | $this->console()->info("Replaced `format=\"Y-m-d\TH:i:s\"` with `| format('c')` in `$file`."); 34 | } 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Updates/UpdateRSSFeed.php: -------------------------------------------------------------------------------- 1 | isUpdatingTo('4.3.0'); 14 | } 15 | 16 | public function update() 17 | { 18 | $view = base_path("resources/views/feed/feed.antlers.xml"); 19 | 20 | if (File::exists($view)) { 21 | $contents = Str::of(File::get($view)) 22 | ->replace('{{ now iso_format="ddd, DD MMM GGGG HH:mm:ss UT" }}', "{{ now | format('r') }}") 23 | ->replace('{{ date iso_format="ddd, DD MMM GGGG hh:mm:ss UT" }}', "{{ date | format('r') }}") 24 | ->replace("{{ glide:image preset='lg' }}", '{{ glide:image width="1200" height="900" fit="crop_focal" }}'); 25 | 26 | File::put($view, $contents); 27 | 28 | $this->console()->info('Use proper ISO formatting for dates, and crop image in your RSS feed template.'); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/Operations/OperationTest.php: -------------------------------------------------------------------------------- 1 | 'copy', 14 | 'input' => '_call_to_action.antlers.html', 15 | 'output' => 'resources/views/page_builder/_call_to_action.antlers.html', 16 | ]; 17 | 18 | $expected = app(\Studio1902\PeakCommands\Operations\Copy::class, ['config' => $config]); 19 | 20 | $this->assertEquals($expected, Registry::resolveOperation('copy', $config)); 21 | $this->assertEquals($expected, Registry::resolveOperation('\Studio1902\PeakCommands\Operations\Copy', $config)); 22 | $this->assertEquals($expected, Registry::resolveOperation(\Studio1902\PeakCommands\Operations\Copy::class, $config)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 |