Skip to content

Commit

Permalink
Merge pull request #5 from RareFormLabs/pull
Browse files Browse the repository at this point in the history
Add `pull` tag functionality
  • Loading branch information
chasegiunta authored Feb 22, 2025
2 parents 6d53dfc + 5b88744 commit ad2453a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
/bootstrap.php
/craft
/composer.lock
/.vscode
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release Notes for Inertia

## 1.0.0-beta.1 - 2025-02-22

- Add `pull` tag DX helper for sharing variables across templates.

## 1.0.0-alpha.5 - 2025-02-01

- Fix console error
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You can install this plugin from the Plugin Store or with Composer.
Go to the Plugin Store in your project’s Control Panel and search for “Inertia”. Then press “Install”.

#### With Composer:

Open your terminal and run the following commands:

```sh
Expand All @@ -34,7 +35,9 @@ Be sure to follow the installation instructions for the [client-side framework](
> Upon installing, the Inertia adapter will takeover all routing and expect all templates to respond with inertia protocol responses. To prevent this, you may set the `takeoverRouting` [config option](#configuration) to `false`
> [!IMPORTANT]
>
> ## Required Reading
>
> The [Inertia documentation](https://inertiajs.com) is a must-read to understand the protocol, the responsibilities of this adapter, and how to use Inertia on the client-side. The following sections will explain how to use this adapter, but assume you have a basic understanding of Inertia.
## Defining Pages
Expand Down Expand Up @@ -70,7 +73,9 @@ Create a `_shared` directory at the root of your `/templates` directory, and use
csrfTokenName: craft.app.config.general.csrfTokenName
}) }}
```

This allows more flexibility for designating responses you may want to cache to reduce unnecessary repetitive queries.

```twig
{# templates/_shared/current-user.twig #}
Expand All @@ -88,6 +93,24 @@ This allows more flexibility for designating responses you may want to cache to
{% endif %}
```

## Pull in Variables

Use the `pull` tag to include variables from a specified template and make them available in the current response twig file.

```twig
{# teams/_base.twig #}
{% set teamColor = "#EE4B2B" %}
```

```twig
{# templates/teams/_entry.twig #}
{% pull('teams/_base') %}
{{ inertia('Teams/Entry', { teamColor: teamColor }) }}
```

This is a simple DX alternative to using `extends` and `block` tags to share variables across templates. Note that the `pull` tag is only available in Inertia responses.

## Saving Data

Craft CMS does not use traditional POST, PUT, PATCH, and DELETE requests for saving data, and instead uses the `action` parameter to hit various internal Craft controllers. This means saving data to Craft CMS data is a little different than what is expected in a traditional Inertia application.
Expand Down Expand Up @@ -178,4 +201,3 @@ return [
'takeoverRouting' => true,
];
```

52 changes: 51 additions & 1 deletion src/controllers/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ public function actionIndex(): array|string
}

try {
$stringResponse = Craft::$app->getView()->renderTemplate($template, $templateVariables);
// Process any pulls in the template first
$processedTemplate = $this->processTemplatePulls($template);

// Render the processed template
$stringResponse = Craft::$app->getView()->renderString($processedTemplate, $templateVariables);
} catch (\Twig\Error\RuntimeError $e) {
$sourceContext = $e->getSourceContext();
$templateFile = $sourceContext ? $sourceContext->getName() : 'unknown template';
Expand Down Expand Up @@ -360,4 +364,50 @@ private function getSharedPropsFromTemplates()
return $allSharedProps;
}

/**
* Process any template pull tags in the template
*/
private function processTemplatePulls(string $template): string
{
$view = Craft::$app->getView();

// Store original template mode and switch to site mode
$originalMode = $view->getTemplateMode();
$view->setTemplateMode($view::TEMPLATE_MODE_SITE);

try {
// Find the actual template file
$templatePath = $view->resolveTemplate($template);
if (!$templatePath) {
throw new \Exception("Template not found: {$template}");
}

// Read the template contents
$templateContent = file_get_contents($templatePath);

// This pattern will match {% pull('path') %}
$pattern = '/\{%\s*pull\s*\(\s*([^\)]+)\s*\)\s*%\}/';

$processedContent = preg_replace_callback($pattern, function($matches) use ($view) {
$pullPath = trim($matches[1]);

$directPath = trim($pullPath, "'\"");
$referencedPath = $view->resolveTemplate($directPath);

if (!$referencedPath) {
Craft::warning("Template not found: {$pullPath}", __METHOD__);
return ''; // Or handle the error as needed
}

return file_get_contents($referencedPath);
}, $templateContent);

return $processedContent;

} finally {
// Restore original template mode
$view->setTemplateMode($originalMode);
}
}

}

0 comments on commit ad2453a

Please sign in to comment.