• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ICanBoogie / Render / 4175973983

pending completion
4175973983

push

github

Olivier Laviale
Add TemplateResolver\Namespaced

25 of 25 new or added lines in 4 files covered. (100.0%)

174 of 188 relevant lines covered (92.55%)

9.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.63
/lib/Renderer.php
1
<?php
2

3
/*
4
 * This file is part of the ICanBoogie package.
5
 *
6
 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
namespace ICanBoogie\Render;
13

14
use function assert;
15
use function is_string;
16
use function iterator_to_array;
17

18
/**
19
 * Renders a target or an array of options.
20
 */
21
class Renderer
22
{
23
    public const VARIABLE_CONTENT = 'content';
24

25
    /**
26
     * @var string[]
27
     */
28
    private readonly array $extensions;
29

30
    public function __construct(
31
        public readonly TemplateResolver $template_resolver,
32
        private readonly EngineProvider $engines
33
    ) {
34
        $this->extensions = array_keys(iterator_to_array($this->engines));
4✔
35
    }
36

37
    /**
38
     * Resolve a template pathname from its name and type.
39
     *
40
     * @return string Template pathname.
41
     *
42
     * @throws TemplateNotFound if the template pathname cannot be resolved.
43
     */
44
    public function resolve_template(string $name): string
45
    {
46
        $tried = [];
3✔
47
        $template_pathname = $this->template_resolver->resolve($name, $this->extensions, $tried);
3✔
48

49
        if (!$template_pathname) {
3✔
50
            throw new TemplateNotFound("There is no template matching `$name`.", $tried);
×
51
        }
52

53
        return $template_pathname;
3✔
54
    }
55

56
    /**
57
     * Renders a content.
58
     */
59
    public function render(mixed $content, RenderOptions $options = new RenderOptions()): string
60
    {
61
        $variables = $options->locals;
4✔
62

63
        if ($options->partial) {
4✔
64
            $content = $this->render_partial($options->partial, $content, $variables);
3✔
65
        }
66

67
        if ($options->template) {
4✔
68
            $content = $this->render_template($options->template, $content, $variables);
×
69
        }
70

71
        if ($options->layout) {
4✔
72
            $content = $this->render_layout($options->layout, [ self::VARIABLE_CONTENT => $content ] + $variables);
2✔
73
        }
74

75
        if ($content === null) {
4✔
76
            return '';
1✔
77
        }
78

79
        return $content;
3✔
80
    }
81

82
    /**
83
     * @param array<string, mixed> $variables
84
     */
85
    private function render_partial(string $template, mixed $content, array $variables): string
86
    {
87
        return $this->render_template(
3✔
88
            $this->resolve_template_name($template)->as_partial,
3✔
89
            $content,
3✔
90
            $variables
3✔
91
        );
3✔
92
    }
93

94
    /**
95
     * @param array<string, mixed> $variables
96
     */
97
    private function render_layout(string $template, array $variables): string
98
    {
99
        return $this->render_template(
2✔
100
            $this->resolve_template_name($template)->as_layout,
2✔
101
            null,
2✔
102
            $variables
2✔
103
        );
2✔
104
    }
105

106
    /**
107
     * @param array<string, mixed> $variables
108
     */
109
    private function render_template(string $name, mixed $content, array $variables): string
110
    {
111
        $template_pathname = $this->resolve_template($name);
3✔
112
        $extension = ExtensionResolver::resolve($template_pathname);
3✔
113

114
        assert(is_string($extension));
115

116
        $engine = $this->engines->engine_for_extension($extension)
3✔
117
            ?? throw new EngineNotAvailable("There is no engine available to render template `$template_pathname`.");
×
118

119
        return $engine->render($template_pathname, $content, $variables);
3✔
120
    }
121

122
    protected function resolve_template_name(mixed $content): TemplateName
123
    {
124
        return TemplateName::from($content);
3✔
125
    }
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc