Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:03,000 --> 00:00:05,990
The ReviewPage is now a dynamic route,
2
00:00:05,990 --> 00:00:09,156
meaning that this same component will be used
3
00:00:09,156 --> 00:00:12,167
to render all the different review pages.
4
00:00:12,167 --> 00:00:13,956
This also means that, if we
5
00:00:13,956 --> 00:00:15,612
want to add a new review,
6
00:00:15,678 --> 00:00:19,096
we can now simply create a new Markdown file.
7
00:00:19,096 --> 00:00:22,487
Let's review the "hellblade" game for example.
8
00:00:22,487 --> 00:00:24,361
I'll change all the front matter
9
00:00:24,361 --> 00:00:25,708
properties accordingly.
10
00:00:26,087 --> 00:00:27,975
Let's put 6 as the day,
11
00:00:27,975 --> 00:00:30,820
and we already have a "hellblade.jpg"
12
00:00:30,820 --> 00:00:32,819
image in the right folder.
13
00:00:32,896 --> 00:00:35,232
As for the body, I'll just write
14
00:00:35,232 --> 00:00:36,838
some placeholder text.
15
00:00:36,911 --> 00:00:39,518
It's not our main focus right now.
16
00:00:39,531 --> 00:00:42,994
So, we have a "hellblade.md" file.
17
00:00:42,994 --> 00:00:45,212
This means that, if we go to our app,
18
00:00:45,212 --> 00:00:49,365
and request the "/reviews/hellblade" path,
19
00:00:49,365 --> 00:00:51,222
we'll see a page with the right
20
00:00:51,222 --> 00:00:52,540
content straight away,
21
00:00:52,600 --> 00:00:56,122
without having to modify any JavaScript code.
22
00:00:56,122 --> 00:00:59,111
The ReviewPage component will automatically
23
00:00:59,111 --> 00:01:01,961
load the data from the new Markdown file,
24
00:01:02,030 --> 00:01:04,105
based on the URL path.
25
00:01:04,105 --> 00:01:06,903
However, if we go to the Reviews page,
26
00:01:06,903 --> 00:01:09,712
we won't see Hellblade in this list.
27
00:01:09,712 --> 00:01:12,783
That's because, in the ReviewsPage component,
28
00:01:12,783 --> 00:01:15,250
we only have two list items,
29
00:01:15,343 --> 00:01:18,388
for Hollow Knight and Stardew Valley.
30
00:01:18,388 --> 00:01:20,491
Now, we don't really want to
31
00:01:20,491 --> 00:01:22,294
manually edit this file,
32
00:01:22,370 --> 00:01:24,772
every time we add a new review.
33
00:01:24,772 --> 00:01:27,876
Why don't we generate this list automatically?
34
00:01:27,876 --> 00:01:30,412
In our "reviews.js" file,
35
00:01:30,412 --> 00:01:32,067
we could add another function,
36
00:01:32,892 --> 00:01:35,654
let's call it "getReviews" (plural).
37
00:01:35,654 --> 00:01:37,952
And here we could return an array,
38
00:01:37,952 --> 00:01:39,237
with all the items.
39
00:01:39,304 --> 00:01:42,095
We'll implement this properly in a second,
40
00:01:42,095 --> 00:01:44,402
but in the ReviewsPage we'll then
41
00:01:44,402 --> 00:01:46,709
be able to call that new function
42
00:01:46,779 --> 00:01:48,670
and get all the "reviews".
43
00:01:48,670 --> 00:01:51,187
We need to use "await", because
44
00:01:51,187 --> 00:01:52,974
getReviews is "async",
45
00:01:53,055 --> 00:01:55,474
which means we also need to declare
46
00:01:55,474 --> 00:01:57,894
this component function as "async".
47
00:01:57,963 --> 00:02:01,673
That's ok, because this is a Server Component.
48
00:02:01,673 --> 00:02:04,953
What I'll do for now is simply log the "reviews",
49
00:02:05,373 --> 00:02:07,631
so we can check the data returned
50
00:02:07,631 --> 00:02:08,999
by our new function.
51
00:02:09,173 --> 00:02:11,218
Ok, if we save, we should see
52
00:02:11,218 --> 00:02:12,980
that message in the logs.
53
00:02:13,051 --> 00:02:16,577
"reviews" is currently an empty array, of course,
54
00:02:16,577 --> 00:02:19,671
because that's what we're returning at the moment.
55
00:02:19,671 --> 00:02:22,406
Now, let's think about how to implement
56
00:02:22,406 --> 00:02:24,018
this function for real.
57
00:02:24,089 --> 00:02:26,663
To find all the available reviews,
58
00:02:26,789 --> 00:02:29,655
we could simply list the Markdown files
59
00:02:29,655 --> 00:02:33,232
that are inside the "content/reviews" folder.
60
00:02:33,232 --> 00:02:35,633
We can list the files in a folder
61
00:02:35,633 --> 00:02:38,151
by using the "readdir" function
62
00:02:38,151 --> 00:02:40,586
from the "fs" built-in module.
63
00:02:40,668 --> 00:02:44,085
So, in "getReviews" we can obtain the "files"
64
00:02:44,085 --> 00:02:47,299
by calling "readdir", which is asynchronous,
65
00:02:47,299 --> 00:02:50,846
and passing the path, that is "./content/reviews".
66
00:02:50,846 --> 00:02:53,598
Just to show you exactly what it returns,
67
00:02:53,686 --> 00:02:56,685
I'll log the "files" variable to the console.
68
00:02:56,706 --> 00:02:57,827
And if we save,
69
00:02:57,827 --> 00:03:00,444
the page in the browser reloads automatically,
70
00:03:00,444 --> 00:03:02,075
running our new code,
71
00:03:02,075 --> 00:03:04,713
and you can see that "files" is an array
72
00:03:04,713 --> 00:03:07,794
containing the name of each Markdown file.
73
00:03:07,794 --> 00:03:11,477
We'll need to strip out the ".md" extension,
74
00:03:11,477 --> 00:03:13,992
because what we want is the "slugs".
75
00:03:13,992 --> 00:03:16,705
Let's transform this "files" array.
76
00:03:16,705 --> 00:03:18,429
For a start, it's better if
77
00:03:18,429 --> 00:03:19,898
we filter the elements,
78
00:03:19,961 --> 00:03:22,794
and only keep the files that end
79
00:03:22,794 --> 00:03:25,007
with the ".md" extension,
80
00:03:25,096 --> 00:03:27,205
just in case there's some other
81
00:03:27,205 --> 00:03:28,838
file in the same folder.
82
00:03:28,906 --> 00:03:32,162
Once we're sure we only have Markdown files,
83
00:03:32,162 --> 00:03:34,020
we can use the "map" method
84
00:03:34,020 --> 00:03:35,809
to transform each element,
85
00:03:35,878 --> 00:03:38,941
and we want to "slice" the file name,
86
00:03:38,941 --> 00:03:40,728
to extract a substring,
87
00:03:40,728 --> 00:03:43,169
containing the characters from zero,
88
00:03:43,169 --> 00:03:44,660
that is the beginning,
89
00:03:44,728 --> 00:03:47,715
up until the end but excluding the
90
00:03:47,715 --> 00:03:50,088
length of the ".md" suffix.
91
00:03:50,176 --> 00:03:52,275
You can pass a negative index
92
00:03:52,275 --> 00:03:54,229
to count back from the end.
93
00:03:54,302 --> 00:03:56,599
Let's log the "slugs" value now,
94
00:03:56,599 --> 00:03:58,895
to check if our code is working.
95
00:03:58,967 --> 00:04:00,745
You can see that this way
96
00:04:00,745 --> 00:04:04,523
we correctly extract the slug from each file name.
97
00:04:04,523 --> 00:04:07,000
Normally I would write unit tests
98
00:04:07,000 --> 00:04:08,651
for this sort of code,
99
00:04:08,726 --> 00:04:11,656
but for this example I'm basically testing
100
00:04:11,656 --> 00:04:13,889
it manually with log statements.
101
00:04:13,958 --> 00:04:16,286
Anyway, once we have the "slug"
102
00:04:16,286 --> 00:04:18,664
we can get a full review object
103
00:04:18,664 --> 00:04:20,740
simply by calling our existing
104
00:04:20,740 --> 00:04:22,193
"getReview" function,
105
00:04:22,262 --> 00:04:24,612
that will read each Markdown file,
106
00:04:24,612 --> 00:04:26,685
extracting all the properties.
107
00:04:26,754 --> 00:04:30,317
So, let's iterate over each "slug" in the array,
108
00:04:30,317 --> 00:04:32,222
and for each one we can get
109
00:04:32,222 --> 00:04:33,914
the full "review" object
110
00:04:33,985 --> 00:04:36,078
by calling "getReview" passing
111
00:04:36,078 --> 00:04:37,752
that "slug" as argument.
112
00:04:37,822 --> 00:04:40,342
Note that we need to use "await"
113
00:04:40,342 --> 00:04:42,626
because "getReview" is async.
114
00:04:42,705 --> 00:04:45,351
Now, let's define a "reviews" array,
115
00:04:45,351 --> 00:04:46,821
outside of the loop,
116
00:04:46,894 --> 00:04:50,096
and we can then add each review to that array,
117
00:04:50,096 --> 00:04:51,944
using the "push" method.
118
00:04:51,944 --> 00:04:55,580
And finally, we can return the "reviews" array.
119
00:04:55,580 --> 00:04:58,087
Let's see what happens now if we save.
120
00:04:58,087 --> 00:05:00,523
There's a lot of data printed here.
121
00:05:00,523 --> 00:05:02,512
The ReviewsPage is still logging
122
00:05:02,512 --> 00:05:03,817
the data it receives,
123
00:05:03,880 --> 00:05:06,548
and you can see that "reviews" is an array
124
00:05:06,548 --> 00:05:09,226
where each element is an object with
125
00:05:09,226 --> 00:05:12,693
"title", "date", "image", and "body" properties.
126
00:05:12,693 --> 00:05:15,638
What we're missing here is the "slug".
127
00:05:15,638 --> 00:05:18,531
We'll need that property in the ReviewsPage,
128
00:05:18,531 --> 00:05:22,151
otherwise we cannot link to the right URL path.
129
00:05:22,151 --> 00:05:24,645
Let's simply add the "slug" to the
130
00:05:24,645 --> 00:05:26,918
object returned by "getReview".
131
00:05:26,992 --> 00:05:29,092
And with this, each review should
132
00:05:29,092 --> 00:05:31,129
have all the properties we need.
133
00:05:31,193 --> 00:05:32,448
You could argue that,
134
00:05:32,448 --> 00:05:34,228
in the ReviewsPage we don't
135
00:05:34,228 --> 00:05:35,744
really need the "body",
136
00:05:35,810 --> 00:05:37,855
so, as an optimization, we
137
00:05:37,855 --> 00:05:39,822
could exclude that field.
138
00:05:39,900 --> 00:05:42,089
But we would still need to read
139
00:05:42,089 --> 00:05:43,925
each Markdown file anyway,
140
00:05:43,996 --> 00:05:47,410
to extract the properties from the front matter,
141
00:05:47,410 --> 00:05:50,468
so we might as well leave this code as it is.
142
00:05:50,468 --> 00:05:53,098
And this is how we can automatically
143
00:05:53,098 --> 00:05:54,559
get all the reviews.
144
00:05:54,632 --> 00:05:58,611
The next step is to display that data in our page,
145
00:05:58,611 --> 00:06:00,721
but we'll do that in the next video.
10549
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.