Passed
Push — master ( 75f29e...00dcc0 )
by Caen
03:06 queued 13s
created

HydePage::navigationMenuTitle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hyde\Framework\Concerns;
4
5
use Hyde\Framework\Actions\SourceFileParser;
6
use Hyde\Framework\Concerns\Internal\ConstructsPageSchemas;
7
use Hyde\Framework\Contracts\CompilableContract;
8
use Hyde\Framework\Contracts\FrontMatter\PageSchema;
9
use Hyde\Framework\Contracts\RouteContract;
10
use Hyde\Framework\Foundation\PageCollection;
11
use Hyde\Framework\Hyde;
12
use Hyde\Framework\Models\FrontMatter;
13
use Hyde\Framework\Models\Metadata\Metadata;
14
use Hyde\Framework\Models\Route;
15
use Hyde\Framework\Services\DiscoveryService;
16
use Illuminate\Support\Arr;
17
18
/**
19
 * To ensure compatibility with the Hyde Framework, all page models should extend this class.
20
 * Markdown-based pages can extend the BaseMarkdownPage class to get relevant helpers.
21
 *
22
 * Unlike other frameworks, in general you don't instantiate pages yourself in Hyde,
23
 * instead, the page models acts as blueprints defining information for Hyde to
24
 * know how to parse a file, and what data around it should be generated.
25
 *
26
 * To create a parsed file instance, you'd typically just create a source file,
27
 * and you can then access the parsed file from the HydeKernel's page index.
28
 * The source files are usually parsed by the SourceFileParser action.
29
 *
30
 * @see \Hyde\Framework\Concerns\BaseMarkdownPage
31
 * @see \Hyde\Framework\Testing\Feature\HydePageTest
32
 */
33
abstract class HydePage implements CompilableContract, PageSchema
34
{
35
    use ConstructsPageSchemas;
0 ignored issues
show
Bug introduced by
The trait Hyde\Framework\Concerns\...l\ConstructsPageSchemas requires the property $markdown which is not provided by Hyde\Framework\Concerns\HydePage.
Loading history...
36
    use Internal\HasNavigationData;
37
38
    public static string $sourceDirectory;
39
    public static string $outputDirectory;
40
    public static string $fileExtension;
41
    public static string $template;
42
43
    public string $identifier;
44
    public string $routeKey;
45
46
    public FrontMatter $matter;
47
    public Metadata $metadata;
48
49
    public string $title;
50
    public ?string $canonicalUrl = null;
51
    public ?array $navigation = null;
52
53
    public function __construct(string $identifier = '', FrontMatter|array $matter = [])
54
    {
55
        $this->identifier = $identifier;
56
        $this->routeKey = static::routeKey($identifier);
57
58
        $this->matter = $matter instanceof FrontMatter ? $matter : new FrontMatter($matter);
0 ignored issues
show
introduced by
$matter is never a sub-type of Hyde\Framework\Models\FrontMatter.
Loading history...
59
        $this->constructPageSchemas();
60
        $this->metadata = new Metadata($this);
61
    }
62
63
    // Section: Query
64
65
    /**
66
     * Parse a source file into a page model instance.
67
     *
68
     * @param  string  $identifier  The identifier of the page to parse.
69
     * @return static New page model instance for the parsed source file.
70
     */
71
    public static function parse(string $identifier): HydePage
72
    {
73
        return (new SourceFileParser(static::class, $identifier))->get();
74
    }
75
76
    /**
77
     * Get an array of all the source file identifiers for the model.
78
     *
79
     * Essentially an alias of DiscoveryService::getAbstractPageList().
80
     *
81
     * @return array<string>|false
82
     */
83
    public static function files(): array|false
84
    {
85
        return DiscoveryService::getSourceFileListForModel(static::class);
86
    }
87
88
    /**
89
     * Get a collection of all pages, parsed into page models.
90
     *
91
     * @return \Hyde\Framework\Foundation\PageCollection<\Hyde\Framework\Concerns\HydePage
92
     */
93
    public static function all(): PageCollection
94
    {
95
        return Hyde::pages()->getPages(static::class);
96
    }
97
98
    // Section: Filesystem
99
100
    /**
101
     * Get the directory in where source files are stored.
102
     */
103
    final public static function sourceDirectory(): string
104
    {
105
        return unslash(static::$sourceDirectory);
106
    }
107
108
    /**
109
     * Get the output subdirectory to store compiled HTML.
110
     */
111
    final public static function outputDirectory(): string
112
    {
113
        return unslash(static::$outputDirectory);
114
    }
115
116
    /**
117
     * Get the file extension of the source files.
118
     */
119
    final public static function fileExtension(): string
120
    {
121
        return '.'.ltrim(static::$fileExtension, '.');
122
    }
123
124
    /**
125
     * Qualify a page identifier into a referenceable local file path.
126
     */
127
    public static function sourcePath(string $identifier): string
128
    {
129
        return static::sourceDirectory().'/'.unslash($identifier).static::fileExtension();
130
    }
131
132
    /**
133
     * Get the proper site output path for a page model.
134
     */
135
    public static function outputPath(string $identifier): string
136
    {
137
        return static::routeKey($identifier).'.html';
138
    }
139
140
    /**
141
     * Get the path to the source file, relative to the project root.
142
     * In other words, qualify the identifier of the page instance.
143
     */
144
    public function getSourcePath(): string
145
    {
146
        return static::sourcePath($this->identifier);
147
    }
148
149
    /**
150
     * Get the path where the compiled page instance will be saved.
151
     */
152
    public function getOutputPath(): string
153
    {
154
        return static::outputPath($this->identifier);
155
    }
156
157
    // Section: Routing
158
159
    /**
160
     * Format a page identifier to a route key.
161
     */
162
    public static function routeKey(string $identifier): string
163
    {
164
        return unslash(static::outputDirectory().'/'.$identifier);
165
    }
166
167
    /**
168
     * Get the route key for the page.
169
     *
170
     * The route key is the URI path relative to the site root.
171
     *
172
     * For example, if the compiled page will be saved to _site/docs/index.html,
173
     * then this method will return 'docs/index'. Route keys are used to
174
     * identify pages, similar to how named routes work in Laravel.
175
     *
176
     * @return string The page's route key.
177
     */
178
    public function getRouteKey(): string
179
    {
180
        return $this->routeKey;
181
    }
182
183
    /**
184
     * Get the route for the page.
185
     *
186
     * @return RouteContract The page's route.
187
     */
188
    public function getRoute(): RouteContract
189
    {
190
        return new Route($this);
191
    }
192
193
    // Section: Getters
194
195
    /**
196
     * Get the page model's identifier property.
197
     *
198
     * The identifier is the part between the source directory and the file extension.
199
     * It may also be known as a 'slug', or previously 'basename'.
200
     *
201
     * For example, the identifier of a source file stored as '_pages/about/contact.md'
202
     * would be 'about/contact', and 'pages/about.md' would simply be 'about'.
203
     *
204
     * @return string The page's identifier.
205
     */
206
    public function getIdentifier(): string
207
    {
208
        return $this->identifier;
209
    }
210
211
    /**
212
     * Get the Blade template key for the page.
213
     */
214
    public function getBladeView(): string
215
    {
216
        return static::$template;
217
    }
218
219
    // Section: Front Matter
220
221
    /**
222
     * Get a value from the computed page data, or fallback to the page's front matter, then to the default value.
223
     *
224
     * @return \Hyde\Framework\Models\FrontMatter|mixed
225
     */
226
    public function get(string $key = null, mixed $default = null): mixed
227
    {
228
        return Arr::get(array_filter(array_merge(
229
            $this->matter->toArray(),
230
            (array) $this,
231
        )), $key, $default);
232
    }
233
234
    /**
235
     * Get the front matter object, or a value from within.
236
     *
237
     * @return \Hyde\Framework\Models\FrontMatter|mixed
238
     */
239
    public function matter(string $key = null, mixed $default = null): mixed
240
    {
241
        return $this->matter->get($key, $default);
242
    }
243
244
    /**
245
     * See if a value exists in the computed page data or the front matter.
246
     */
247
    public function has(string $key): bool
248
    {
249
        return ! blank($this->get($key));
250
    }
251
252
    // Section: Accessors
253
254
    /**
255
     * Get the page title to display in HTML tags like <title> and <meta> tags.
256
     */
257
    public function htmlTitle(): string
258
    {
259
        return config('site.name', 'HydePHP').' - '.$this->title;
260
    }
261
262
    public function renderPageMetadata(): string
263
    {
264
        return $this->metadata->render();
265
    }
266
}
267