Trongate PHP Framework Docs
Introduction
Quick Start
Basic Concepts
Understanding Routing
Intercepting Requests
Module Fundamentals
Database Operations
Templates
Helpers
Form Handling
Form Validation
Working With Files
Image Manipulation
Working With Dates & Times
Language Control
Security
Tips And Best Practices

Understanding Image Paths

Successfully working with images in Trongate requires understanding three distinct types of paths and when to use each one.

The Three Types of Paths

Every image in a Trongate application can be referenced using three different path formats:

Path Types Explained:

  • Relative path: Path relative to application root (e.g., public/images/logo.png or ../modules/shop/products/widget.jpg)
  • Absolute path: Complete filesystem path from root (e.g., /var/www/html/myapp/public/images/logo.png)
  • URL: Web-accessible address (e.g., https://example.com/images/logo.png or shop_module/products/widget.jpg)

Which Path Type to Use When

Understanding when to use each path type is essential:

The Image module methods operate on a loaded image resource in memory. Most operations don't take file paths at all - they work on the image already loaded via the method or the method.

For Image Module Operations

The Image module follows a three-step pattern:

  1. Upload/Load: Get the image into memory via upload() (for new uploads) or load() (for existing images)
  2. Process: Call methods like resize_to_width(), resize_to_height(), resize_and_crop()
  3. Save: Write the result using save()

Only upload(), load(), and save() deal with file paths. When they do, use relative paths:

PHP
// Step 1a: Upload NEW image (config array specifies destination directory)
$config = [
    'destination' => 'products',
    'upload_to_module' => true
];
$file_info = $this->image->upload($config);

// Step 1b: Load EXISTING image (uses relative path)
$this->image->load('modules/products/images/original.jpg');

// Step 2: Process (no paths needed - works on loaded image)
$this->image->resize_to_width(800);

// Step 3: Save (uses relative path)
// ✅ CORRECT: Relative path
$this->image->save('modules/products/images/resized.jpg');

// ⚠️ WORKS BUT NOT RECOMMENDED: Absolute path
$this->image->save('/var/www/html/myapp/modules/products/images/resized.jpg');

// ❌ DOES NOT WORK: URL
$this->image->save('https://example.com/products/images/resized.jpg');

// ❌ DOES NOT WORK: Module asset trigger
$this->image->save('products_module/images/resized.jpg');

Why Relative Paths Are Recommended:

Relative paths work consistently across development, staging, and production environments. Absolute paths break when you move your application to a different server or directory structure.

When to Use upload() vs. load():

  • upload(): Use for NEW images coming from user file uploads. Automatically handles validation, security checks, and optional resizing/thumbnails.
  • load(): Use for EXISTING images already stored on disk. Perfect for batch processing, generating new sizes, or creating thumbnails from stored images.

For Browser Display

When displaying images in HTML, use URLs:

PHP
// Public directory images - simple URL
<img src="<?= BASE_URL ?>gallery/photo.jpg" alt="Gallery Photo">

// Module images - use module asset trigger
<img src="<?= BASE_URL ?>shop_module/products/widget.jpg" alt="Product">

The Module Asset Trigger

Images stored in module directories require special handling for browser display. Trongate uses a naming convention called the "module asset trigger":

The Module Asset Trigger Pattern:

To display images from a module, append _module to the module name in the URL:

  • Filesystem path (for PHP): ../modules/shop/products/widget.jpg
  • Browser URL (for HTML): shop_module/products/widget.jpg

Example: Converting Paths for Display

PHP
public function view_product(): void {
    $product_id = segment(3, 'int');
    
    // Get product from database
    $product = $this->db->get_where($product_id, 'products');
    
    // The database stores the filesystem path
    // e.g., '../modules/shop/products/laptop.jpg'
    $filesystem_path = $product->image_path;
    
    // Convert to browser URL for display
    // Remove '../modules/' and replace '/' with '_module/'
    $browser_url = str_replace('../modules/shop/', 'shop_module/', $filesystem_path);
    
    // Pass to view
    $data['product'] = $product;
    $data['image_url'] = $browser_url;
    $this->view('product_detail', $data);
}

In the view:

View File
<img src="<?= BASE_URL . $image_url ?>" alt="<?= out($product->name) ?>">
<!-- Renders as: <img src="https://example.com/shop_module/products/laptop.jpg"> -->

Important: The _module trigger only works in browser URLs. It does not work with Image module methods that operate on the filesystem.

What You Get When Uploading Images

When you call , it returns an array with five pieces of information:

PHP
$config = [
    'destination' => 'products',
    'upload_to_module' => true,
    'thumbnail_dir' => 'products/thumbs',
    'thumbnail_max_width' => 300,
    'thumbnail_max_height' => 300
];

$file_info = $this->image->upload($config);

/* Returns:
[
    'file_name' => 'laptop.jpg',
    'file_path' => '../modules/shop/products/laptop.jpg',
    'file_type' => 'image/jpeg',
    'file_size' => 245760,
    'thumbnail_path' => '../modules/shop/products/thumbs/laptop.jpg'
]
*/

Understanding the Return Values:

  • file_name: Just the filename - useful for display or storage
  • file_path: Filesystem path - store this in your database
  • file_type: MIME type - useful for validation
  • file_size: Size in bytes - useful for display or quotas
  • thumbnail_path: Filesystem path to thumbnail - store this too

Notice that both file_path and thumbnail_path are filesystem paths, not URLs. You'll need to convert these when displaying images in your views.

Common Path Scenarios

Scenario 1: Public Directory Image

PHP
// Upload configuration
$config['destination'] = 'gallery';

$file_info = $this->image->upload($config);

// What you get back
$file_info['file_path']; // 'gallery/landscape.jpg'

Scenario 2: Module Directory Image

PHP
// Upload configuration
$config = [
    'destination' => 'avatars',
    'upload_to_module' => true
];

$file_info = $this->image->upload($config);

// What you get back
$file_info['file_path']; // '../modules/users/avatars/profile.jpg'

// How to display in browser (convert path to URL)
$url = str_replace('../modules/users/', 'users_module/', $file_info['file_path']);

Scenario 3: Loading and Processing Existing Images

PHP
// Load existing image using filesystem path
$source = '../modules/products/images/original.jpg';
$this->image->load($source);

// Process the loaded image
$this->image->resize_to_width(800);

// Save the processed result
$this->image->save('../modules/products/images/original_800.jpg');

// Display image using URL (convert filesystem path to browser URL)
$url = 'products_module/images/original_800.jpg';

Load vs. Upload: Use load() when working with images that already exist on your server. This is perfect for batch processing jobs, creating additional sizes from stored images, or building image galleries from existing files. Use upload() only for handling new file uploads from users.

Scenario 4: Processing Multiple Sizes from Database Path

PHP
// Get product from database
$product = $this->db->get_where($product_id, 'products');

// Database stores filesystem path
$original_path = $product->image_path; // e.g., '../modules/products/images/widget.jpg'

// Generate thumbnail
$this->image->load($original_path);
$this->image->resize_and_crop(150, 150);
$thumbnail_path = '../modules/products/thumbnails/widget.jpg';
$this->image->save($thumbnail_path);

// Generate medium size
$this->image->load($original_path); // Reload original
$this->image->resize_to_width(600);
$medium_path = '../modules/products/medium/widget.jpg';
$this->image->save($medium_path);

// Store both paths in database
$update_data = [
    'thumbnail_path' => $thumbnail_path,
    'medium_path' => $medium_path
];
$this->model->update($product_id, $update_data, 'products');

// In your view, convert to URLs for display:
// Thumbnail: products_module/thumbnails/widget.jpg
// Medium: products_module/medium/widget.jpg

Including a <base> tag in your page head ensures that all relative URLs - including module asset URLs such as shop_module/products/widget.jpg - resolve from the application root rather than the current request path.

HTML
<base href="<?= BASE_URL ?>">

This is especially important in Trongate applications, where pages are often rendered from nested routes or modules. Setting a base tag prevents broken images, scripts, and links when URLs are constructed relative to deeper paths.

Essential Guidelines

  • ✅ Use upload() for NEW images from user uploads
  • ✅ Use load() for EXISTING images already on disk
  • ✅ Use relative filesystem paths for Image module methods (load(), save())
  • ✅ Use URLs for browser display in HTML
  • ✅ Store filesystem paths in your database
  • ✅ Convert module paths to URLs using the _module trigger in views
  • ✅ Public directory images have simpler URL construction
  • ✅ The _module trigger only works in browser URLs, not PHP methods
  • ❌ Never use URLs with Image module processing methods
  • ❌ Never use filesystem paths in HTML image tags
  • ❌ Never use absolute paths unless absolutely necessary (they break portability)

We're continually improving the Trongate documentation. If anything is incorrect, unclear, incomplete, or could be better, we'd genuinely appreciate your input.

Share your thoughts in the Documentation Feedback.

Leave Feedback About This Page