Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Extra contribution to [`nette/latte`](https://github.com/nette/latte).
## Content

- [Setup](#setup)
- [Replacus - simple string placeholder replacer](#replacus)
- [VersionExtension - revision macros for assets](#versions-extension)
- [CdnExtension - CDN support for assets](#cdn-extension)
- [ParsedownExtension - markdown parsing support](#parsedown-extension)
Expand All @@ -18,6 +19,67 @@ Extra contribution to [`nette/latte`](https://github.com/nette/latte).
composer require contributte/latte
```

## Replacus

Simple string placeholder replacer using Latte templating engine. Replaces placeholders like `{$variable}` with provided values.

### Usage

```php
use Contributte\Latte\Replacus\Replacus;

$replacus = Replacus::create();

// Simple variable replacement
$result = $replacus->replace('Hello {$name}!', ['name' => 'World']);
// Result: "Hello World!"

// URL with placeholder
$url = $replacus->replace('https://{$domain}/path', ['domain' => 'contributte.org']);
// Result: "https://contributte.org/path"

// Multiple variables
$result = $replacus->replace('User {$name} has {$count} messages', [
'name' => 'John',
'count' => 5,
]);
// Result: "User John has 5 messages"

// Array access
$result = $replacus->replace('{$items[0]} and {$items[1]}', [
'items' => ['first', 'second'],
]);
// Result: "first and second"
```

### Custom Filters

You can add custom Latte filters:

```php
$replacus = Replacus::create()
->addFilter('upper', fn($s) => strtoupper($s))
->addFilter('trim', fn($s) => trim($s));

$result = $replacus->replace('{$text|trim|upper}', ['text' => ' hello ']);
// Result: "HELLO"
```

### Custom Latte Engine

For advanced usage, you can provide your own configured Latte engine:

```php
use Latte\Engine;
use Latte\Loaders\StringLoader;

$latte = new Engine();
$latte->setLoader(new StringLoader());
// ... configure as needed

$replacus = new Replacus($latte);
```

## Version(s) Extension

This extension adds 3 macros: `{rev}`, `{build}`, `{v}`.
Expand Down
58 changes: 58 additions & 0 deletions src/Replacus/Replacus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php declare(strict_types = 1);

namespace Contributte\Latte\Replacus;

use Latte\ContentType;
use Latte\Engine;
use Latte\Loaders\StringLoader;

/**
* Simple string replacer using Latte templating engine.
* Replaces placeholders like {$variable} with provided values.
*/
class Replacus
{

private Engine $latte;

public function __construct(?Engine $latte = null)
{
$this->latte = $latte ?? $this->createDefaultEngine();
}

public static function create(): self
{
return new self();
}

/**
* @param mixed[] $args
*/
public function replace(string $input, array $args = []): string
{
return $this->latte->renderToString($input, $args);
}

public function addFilter(string $name, callable $callback): self
{
$this->latte->addFilter($name, $callback);

return $this;
}

public function getLatte(): Engine
{
return $this->latte;
}

private function createDefaultEngine(): Engine
{
$latte = new Engine();
$latte->setLoader(new StringLoader());
$latte->setAutoRefresh(false);
$latte->setContentType(ContentType::Html);

return $latte;
}

}
88 changes: 88 additions & 0 deletions tests/Cases/Replacus/Replacus.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php declare(strict_types = 1);

use Contributte\Latte\Replacus\Replacus;
use Contributte\Tester\Toolkit;
use Latte\Engine;
use Latte\Loaders\StringLoader;
use Tester\Assert;

require_once __DIR__ . '/../../bootstrap.php';

// Test simple variable replacement
Toolkit::test(function (): void {
$replacus = Replacus::create();
$result = $replacus->replace('{$foo}', ['foo' => 'bar']);
Assert::equal('bar', $result);
});

// Test integer replacement
Toolkit::test(function (): void {
$replacus = Replacus::create();
$result = $replacus->replace('{$num}', ['num' => 1]);
Assert::equal('1', $result);
});

// Test array index replacement
Toolkit::test(function (): void {
$replacus = Replacus::create();
$result = $replacus->replace('{$foo[0]}{$foo[1]}', ['foo' => ['a', 'b']]);
Assert::equal('ab', $result);
});

// Test URL replacement (from original docs)
Toolkit::test(function (): void {
$replacus = Replacus::create();
$result = $replacus->replace('https://{$domain}', ['domain' => 'contributte.org']);
Assert::equal('https://contributte.org', $result);
});

// Test multiple variables
Toolkit::test(function (): void {
$replacus = Replacus::create();
$result = $replacus->replace('Hello {$name}, you have {$count} messages', [
'name' => 'John',
'count' => 5,
]);
Assert::equal('Hello John, you have 5 messages', $result);
});

// Test with custom filter
Toolkit::test(function (): void {
$replacus = Replacus::create();
$replacus->addFilter('upper', fn ($s) => strtoupper($s));
$result = $replacus->replace('{$text|upper}', ['text' => 'hello']);
Assert::equal('HELLO', $result);
});

// Test constructor with custom Latte engine
Toolkit::test(function (): void {
$latte = new Engine();
$latte->setLoader(new StringLoader());

$replacus = new Replacus($latte);
$result = $replacus->replace('{$foo}', ['foo' => 'custom']);
Assert::equal('custom', $result);
});

// Test getLatte method
Toolkit::test(function (): void {
$replacus = Replacus::create();
Assert::type(Engine::class, $replacus->getLatte());
});

// Test empty args
Toolkit::test(function (): void {
$replacus = Replacus::create();
$result = $replacus->replace('static text');
Assert::equal('static text', $result);
});

// Test fluent interface for addFilter
Toolkit::test(function (): void {
$replacus = Replacus::create()
->addFilter('lower', fn ($s) => strtolower($s))
->addFilter('trim', fn ($s) => trim($s));

$result = $replacus->replace('{$text|trim|lower}', ['text' => ' HELLO ']);
Assert::equal('hello', $result);
});