### Install Craft Cloud Extension with Composer
Source: https://craftcms.com/docs/cloud/extension
Alternatively, install the craftcms/cloud package directly using Composer. After installation, run the setup command to configure the extension.
```bash
composer require craftcms/cloud
php craft cloud/setup
```
--------------------------------
### Install Package and Discover Packages
Source: https://craftcms.com/docs/6.x/extend/local-dev
Use these commands to install a new package and then ask Laravel to discover it, especially if the host project lacks recommended scripts.
```bash
ddev composer require myorg/activity-plugin
# New: Ask Laravel to
ddev artisan package:discover
```
--------------------------------
### Example Preview Domain
Source: https://craftcms.com/docs/cloud/domains
This is an example of a preview domain format for a Craft Cloud environment. Preview domains are automatically generated and end with 'preview.craft.cloud'.
```text
project-my-handle-environment-b62dec18.preview.craft.cloud
```
--------------------------------
### Install a Craft CMS Plugin
Source: https://craftcms.com/docs/6.x/extend/local-dev
Use this command to install a plugin via the Craft CMS console. Legacy options are also provided.
```bash
ddev artisan craft:plugin:install
# ...or either of these legacy options:
ddev php craft plugin:install
ddev php craft plugin/install
```
--------------------------------
### Launch Craft CMS Project
Source: https://craftcms.com/docs/getting-started-tutorial/install
Open your installed Craft CMS project in a web browser using DDEV.
```bash
ddev launch
```
--------------------------------
### Run the 'whoami' command
Source: https://craftcms.com/docs/getting-started-tutorial/environment/terminal
Executes the 'whoami' command to display your current username. The line starting with '#' shows an example of the expected output.
```bash
whoami
# -> oli
```
--------------------------------
### Install http-message-sig for Node.js
Source: https://craftcms.com/docs/cloud/request-signing
Install the http-message-sig package to generate RFC 9421-compliant signatures.
```bash
npm install http-message-sig
```
--------------------------------
### Install Craft Cloud Extension
Source: https://craftcms.com/docs/cloud/extension
Install the Craft Cloud extension using the provided command. This command is available for Craft CMS 4.5.10 and later.
```bash
php craft setup/cloud
```
--------------------------------
### Require the Adapter Package
Source: https://craftcms.com/docs/6.x/extend/adapter.html
Install the adapter package using Composer to begin porting your plugin or compatibility release.
```bash
composer require craftcms/yii2-adapter
```
--------------------------------
### Create a New Table
Source: https://craftcms.com/docs/6.x/extend/migrations.html
Example of using the `Schema` facade and `Blueprint` builder to create a new database table with an ID, name, and handle column.
```php
// Create a new table:
Schema::create('my_table', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('handle');
});
```
--------------------------------
### Set up a New Craft Project for Cloud
Source: https://craftcms.com/docs/cloud/getting-started
Run this command to install the necessary Craft Cloud extension and configuration for new sites. The project will continue to function locally.
```bash
ddev craft setup/cloud
```
--------------------------------
### Install CKEditor Plugin via Command Line
Source: https://craftcms.com/docs/getting-started-tutorial/configure/resources
After adding the package, install the CKEditor plugin using the Craft CMS console command. This is also run within the DDEV environment.
```bash
ddev php craft plugin/install ckeditor
```
--------------------------------
### Define Front-End Routes with Controllers
Source: https://craftcms.com/docs/6.x/extend/http.html
Example of a `web.php` file for defining front-end routes. This maps a POST request to a specific controller.
```php
use MyOrg\Activity\Http\Controllers\TrackEvent;
use Illuminate\Support\Facades\Route;
Route::post('activity/track', TrackEvent::class);
```
--------------------------------
### Vite Server Configuration for DDEV
Source: https://craftcms.com/docs/6.x/extend/assets
Example Vite server configuration for DDEV environments, specifying host, origin, port, and CORS settings to ensure compatibility with the development setup.
```javascript
// ...
const host = '0.0.0.0';
const port = 3000;
const origin = `${process.env.DDEV_PRIMARY_URL}:${port}`;
export default defineConfig({
server: {
host,
origin,
port,
cors: {
// Live dangerously...
origin: true,
// ...or permit only DDEV origins.
// See: https://dev.to/mandrasch/vite-is-suddenly-not-working-anymore-due-to-cors-error-ddev-3673
// origin: /https?:\/([A-Za-z0-9\-\.]+)?(\.ddev.site)(?::\d+)?$/,
},
},
// ...
});
```
--------------------------------
### Creating a Facade for a Service in Craft 6.x
Source: https://craftcms.com/docs/6.x/extend/services.html
Provides an example of creating a facade for a service in Craft 6.x. Facades offer a static-like interface to services, simplifying their access throughout the application.
```php
namespace MyOrg\Activity\Facades;
use Illuminate\Support\Facades\Facade;
class Reports extends Facade
{
#[\]Override]
protected static function getFacadeAccessor(): string
{
return \MyOrg\Activity\Reporting\Manager::class;
}
}
# -> Reports::generate(...)
```
--------------------------------
### Navigate directories
Source: https://craftcms.com/docs/getting-started-tutorial/environment/terminal
Use 'cd' followed by a path to change the working directory. Examples include moving up a directory ('cd ..'), navigating to the root, a specific path, or the home directory.
```bash
cd ..
pwd
cd /Applications
pwd
cd ~/Desktop
pwd
cd ~
pwd
```
```powershell
cd ..
cd
cd C:\Windows
cd
cd %HOMEPATH%/Desktop
cd
cd %HOMEPATH%
cd
```
--------------------------------
### GraphQL Query Response Example
Source: https://craftcms.com/docs/getting-started-tutorial/more/graphql.html
This is a sample JSON response for the GraphQL query above, showing the structure and data returned for a blog entry and site description.
```json
{
"data": {
"entry": {
"title": "My Trip to Bend",
"postDate": "15 Oct 2024",
"postDateAlt": "2024-10-15",
"url": "https://tutorial.ddev.site/blog/my-trip-to-bend",
"featureImage": [
{
"title": "Highway 26",
"url": "https://tutorial.ddev.site/uploads/images/highway-26.JPG",
"sized": "https://tutorial.ddev.site/uploads/_900x600_crop_center-center_90_none/5/highway-26.jpg"
}
],
"postContent": [
{
"typeHandle": "text",
"text": "Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Curabitur blandit tempus porttitor. Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas sed diam eget risus varius blandit sit amet non magna. Nullam quis risus eget urna mollis ornare vel eu leo."
},
{
"typeHandle": "image",
"image": [
{
"title": "Warm Springs",
"url": "https://tutorial.ddev.site/uploads/images/warm-springs.JPG"
}
]
},
{
"typeHandle": "text",
"text": "Vestibulum id ligula porta felis euismod semper. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Nullam quis risus eget urna mollis ornare vel eu leo.\n\nCras mattis consectetur purus sit amet fermentum. Vestibulum id ligula porta felis euismod semper. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit."
}
],
"postCategories": [
{
"title": "Trips",
"url": "https://tutorial.ddev.site/blog/topic/trips"
},
{
"title": "Oregon",
"url": "https://tutorial.ddev.site/blog/topic/oregon"
}
]
},
"globalSet": {
"description": "
Photos and stories from around the Pacific Northwest.
\n"
}
}
}
```
--------------------------------
### Using a Facade to Fork a Template
Source: https://craftcms.com/docs/6.x/extend/services.html
This example shows how to use a facade (`Reports`) to call a method that likely involves dependency injection for its arguments, such as `$template` and `$currentUser`.
```php
Reports::fork($template, $currentUser);
```
--------------------------------
### Run Upgrade Tool in Docker
Source: https://craftcms.com/docs/6.x/upgrade.html
If composer packages cannot be installed directly, mount your project into a Docker container to run the upgrade tool commands.
```bash
# On the host machine...
docker run --interactive --tty --volume $PWD:/app composer bash
# ...in the container:
-> 42dae745a6ab:/app# composer global require craftcms/craft6-revamp
-> ...
-> 42dae745a6ab:/app# composer global exec craft6-revamp
```
--------------------------------
### Extract Project ID from URL
Source: https://craftcms.com/docs/cloud/billing
This example shows how to identify a project's ID from its URL in Craft Console for support inquiries.
```text
/accounts/{org-name}/cloud/projects/{project-id}
```
--------------------------------
### Twig Syntax Example
Source: https://craftcms.com/docs/getting-started-tutorial/build/twig.html
This snippet demonstrates fundamental Twig syntax, including comments, variable output, setting variables, loops, and filters. It's useful for understanding basic Twig structure and functionality.
```twig
{# This is a comment in Twig! It won’t appear in the HTML output. #}
{# Here’s some text, dynamically inserted into an HTML tag: #}
{{ siteName }}
{# What about a dynamic value? #}
Today is {{ now | date }}!
{# This is a variable, and it’s being set to a list (or “array”) of colors: #}
{% set colors = ['red', 'green', 'blue'] %}
{# How many colors are in the list? #}
The following list contains {{ colors | length }} color(s).
{# This is a loop that outputs those items, sorted alphabetically: #}
{% for color in colors | sort %}
{# Let’s stylize each item using some inline CSS: #}
-
{# The color is capitalized for display: #}
{{ color | title }}
{% endfor %}
```
--------------------------------
### Require craftcms/yii2-adapter
Source: https://craftcms.com/docs/6.x/extend/upgrade
Install the Yii2 adapter package using Composer. This is a required step for plugins to initialize properly in a Laravel project with Craft 6.x.
```bash
composer require craftcms/yii2-adapter
```
--------------------------------
### Craft CMS Project File Structure
Source: https://craftcms.com/docs/getting-started-tutorial/install/files
Displays the default directory and file layout for a new Craft CMS installation. This structure should be maintained throughout the tutorial.
```bash
craft
├── .ddev
├── config
├── storage
├── templates
├── vendor
├── web
├── .env
├── .env.example.dev
├── .env.example.production
├── .env.example.staging
├── .gitignore
├── bootstrap.php
├── composer.json
├── composer.lock
└── craft
```
--------------------------------
### Default Cache Rule Example
Source: https://craftcms.com/docs/cloud/static-caching
Represent the default caching behavior with a catch-all rule that excludes specific UTM parameters from the cache key for the homepage.
```yaml
php-version: 8.5
cache:
rules:
- pattern: "/*?"
query-string:
mode: exclude
keys:
- utm_source
- utm_medium
- utm_campaign
- # ...
```
--------------------------------
### Binding Closure Listeners in bootPlugin()
Source: https://craftcms.com/docs/6.x/extend/events
Closures must be bound in your plugin’s `bootPlugin()` method. This example shows how to listen for a `RegisterFilesystemTypes` event and push a new filesystem type.
```php
use CraftCms\Cms\Filesystem\Events\RegisterFilesystemTypes;
use MyVendor\MyPlugin\Filesystems\Dropbox
// ...
public function bootPlugin(): void
{
// Closures must be bound in your plugin’s bootPlugin() method, as PHP doesn’t support them as static class properties!
Event::listen(function(RegisterFilesystemTypes $event): void {
$event->types->push(Dropbox::class)
});
}
```
--------------------------------
### Get Temporary Paths in Craft Cloud
Source: https://craftcms.com/docs/cloud/plugin-development
Use Craft's Path service to get temporary, storage, and cache directory paths. Avoid hard-coding or dynamically constructing these paths.
```php
$path = Craft::$app->getPath();
$tmp = $path->getTempPath();
$storage = $path->getStoragePath();
$cache = $path->getCachePath();
// ...
```
--------------------------------
### Enable Headless Mode in Craft CMS
Source: https://craftcms.com/docs/getting-started-tutorial/more/graphql.html
Add this configuration to `config/general.php` to enable headless mode. This optimizes the installation for content delivery and hides template settings.
```php
headlessMode(true)
;
```
--------------------------------
### Get the current working directory
Source: https://craftcms.com/docs/getting-started-tutorial/environment/terminal
Use 'pwd' on macOS/Linux or 'cd' on Windows to determine your current working directory.
```bash
pwd
```
```powershell
cd
```
--------------------------------
### Twig Function Example
Source: https://craftcms.com/docs/getting-started-tutorial/build/twig.html
Illustrates the use of a Twig function, such as `getenv`, which is responsible for fetching or generating a value. Functions often do not require input, unlike filters.
```twig
getenv('ENV_VAR_NAME')
```
--------------------------------
### Accessing and Displaying Overridden Settings
Source: https://craftcms.com/docs/6.x/extend/config
Retrieve all configuration overrides for a plugin and use this information to conditionally render form fields. This example shows how to identify overridden settings and display them as read-only.
```php
#[\Override]
protected function settingsHtml(): string
{
// Get the whole static config array (so `nulls` are significant):
$overrides = config(sprintf('craft.%s', $this->handle));
return template('plugin-handle/_settings', [
'settings' => $this->getSettings(),
'overrides' => array_keys($overrides),
]);
}
```
```twig
{% set mySettingOverridden = 'mySetting' in overrides %}
{{ forms.textField({
id: 'mySetting',
label: 'My Setting'|t('plugin-handle'),
static: mySettingOverridden,
readonly: mySettingOverridden,
warning: mySettingOverridden ? 'This setting is being overridden by `{name}` in `{file}`.'|t('plugin-handle', { name: 'mySetting', file: 'config/craft/my-plugin.php' }),
}) }}
```
--------------------------------
### Basic Vite Configuration
Source: https://craftcms.com/docs/6.x/extend/assets
A minimal `vite.config.js` setup for a Craft CMS plugin, matching the input and output paths defined in the plugin's PHP configuration.
```javascript
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/js/plugin.js',
'resources/css/plugin.css'
],
publicDirectory: 'resources/dist',
}),
],
});
```
--------------------------------
### Headless CMS: craft-cloud.yaml with 'noop' npm-script
Source: https://craftcms.com/docs/cloud/config
Updates `craft-cloud.yaml` to use the 'noop' npm script, disabling the build process for headless or decoupled front-end setups.
```yaml
# ...
npm-script: 'noop'
```
--------------------------------
### Gather data before rendering a template with Laravel routes
Source: https://craftcms.com/docs/6.x/upgrade.html
This Laravel route example demonstrates how to gather data before rendering a template, serving as an alternative to `Route::view()`. It uses a closure to process the request and pass data to the `pageTemplate` helper.
```php
use Illuminate\Http\Request;
use function CraftCms\Cms\pageTemplate;
Route::get('newsletter', function (Request $request) {
return pageTemplate('_forms/newsletter', [
'source' => $request->input('campaign_id', 'internal'),
]);
});
```
--------------------------------
### Create and Navigate to Project Folder
Source: https://craftcms.com/docs/getting-started-tutorial/install
Use these commands to create a new directory for your project and change into it.
```bash
cd /path/to/dev/folder
mkdir tutorial
cd tutorial
```
--------------------------------
### Install Craft CMS 6 Upgrade Tool
Source: https://craftcms.com/docs/6.x/upgrade.html
Install the global composer package for the Craft 6 revamp tool. This tool helps automate the upgrade process.
```bash
composer global install craftcms/craft6-revamp
```
--------------------------------
### Get Build Artifact URL
Source: https://craftcms.com/docs/cloud/builds
Use `craft\cloud\Helper::artifactUrl()` to get the build-specific URL for an artifact. This is useful when needing to access manifest files or other build outputs from the CDN.
```php
craft\cloud\Helper::artifactUrl('path/to/manifest.json')
```
--------------------------------
### Implement Custom Filesystem Class
Source: https://craftcms.com/docs/6.x/extend/disks
Extend the base Filesystem class and implement `getDiskConfig()` to define disk configuration for custom storage adapters like Backblaze B2. Ensure all required credentials and settings are parsed from environment variables.
```php
use CraftCms\Cms\Filesystem\Filesystems\Filesystem;
use CraftCms\Cms\Support\Env;
class Backblaze extends Filesystem
{
// ...
public function getDiskConfig(): array
{
return [
'driver' => 'b2',
'bucketId' => Env::parse($this->bucketId),
'bucketName' => Env::parse($this->bucketName),
'accountId' => Env::parse($this->accountId),
'applicationKey' => Env::parse($this->applicationKey),
'url' => Env::parse($this->url),
// ...
]
}
}
```
--------------------------------
### Accessing Project Config via Facade
Source: https://craftcms.com/docs/6.x/extend/services.html
This demonstrates accessing the `ProjectConfig` service using its provided facade. Facades offer a convenient, static-like interface to services managed by the application container.
```php
CraftCms\Cms\Support\Facades\ProjectConfig::get('graphql.enabled')
```
--------------------------------
### Check DDEV Version
Source: https://craftcms.com/docs/getting-started-tutorial/environment/stack
Use this command to verify your installed DDEV version. Ensure you are running DDEV 1.23.4 or later.
```bash
ddev -v
# -> ddev version v1.23.4
```
--------------------------------
### Render a Template with `template()` Helper
Source: https://craftcms.com/docs/6.x/extend/templates.html
Use the `template()` helper for most situations to render a template. Pass the template path and an array of variables.
```php
return template('my-plugin/_settings', [
'settings' => $this->getSettings(),
]);
```
--------------------------------
### Basic GraphQL Ping Query
Source: https://craftcms.com/docs/getting-started-tutorial/more/graphql.html
Run this query in the GraphiQL explorer to verify your GraphQL setup. It should return 'pong' if the connection is successful.
```graphql
{ ping }
```
--------------------------------
### Redirecting with Flash Messages
Source: https://craftcms.com/docs/6.x/extend/session
Example of redirecting back to the previous page and flashing an error message, along with additional serializable data, to the session.
```php
return back()
->with('error', t('This is already on your favorites list!'))
->with([
'favorite' => CraftCms\Cms\Support\Arr::toArray($favorite),
]);
```
--------------------------------
### Use Facade to Track Events
Source: https://craftcms.com/docs/6.x/extend/helpers.html
Once a facade is defined, it can be used as a shortcut to access the underlying service's methods. This provides a cleaner syntax compared to directly accessing the service container.
```php
use MyOrg\Activity\Support\Events;
Events::track('pageView', ['elementId' => $entry->id]);
// This still works:
app(\MyOrg\Activity\Reporting\Manager::class)->track(
'pageView',
['elementId' => $entry->id],
);
```
--------------------------------
### List directory contents
Source: https://craftcms.com/docs/getting-started-tutorial/environment/terminal
Use 'ls' on macOS/Linux or 'dir' on Windows to view the files and folders in the current directory.
```bash
ls
```
```powershell
dir
```
--------------------------------
### Drop Table Prefix for Existing Projects
Source: https://craftcms.com/docs/cloud/getting-started
If your project uses the `tablePrefix` setting or `CRAFT_DB_TABLE_PREFIX` config variable, run this command before proceeding with Cloud setup.
```bash
ddev craft db/drop-table-prefix
```
--------------------------------
### Install CKEditor Plugin via Composer
Source: https://craftcms.com/docs/getting-started-tutorial/configure/resources
Use Composer to add the Craft CMS CKEditor plugin to your project. This command is run within the DDEV environment.
```bash
ddev composer require craftcms/ckeditor -w
```
--------------------------------
### Create a Static CSS File
Source: https://craftcms.com/docs/getting-started-tutorial/build/routing.html
Add a simple CSS file to the web root. This file will be served directly by the web server without involving Craft CMS.
```css
/* Hello, world! */
```
--------------------------------
### Register Callback for App Booted Event
Source: https://craftcms.com/docs/6.x/extend/avenues.html
Use this hook to be notified when the application has fully booted, including all plugins. This replaces the legacy EVENT_AFTER_LOAD_PLUGINS event.
```php
app()->booted($callback);
```
--------------------------------
### Import Plaintext Postgres Backup to Craft Cloud
Source: https://craftcms.com/docs/cloud/databases
Import a plaintext format Postgres backup using the psql command. The --password flag prompts for the password.
```bash
psql \
--host="{hostname}" \
--username="{username}" \
--dbname "{database}" \
--password \
< path/to/backup.sql
```
--------------------------------
### Retrieve GET/POST Data in Twig
Source: https://craftcms.com/docs/6.x/upgrade.html
Use `app('request').get('paramName')` to retrieve data from a GET query string or POST body, replacing `craft.app.request.getQueryParam()`.
```twig
app('request').get('paramName')
```
--------------------------------
### Accessing Services in Craft 2.x and 3.x-5.x
Source: https://craftcms.com/docs/6.x/extend/services.html
Illustrates the historical methods for accessing services in older versions of Craft CMS. Craft 2.x used a global access method, while Craft 3.x-5.x utilized plugin instances.
```php
# Craft 2.x — instances available via Craft:
craft()->activityPlugin_reportsService->generate(...);
# Craft 3.x–5.x — singletons available via plugin:
Activity::getInstance()->getReports()->generate(...);
```
--------------------------------
### Displaying Old Input Values in Twig
Source: https://craftcms.com/docs/6.x/extend/session
This example shows how to repopulate form fields with previously submitted values using the `old()` function, which is useful after validation errors.
```twig
{{ input('text', 'name', old('title')) }}
```
--------------------------------
### Create Project Directory
Source: https://craftcms.com/docs/6.x/install.html
Use this command to create a new directory for your Craft CMS project and navigate into it.
```bash
mkdir my-craft-project
cd my-craft-project/
```
--------------------------------
### Accessing Artifact Base URL in Node.js
Source: https://craftcms.com/docs/cloud/builds
Access the `CRAFT_CLOUD_ARTIFACT_BASE_URL` environment variable in Node.js to get the base URL for build artifacts. This variable is not available in browser environments.
```javascript
process.env.CRAFT_CLOUD_ARTIFACT_BASE_URL
```
--------------------------------
### Accessing Project Config via Application Container
Source: https://craftcms.com/docs/6.x/extend/services.html
When not in a DI-capable context, services like `ProjectConfig` can be accessed using the `app()` helper function, which retrieves the service from the application container.
```php
app(\CraftCms\Cms\ProjectConfig\ProjectConfig)->get('graphql.enabled');
```
--------------------------------
### List Routes with Middleware Details
Source: https://craftcms.com/docs/6.x/extend/http.html
Use the `route:list` Artisan command to view route configurations, including middleware groups. The `-v` flag shows middleware groups, and `-vv` lists all applied middleware classes.
```bash
# -v displays middleware groups for each route.
# -vv lists *every middleware class* that will apply to each route.
ddev artisan route:list --path=some-path-segment -v
```
--------------------------------
### Registering a Dashboard Widget using HasWidgets Trait
Source: https://craftcms.com/docs/6.x/extend/avenues.html
Example of how to add a custom dashboard widget by defining the $widgets property in your main plugin class, utilizing the HasWidgets trait.
```php
use CraftCms\Cms\Plugin\Plugin;
use MyOrg\MyPlugin\Widgets\RandomQuoteWidget;
class InspirationPlugin extends Plugin
{
// ...
protected array $widgets = [
RandomQuoteWidget::class,
];
}
```
--------------------------------
### Registering Recurring Tasks with the Scheduler
Source: https://craftcms.com/docs/6.x/extend/scheduling.html
Implement the `schedule()` method in your plugin's base class to define recurring tasks. This example shows how to schedule a command, a job, and a closure.
```php
protected function schedule(Schedule $schedule): void
{
// Send a test email every day:
$schedule->command('craft:mailer:test')
->daily();
// Queue a report at the top of every hour:
$schedule->job(new GenerateReport(['templateId' => 1234]))
->hourly();
// Report
$schedule->call(function () {
Log::info('Scheduler healthy!');
})
->everyTenMinutes()
->thenPing(env('UPTIME_KUMA_SERVICE_URL'));
}
```
--------------------------------
### Import MySQL Backup to Craft Cloud
Source: https://craftcms.com/docs/cloud/databases
Use this command to import MySQL backups from Craft or Cloud. Ensure your mysql client version matches the dump's creation version.
```bash
mysql \
--host={cloud-db-hostname} \
--port=3306 \
--user={username} \
--password={password} \
--database={database} \
< path/to/backup.sql
```
--------------------------------
### Query Blog Entry and Site Info with GraphQL
Source: https://craftcms.com/docs/getting-started-tutorial/more/graphql.html
Use this GraphQL query to fetch a specific blog entry by its slug and retrieve site information. It demonstrates date formatting, accessing nested assets and content blocks, and applying Markdown to rich text fields.
```graphql
{
entry(slug: "my-trip-to-bend") {
title
postDate @formatDateTime(format: "d M Y")
postDateAlt: postDate @formatDateTime(format: "Y-m-d")
url
... on post_Entry {
featureImage {
title
url
sized: url @transform(width: 900, height: 600, quality: 90)
}
postContent {
... on text_Entry {
typeHandle
text
}
... on image_Entry {
typeHandle
image {
title
url
}
}
}
postCategories {
title
url
}
}
}
globalSet(handle: ["siteInfo"]) {
... on siteInfo_GlobalSet {
description @markdown
}
}
}
```
--------------------------------
### Validation with Middleware
Source: https://craftcms.com/docs/6.x/extend/validation.html
Implement validation logic within middleware to protect routes or process incoming data before it reaches the controller. This example uses a custom `SharingTokenRule` to validate a 'share' token.
```php
use Illuminate\Http\Request;
use Illuminate\Support\Closure;
use Symfony\Component\HttpFoundation\Response;
class HandleShareRequest
{
public function handle(Request $request, Closure $next): Response
{
$shareToken = $request->string('share');
if (! $shareToken) {
return $next($request);
}
$validator = new SharingTokenRule(minAge: 'P1W');
abort_unless($validator->validate($shareToken), t('The provided sharing token is not valid.', category: 'activity'));
return $next($request);
}
}
```