Skip to content

Virtual Pages

How to create dynamic pages without modResource — the clean, modern way.

Why would you need this?

In traditional MODX, every document is a resource in the tree. It works fine, but:

  • It becomes messy for large catalogs or dynamic content
  • You're forced to use TVs, chunks, and rigid templates
  • You can’t fully control logic or structure

PageBlocks changes that. You define how to handle URLs, what data to load, and what template to render — all through controllers.

What is a virtual page?

A virtual page is:

  • Not created in the MODX resource tree
  • Available at a custom URL (e.g., /product/macbook-pro)
  • Fully managed by a controller
  • Built from any data — database, API, cache, etc.

Example — Product page

Let’s say you have a products table. You want to open a product page by its alias, like /product/macbook.

1. Define a route (routes/web.php):

php
Route::get('/product/{alias}', [ProductController::class, 'show']);

2. Create a controller (ProductController.php):

php
class ProductController extends Controller
{
    public function show($alias)
    {
        $product = $this->modx->getObjct(\pbTableValue::class, ['alias' => $alias]);

        if (!$product) {
            return $this->abort(404);
        }

        return $this->view('templates/product', ['product' => $product->toArray()]);
    }
}

3. Create a template (templates/product.tpl):

html
<h1>{$product.name}</h1>
<div>{$product.description}</div>
<p>Price: {$product.price}</p>

Why controllers rock

  • No dependency on modResource — you control structure entirely
  • Better performance — no TVs, chunks, or unnecessary logic
  • Flexible logic — access control, redirects, SEO, error handling
  • Template freedom — write clean Fenom views without limitations
  • Custom URLs — support any route structure and dynamic segments

Where virtual pages shine

  • Product catalogs with thousands of items
  • User profiles like /user/boshnik
  • Blog articles from a custom table
  • Multilingual URLs like /en/blog/title
  • AJAX/API endpoints like /api/products/42
  • Dynamic filters like /catalog/sale/smartphones

Conclusion

Controllers in PageBlocks = full MVC inside MODX. You gain Laravel-like control and flexibility while staying within the MODX ecosystem. No more relying on modResource. Just clean logic, custom structure, and full freedom.

© PageBlocks 2019-present