okay i have a form to save a yaml file to my themes directory with order information in it. the form saves the file into my themes directory at /user/themes/sr/data/orders/{{ grav.user.username }}.yaml
that is working using a plugin i created called ordersaver. i do not for the life of me can figure out how to display the order information from that yaml file in a twig template called orders. I can get the twig template called orders to show the contents if the orders are in the page frontmatter page.header.orders
of the page .md file but does NOT showing from the themes .yaml file i mentioned earlier. I will post my code below the plugin .php file and the order-form for submitting the order data in pages frontmatter and finnally the template twig file for rendering the order data. i have done plenty of troubleshooting and am able to get the resloved path to show correctly my twig template is finding the .yaml file in my themes folder but will not render the darn contents of the file. another thing is that all orders will be placed in this themes folder and the twig template will loop through finding orders with the logged in users name to know which details to display from the file.
odersaver.php
<?php
namespace Grav\Plugin;
use Composer\Autoload\ClassLoader;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use Grav\Common\Page\Page;
use Grav\Common\Plugin;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\File\YamlFile;
use Symfony\Component\Yaml\Yaml;
class OrdersaverPlugin extends Plugin
{
public static function getSubscribedEvents(): array
{
return [
// For general plugin initialization
'onPluginsInitialized' => [
// Uncomment next line if needed for Grav < 1.7
// ['autoload', 100000],
['onPluginsInitialized', 0]
],
// For form processing logic
'onFormProcessed' => ['onFormProcessed', 0]
];
}
/**
* Optional: Composer autoload
*/
public function autoload(): ClassLoader
{
return require __DIR__ . '/vendor/autoload.php';
}
public function onPluginsInitialized(): void
{
// Skip execution in the admin panel
if ($this->isAdmin()) {
return;
}
// Enable any future front-end events if needed
$this->enable([
// Future front-end events can go here
]);
}
/**
* Custom form action handler to append order data to a single YAML file
*/
public function onFormProcessed(Event $event): void
{
$action = $event['action'];
$form = $event['form'];
if ($action !== 'saveOrderToThemeYaml') {
return;
}
$user = $this->grav['user'];
if (!$user || !$user->authenticated) {
return;
}
$username = $user->username;
$data = $form->getData()->toArray();
$data['user'] = $username;
$data['date'] = date('Y-m-d');
$data['orderid'] = uniqid();
$theme = $this->config->get('system.pages.theme');
$file = GRAV_ROOT . "/user/themes/{$theme}/data/orders/{$username}.yaml";
$existing = [];
if (file_exists($file)) {
$existing = Yaml::parse(file_get_contents($file)) ?? [];
}
$existing[] = $data;
file_put_contents($file, Yaml::dump($existing, 10, 2));
}
}
order-form
---
title: 'Place Order'
form:
name: order
fields:
-
type: section
title: 'Shipping Address'
underline: true
-
name: shipping_address.name
type: text
label: 'Recipient Name'
-
name: shipping_address.phone
type: text
label: 'Phone Number'
-
name: shipping_address.street
type: text
label: 'Street Address'
-
name: shipping_address.city
type: text
label: City
-
name: shipping_address.state
type: text
label: State
-
name: shipping_address.postal_code
type: text
label: 'Postal Code'
-
name: shipping_address.country
type: text
label: Country
-
type: section
title: 'Order Details'
underline: true
-
name: total_amount
type: number
label: 'Total Amount'
-
name: currency
type: text
label: Currency
default: USD
-
name: payment_method
type: text
label: 'Payment Method'
default: Stripe
-
name: tracking_number
type: text
label: 'Tracking Number'
-
name: notes
type: textarea
label: Notes
buttons:
-
type: submit
value: Send
process:
-
saveOrderToThemeYaml: true
-
message: 'Order submitted!'
-
redirect: /orders
twig_first: true
never_cache_twig: true
cache_enable: false
visible: true
---
twig template
{% extends 'partials/base.html.twig' %}
{% block content %}
<section class="section">
<div class="container">
<h1 class="title">My Orders</h1>
{% set user_orders = [] %}
{# Load orders from the theme directory #}
{% set order_data = yaml('theme://data/orders/' ~ grav.user.username ~ '.yaml') %}
{% for order in order_data %}
{% if order.user == grav.user.username %}
{% set user_orders = user_orders|merge([order]) %}
{% endif %}
{% endfor %}
{% if user_orders|length > 0 %}
{% for order in user_orders %}
<div class="box mb-5">
<h2 class="subtitle">Order #{{ order.orderid }}</h2>
<p><strong>Status:</strong> {{ order.status }}</p>
<p><strong>Date:</strong> {{ order.date }}</p>
<p><strong>Total:</strong> {{ order.total_amount }} {{ order.currency }}</p>
<p><strong>Payment Method:</strong> {{ order.payment_method }}</p>
<p><strong>Tracking Number:</strong> {{ order.tracking_number }}</p>
<h3 class="subtitle is-6 mt-4">Shipping Address</h3>
<ul>
<li>{{ order.shipping_address.name }}</li>
<li>{{ order.shipping_address.street }}</li>
<li>{{ order.shipping_address.city }}, {{ order.shipping_address.state }} {{ order.shipping_address.postal_code }}</li>
<li>{{ order.shipping_address.country }}</li>
<li>Phone: {{ order.shipping_address.phone }}</li>
</ul>
{% if order.notes %}
<p class="mt-3"><strong>Notes:</strong> {{ order.notes }}</p>
{% endif %}
<h3 class="subtitle is-6 mt-4">Items</h3>
<table class="table is-fullwidth is-bordered is-striped">
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>SKU</th>
<th>Price</th>
<th>Qty</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
{% for item in order.items %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.category }}</td>
<td>{{ item.sku }}</td>
<td>{{ item.price }}</td>
<td>{{ item.quantity }}</td>
<td>{{ (item.price * item.quantity)|number_format(2, '.', '') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
{% else %}
<p class="has-text-grey">You have no orders yet.</p>
{% endif %}
</div>
</section>
{% endblock %}
saved yaml file in themes folder i am trying to display in the twig
0:
shipping_address:
name: asd
phone: asd
street: asd
city: asd
state: asd
postal_code: asdasd
country: asdas
total_amount: 2322
currency: USD
payment_method: Stripe
tracking_number: asdasd
notes: asdasd
user: digital1
date: ‘2025-05-03’
orderid: 6816f538cad20