Server technologies

PHP / Laravel

Retrieve published documents with Laravel’s HTTP client and render escaped Blade templates.

PeopleTide Content · HTTP integration guides

1. Prepare your project.

Use Laravel 11+ and PHP 8.2+. Configure the three CONTENT_* values in .env, add the services configuration shown below, then add the route and Blade view in their respective files.

Connect and render.

Publish an article of type article with slug welcome and a body field before running the example. Split the labelled files into the paths shown.

PHP / Blade
// config/services.php — add this entry to the returned array
'content' => [
    'origin' => env('CONTENT_ORIGIN', 'https://content.peopletide.com'),
    'organization' => env('CONTENT_ORGANIZATION_ID'),
    'site' => env('CONTENT_SITE_ID'),
],

// routes/web.php — Laravel 11+, PHP 8.2+
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Route;

Route::get('/articles/{slug}', function (string $slug) {
    $origin = rtrim(config('services.content.origin'), '/');
    $prefix = '/delivery/v1/'.config('services.content.organization').'/'.config('services.content.site').'/';
    $read = function ($path) use ($origin, $prefix) {
        if (!str_starts_with($path, $prefix) || str_contains($path, '..')) {
            throw new \RuntimeException('Unexpected delivery URL');
        }
        return Http::connectTimeout(3)->timeout(8)->withoutRedirecting()
            ->get($origin.$path)->throw()->json();
    };
    try {
        $current = $read($prefix.'current.json');
        $manifest = $read($current['url']);
        $entry = collect($manifest['entries'])->first(fn ($e) => $e['type'] === 'article' && $e['slug'] === $slug);
        if (!$entry) return response('Article not published', 404);
        $article = $read($entry['url']);
    } catch (\Throwable $error) {
        report($error);
        return response('Content temporarily unavailable', 503);
    }
    return view('article', ['article' => $article]);
});

// resources/views/article.blade.php — escaped text, no raw HTML
<h1>{{ $article['title'] }}</h1>
<p style="white-space: pre-wrap">{{ $article['fields']['body'] ?? '' }}</p>

Choose when content refreshes.

The route fetches the active pointer for each request. Use Laravel Cache with at most 30 seconds for discovery if desired, and cache immutable documents by URL. Blade’s double braces escape values; do not switch to raw output for untrusted Markdown.

Verify success and failure.

Run php artisan serve and open /articles/welcome. Check a published article, an unknown slug returning 404, and an upstream outage returning 503. If configuration is cached, refresh it after changing CONTENT_* settings.