WEBVTT - This file was automatically generated by VIMEO

0
00:00:00.985 --> 00:00:02.645
Hi, my name's Aral Balkan,

1
00:00:02.785 --> 00:00:04.925
and today I wanna take you through a recent feature

2
00:00:05.035 --> 00:00:08.245
that I added to Kitten called the Streaming HTML workflow.

3
00:00:09.025 --> 00:00:13.805
So let's jump right in and create a basic counter example.

4
00:00:13.945 --> 00:00:15.805
So I'm gonna create a directory called counter,

5
00:00:16.025 --> 00:00:19.445
and then I'm going to enter that directory

6
00:00:20.185 --> 00:00:22.165
and I'm gonna run Kitten there.

7
00:00:22.825 --> 00:00:25.845
So you can see Kitten's just launched

8
00:00:26.665 --> 00:00:28.805
and is running in that directory.

9
00:00:29.225 --> 00:00:32.485
So what I'm gonna do now is take my web browser

10
00:00:32.825 --> 00:00:34.725
and go to localhost,

11
00:00:35.105 --> 00:00:38.205
and I get a page not found error, which is exactly

12
00:00:38.205 --> 00:00:40.085
what I would expect because there's nothing there.

13
00:00:40.745 --> 00:00:43.085
Um, but Kitten is running in that folder now.

14
00:00:43.545 --> 00:00:48.285
So what I'm going to do is start up my editor using Helix

15
00:00:48.285 --> 00:00:50.365
Editor here, um,

16
00:00:50.745 --> 00:00:54.925
and I am going to, uh, create a file.

17
00:00:55.745 --> 00:00:59.685
So let's create a file called index.page.js

18
00:01:01.145 --> 00:01:05.205
and it says, uh, page route is missing.

19
00:01:06.035 --> 00:01:10.445
Okay, so, um, a handler

20
00:01:10.785 --> 00:01:14.005
and it says, ensure you're exporting a default function

21
00:01:14.005 --> 00:01:15.125
from your page.

22
00:01:15.435 --> 00:01:17.085
Okay, so this is what we need to do.

23
00:01:17.085 --> 00:01:21.125
We need to export a default function from our page.

24
00:01:21.385 --> 00:01:24.725
So if I paste that in and I save it, well, there we go.

25
00:01:24.875 --> 00:01:26.965
There's our little “Hello, World.”

26
00:01:27.505 --> 00:01:29.965
Now, we don't really want this to say hello world.

27
00:01:31.665 --> 00:01:36.405
We want this to be our, um, counter.

28
00:01:36.985 --> 00:01:39.805
So I'll just change that to read counter and save

29
00:01:40.305 --> 00:01:44.765
and Kitten, live reloads, um, as you, as you work.

30
00:01:45.425 --> 00:01:48.165
So as you can see, we are exporting a route here.

31
00:01:48.165 --> 00:01:50.925
It's the GET route, and this gets called, um,

32
00:01:50.995 --> 00:01:52.965
when you hit it in the browser, when you go

33
00:01:52.965 --> 00:01:54.485
to localhost as the index.

34
00:01:55.105 --> 00:01:59.245
Um, and it's returning some HTML, some kitten, HTML, uh,

35
00:02:00.065 --> 00:02:03.365
to the, to the client to the, to the browser.

36
00:02:03.985 --> 00:02:06.525
So let's quickly create our interface for this.

37
00:02:06.995 --> 00:02:09.885
What do we need? Well, we need to display the count.

38
00:02:10.425 --> 00:02:14.045
So I'm just going to hard code that for now.

39
00:02:14.075 --> 00:02:17.485
There's our count, and then we will need a button

40
00:02:18.985 --> 00:02:21.165
to increment that count.

41
00:02:22.345 --> 00:02:23.485
So there's our button,

42
00:02:23.985 --> 00:02:27.165
and then we'll need another button to decrement

43
00:02:27.835 --> 00:02:29.525
that count.

44
00:02:30.025 --> 00:02:34.205
So let me save this, and there's our very basic interface.

45
00:02:34.225 --> 00:02:35.405
It doesn't look really great.

46
00:02:35.665 --> 00:02:38.405
It might look a little better if we added some CSS

47
00:02:38.405 --> 00:02:39.885
to the page, so let's go ahead

48
00:02:39.945 --> 00:02:42.045
and do that, and that's a little better.

49
00:02:42.235 --> 00:02:45.365
Yeah, so that's, uh, a little kitten, um, feature.

50
00:02:46.065 --> 00:02:49.765
Uh, it's has first-class support for certain libraries.

51
00:02:49.825 --> 00:02:52.005
One of those libraries is a semantic CSS

52
00:02:52.005 --> 00:02:53.125
library called Water.

53
00:02:53.425 --> 00:02:55.845
So as long as you use semantic elements, um,

54
00:02:55.905 --> 00:03:00.085
and you want a very legible, kind of usable basic, uh,

55
00:03:00.405 --> 00:03:03.885
CSS layout, then you can just say, uh, use the page tag

56
00:03:03.885 --> 00:03:05.765
and the css attribute, um,

57
00:03:05.785 --> 00:03:08.365
or the water attribute they are, uh, equivalent.

58
00:03:08.705 --> 00:03:12.205
Um, and you, uh, Kitten will include the Water library

59
00:03:12.465 --> 00:03:14.165
for you on your page as we've done here.

60
00:03:14.425 --> 00:03:16.645
Um, the only thing I would change is I probably,

61
00:03:16.865 --> 00:03:18.165
now I'm gonna do this in-line.

62
00:03:18.345 --> 00:03:22.565
Um, you don't have to, uh, do it in-line of course, um,

63
00:03:22.585 --> 00:03:25.765
but I'm just going to add, um, an inline style

64
00:03:25.945 --> 00:03:28.965
and I'll up the, uh, font size a little bit,

65
00:03:29.495 --> 00:03:31.365
maybe make it two em.

66
00:03:31.575 --> 00:03:36.365
Let's see. And oops, I accidentally

67
00:03:37.595 --> 00:03:41.005
deleted my page, uh, CSS tag over here.

68
00:03:41.025 --> 00:03:45.005
So there we go. So the, uh, font size is a little bigger,

69
00:03:45.005 --> 00:03:46.365
looking a bit nicer now.

70
00:03:46.985 --> 00:03:48.925
Now, none of this is functional, of course.

71
00:03:49.385 --> 00:03:53.285
Um, it does nothing. So, um, what do we need to do?

72
00:03:53.315 --> 00:03:57.725
Well, first of all, we need to not be hard coding this,

73
00:03:58.185 --> 00:04:00.765
uh, count that we have here.

74
00:04:00.825 --> 00:04:02.725
We want to get that from a database,

75
00:04:03.065 --> 00:04:05.565
and then we want to be able to alter that count.

76
00:04:06.025 --> 00:04:09.925
So let's, um, create, let's make sure that our, uh,

77
00:04:10.325 --> 00:04:11.325
database table exists

78
00:04:11.505 --> 00:04:15.405
and create it if it doesn't with a default count of one.

79
00:04:15.785 --> 00:04:19.085
So how do we do that? Well, Kitten has a database built in.

80
00:04:19.265 --> 00:04:21.565
Um, it's a JavaScript database, um,

81
00:04:21.585 --> 00:04:25.645
and it exposes it, uh, from the kitten.db reference.

82
00:04:25.745 --> 00:04:29.005
So we're going to say if kitten.

83
00:04:30.185 --> 00:04:32.525
db.counter, that's what we call our object

84
00:04:32.525 --> 00:04:35.285
that we're saving, um, is undefined.

85
00:04:35.985 --> 00:04:38.205
So if that's undefined, we will go ahead

86
00:04:38.945 --> 00:04:40.405
and create our default one.

87
00:04:40.405 --> 00:04:44.685
So we'll say kitten.db.counter, make it an object,

88
00:04:44.825 --> 00:04:46.765
and we'll give it a property called count

89
00:04:47.155 --> 00:04:49.125
that defaults to one.

90
00:04:49.665 --> 00:04:54.085
And then what I'm going to do here is instead of,

91
00:04:54.465 --> 00:04:58.085
uh, having this, uh, hard-coded one, I'm just going

92
00:04:58.085 --> 00:04:59.365
to use string interpolation

93
00:04:59.365 --> 00:05:01.445
because remember, this is a tag template string in

94
00:05:01.445 --> 00:05:05.525
JavaScript, and I'm just gonna say kitten dot db dot counter

95
00:05:06.145 --> 00:05:07.685
dot count.

96
00:05:08.265 --> 00:05:10.885
So if we look at the code there, that's what I did.

97
00:05:11.265 --> 00:05:15.885
Um, I'm now actually using the count from, uh, the database.

98
00:05:16.505 --> 00:05:20.845
So if I now save this, um, you'll see

99
00:05:21.355 --> 00:05:26.205
that, uh, the counter here, uh, sorry,

100
00:05:26.305 --> 00:05:27.965
let me go ahead and save this.

101
00:05:30.835 --> 00:05:32.495
Um, the counter is at six

102
00:05:33.795 --> 00:05:36.415
and there's a reason it's at six and not at one.

103
00:05:36.795 --> 00:05:40.015
And that's because I didn't actually clear out the, uh,

104
00:05:40.335 --> 00:05:42.815
database table, um, before starting this recording.

105
00:05:42.815 --> 00:05:44.215
So let's go ahead and do that now.

106
00:05:45.355 --> 00:05:49.575
So I can say kitten db, um, and delete.

107
00:05:49.635 --> 00:05:54.015
So this is a, uh, uh, um, a command

108
00:05:54.015 --> 00:05:55.895
that Kitten has in there.

109
00:05:56.475 --> 00:05:58.085
So now if I go back here

110
00:05:58.105 --> 00:06:00.165
and I save, you'll see

111
00:06:00.165 --> 00:06:03.125
that the count is at one as it should be.

112
00:06:03.745 --> 00:06:06.445
Um, so if I go and I press plus

113
00:06:06.505 --> 00:06:08.805
or minus, of course nothing is happening

114
00:06:08.995 --> 00:06:13.925
because we need to bind, uh, these buttons somehow

115
00:06:14.265 --> 00:06:17.965
to, uh, some logic that's going to, uh,

116
00:06:18.115 --> 00:06:19.725
fire on the server.

117
00:06:19.785 --> 00:06:21.605
And the way we do that is through events.

118
00:06:22.185 --> 00:06:26.925
So, um, we can have, uh, objects in the client raise events

119
00:06:27.505 --> 00:06:29.485
and, uh, handle those events on the server

120
00:06:29.745 --> 00:06:34.125
and then send updated, um, interface, uh, fragments back.

121
00:06:34.825 --> 00:06:38.285
So, um, how do we do that? Let's take a look.

122
00:06:38.825 --> 00:06:41.845
So let me switch to my editor here.

123
00:06:43.105 --> 00:06:45.645
And, uh, so the way that we do

124
00:06:45.645 --> 00:06:50.165
that is we connect those elements that we want, um, to,

125
00:06:51.345 --> 00:06:55.285
uh, listen for events on to the server using

126
00:06:56.385 --> 00:06:59.645
the connect attribute.

127
00:07:00.385 --> 00:07:04.805
Now, when we, uh, have a connect attribute, um, what we have

128
00:07:04.805 --> 00:07:09.725
to do is on the, on the server, uh, sorry, um,

129
00:07:09.945 --> 00:07:14.805
on the server, we actually have to create a on connect

130
00:07:15.765 --> 00:07:19.925
function, and we need to export

131
00:07:20.115 --> 00:07:22.645
that function from our route.

132
00:07:22.645 --> 00:07:25.325
When kitten sees this, then it goes, oh, okay,

133
00:07:25.325 --> 00:07:26.765
so there must be some connections I need to make.

134
00:07:26.765 --> 00:07:28.685
It starts looking for those connect attributes

135
00:07:28.685 --> 00:07:30.005
and then connects those two.

136
00:07:30.425 --> 00:07:32.925
And what will happen here is, um,

137
00:07:35.035 --> 00:07:37.965
when the page loads, uh, when the page connects,

138
00:07:37.985 --> 00:07:41.525
we will get this connect function called.

139
00:07:42.345 --> 00:07:44.125
So if I was to go over here

140
00:07:44.785 --> 00:07:48.085
and show you, there you go.

141
00:07:48.425 --> 00:07:50.405
Um, we could just do that again, refresh it,

142
00:07:50.405 --> 00:07:54.165
and you can see that when page connects, uh, log is,

143
00:07:54.425 --> 00:07:56.725
uh, is getting called.

144
00:07:57.705 --> 00:08:01.925
So, um, this onConnect function actually gets a reference

145
00:08:01.985 --> 00:08:04.605
to the page in its, uh, parameter object.

146
00:08:05.345 --> 00:08:08.125
And this is where we can listen for events,

147
00:08:08.785 --> 00:08:10.045
um, on that page.

148
00:08:10.505 --> 00:08:14.805
But what, um, is the event that we want to listen for?

149
00:08:15.635 --> 00:08:20.405
Well, the events, uh, are tied

150
00:08:20.625 --> 00:08:25.365
to the names of

151
00:08:26.745 --> 00:08:30.165
the elements in your DOM that, uh,

152
00:08:31.635 --> 00:08:33.205
trigger the the event.

153
00:08:33.625 --> 00:08:38.085
So if we give these buttons the name update, then

154
00:08:38.785 --> 00:08:42.085
in our onConnect, we can actually listen for

155
00:08:42.085 --> 00:08:43.485
that update event.

156
00:08:44.025 --> 00:08:48.205
So we can say page on update,

157
00:08:49.185 --> 00:08:51.405
and then we can get a handler that gets called.

158
00:08:51.915 --> 00:08:55.645
Okay, so let's create that handler as an arrow function

159
00:08:57.875 --> 00:09:00.765
over here, and let's just again log it for now

160
00:09:01.105 --> 00:09:03.245
and I'll say updates.

161
00:09:03.715 --> 00:09:06.085
Okay, cool. So we've just had an update event.

162
00:09:06.705 --> 00:09:11.005
Um, so now let me show you the, uh,

163
00:09:12.065 --> 00:09:14.565
Kitten running here again with the output.

164
00:09:15.025 --> 00:09:16.125
And if I press this,

165
00:09:16.145 --> 00:09:19.565
you can see now we're getting update events.

166
00:09:20.385 --> 00:09:22.245
Um, that's pretty cool. Okay.

167
00:09:22.825 --> 00:09:26.765
But what we wanna do is when these buttons are pressed,

168
00:09:26.825 --> 00:09:28.125
we want to do something different.

169
00:09:28.125 --> 00:09:30.645
So we need to be able to differentiate those two buttons,

170
00:09:31.185 --> 00:09:32.965
uh, the decrement and the increment.

171
00:09:33.065 --> 00:09:36.765
But so, um, the way that we can do that is we can actually,

172
00:09:37.065 --> 00:09:39.645
um, have them send some data back.

173
00:09:40.025 --> 00:09:42.645
So I'm going to say data equals,

174
00:09:43.545 --> 00:09:46.925
and I'll have them send back a function, yeah, sorry,

175
00:09:46.945 --> 00:09:49.525
an object that has a value property.

176
00:09:50.705 --> 00:09:55.325
And for the decrement button, we'll make that a minus one.

177
00:09:55.345 --> 00:09:57.805
And for the increment button, we'll make that a one.

178
00:09:58.385 --> 00:10:03.165
Now, here when, um, in our handler, uh, that receives

179
00:10:03.165 --> 00:10:07.725
that data, um, uh, property that, um,

180
00:10:08.105 --> 00:10:12.925
the buttons have as the, uh, data, um, parameter,

181
00:10:13.625 --> 00:10:18.325
um, so let's just log what that,

182
00:10:18.895 --> 00:10:20.805
sorry, sorry.

183
00:10:20.895 --> 00:10:24.205
There we go. Let's log that data

184
00:10:24.715 --> 00:10:26.685
attribute over here.

185
00:10:28.145 --> 00:10:30.125
And, uh, I'll just go ahead

186
00:10:30.505 --> 00:10:33.245
and show you again the console.

187
00:10:34.425 --> 00:10:38.205
Now, if I press the plus button, you can see update

188
00:10:38.225 --> 00:10:40.565
and we get this, um, object here.

189
00:10:41.065 --> 00:10:42.525
And all of these are headers.

190
00:10:42.705 --> 00:10:44.845
Uh, those of you that know HTMX,

191
00:10:44.845 --> 00:10:46.565
that's what's working behind the scenes.

192
00:10:47.105 --> 00:10:51.525
Um, and uh, we get the value of one, if I press the minus,

193
00:10:51.585 --> 00:10:54.565
you'll see the value is minus one.

194
00:10:55.115 --> 00:10:58.445
Okay? So I guess, uh, it's very clear what we need

195
00:10:58.445 --> 00:11:03.365
to do now, which is that we need to, um,

196
00:11:04.425 --> 00:11:07.645
update the kittens, uh, the counter dot count.

197
00:11:08.505 --> 00:11:12.205
So here I am gonna go ahead

198
00:11:13.425 --> 00:11:17.925
and, uh, say, okay, uh, kitten,

199
00:11:18.705 --> 00:11:22.525
dot db dot counter, dot count plus equals,

200
00:11:23.185 --> 00:11:27.205
and I'll say, uh, data dot value.

201
00:11:28.185 --> 00:11:33.085
And again, for now, let's just log, um, the,

202
00:11:33.185 --> 00:11:35.725
the new value, the new count, okay?

203
00:11:36.385 --> 00:11:40.965
And we'll just log kitten db dot counter dot count.

204
00:11:41.865 --> 00:11:43.885
So now we're just gonna log that.

205
00:11:44.865 --> 00:11:47.245
Uh, so if I go ahead and press, there we go.

206
00:11:47.255 --> 00:11:52.085
Count is 3, 4, 5, 6, count is two. Okay?

207
00:11:52.545 --> 00:11:55.565
So what's not happening right now is

208
00:11:55.625 --> 00:11:58.965
of course our counter on the display is not being updated.

209
00:11:59.585 --> 00:12:04.525
So, um, in order to update that, what we need to do is,

210
00:12:04.905 --> 00:12:09.085
uh, send this piece of the interface again,

211
00:12:09.585 --> 00:12:11.525
the div that has the count.

212
00:12:12.185 --> 00:12:16.565
Um, so the simplest way we can do that just

213
00:12:16.565 --> 00:12:20.125
to see it working is to copy and paste it, of course.

214
00:12:20.985 --> 00:12:24.205
So here, um, I'm going to go

215
00:12:24.305 --> 00:12:26.605
and say page sent.

216
00:12:26.605 --> 00:12:29.365
So I'm gonna call this sent method that you get on the page

217
00:12:29.965 --> 00:12:32.445
reference that you're provided on your on connect handler.

218
00:12:32.985 --> 00:12:37.125
Um, and I'm going to send the, uh,

219
00:12:38.075 --> 00:12:40.445
oops, let's go and copy the right thing.

220
00:12:41.365 --> 00:12:46.125
I am going to send, uh, sorry, let's just, uh,

221
00:12:46.465 --> 00:12:48.205
go and copy that properly.

222
00:12:50.175 --> 00:12:54.485
There we go. I'm going to send this, um,

223
00:12:58.515 --> 00:13:02.685
this piece of HTML, which is again, kitten html.

224
00:13:02.955 --> 00:13:07.445
Okay? So I'm just sending this same div

225
00:13:08.235 --> 00:13:12.085
back, but kitten doesn't really have a way of knowing

226
00:13:12.085 --> 00:13:13.365
that it's the same div yet

227
00:13:13.795 --> 00:13:17.285
because, um, I could have another div here, right?

228
00:13:18.065 --> 00:13:19.285
Uh, hello.

229
00:13:20.625 --> 00:13:23.885
Um, and it doesn't know this div from that div

230
00:13:23.905 --> 00:13:25.645
unless we give it an id.

231
00:13:25.745 --> 00:13:27.125
So that's what I'm gonna do here.

232
00:13:27.225 --> 00:13:29.765
So I'll say id equals count,

233
00:13:30.785 --> 00:13:32.285
and I'll go down here as well

234
00:13:32.585 --> 00:13:36.205
and say, id equals count.

235
00:13:36.665 --> 00:13:38.325
Now it knows it's the same div and it,

236
00:13:38.325 --> 00:13:39.565
and it should replace it.

237
00:13:40.065 --> 00:13:44.165
So now if I go over here and I, oh, there we go, increment

238
00:13:44.545 --> 00:13:46.925
and decrement and it's all working.

239
00:13:47.065 --> 00:13:48.845
So we could leave it here and call it a day.

240
00:13:49.105 --> 00:13:51.925
Wow, a counter streaming HTML from the server

241
00:13:52.425 --> 00:13:54.885
to the client in response to events on the client.

242
00:13:54.945 --> 00:13:56.765
That's pretty cool. Um,

243
00:13:57.905 --> 00:14:01.005
but uh, we can make this a little nicer.

244
00:14:01.665 --> 00:14:04.245
Uh, so first and foremost, what's the problem?

245
00:14:04.945 --> 00:14:09.005
Uh, well, you can see that we have replication here

246
00:14:09.075 --> 00:14:10.765
between these two divs, right?

247
00:14:10.765 --> 00:14:12.325
Between this one and the other one.

248
00:14:12.865 --> 00:14:16.885
So what we can do is we can create a fragment.

249
00:14:17.845 --> 00:14:20.165
A fragment is pretty much the same as a component.

250
00:14:20.665 --> 00:14:24.045
And in Kitten, the way that you do that is,

251
00:14:24.345 --> 00:14:25.685
um, with a function.

252
00:14:25.985 --> 00:14:29.205
So fragments and components are functions in Kitten.

253
00:14:29.545 --> 00:14:32.925
So I'm gonna go over here and I'm going to say function.

254
00:14:33.945 --> 00:14:35.565
Um, and let's call it Count.

255
00:14:35.565 --> 00:14:36.805
That's the name of our fragment.

256
00:14:37.625 --> 00:14:40.525
Um, and the only difference, uh, between a fragment

257
00:14:40.665 --> 00:14:43.045
and a component by the way, is, uh, whether

258
00:14:43.105 --> 00:14:46.045
or not you'll be reusing it on a page multiple times,

259
00:14:46.465 --> 00:14:47.765
if you are, it's a component

260
00:14:48.225 --> 00:14:50.325
and you would pass each one of them a separate id,

261
00:14:50.325 --> 00:14:54.085
for example, whereas a fragment is, uh, a piece of, uh,

262
00:14:54.115 --> 00:14:56.565
interface that will appear only once on your page.

263
00:14:57.025 --> 00:14:59.685
Um, and so you can hardcode an id for example,

264
00:15:00.025 --> 00:15:02.565
and it won't be reused many times on there.

265
00:15:02.565 --> 00:15:03.645
That's really the only difference,

266
00:15:03.645 --> 00:15:06.165
otherwise they're exactly, exactly the same.

267
00:15:06.825 --> 00:15:08.605
So, um, I'm gonna go ahead

268
00:15:08.985 --> 00:15:12.645
and, uh, create this function called count

269
00:15:13.145 --> 00:15:15.645
and it will return some Kitten HTML.

270
00:15:17.705 --> 00:15:21.365
And uh, there we go.

271
00:15:22.185 --> 00:15:24.005
And what is the Kitten HTML we wanna return?

272
00:15:24.155 --> 00:15:27.725
Well, again, it is this, um, piece

273
00:15:27.765 --> 00:15:29.685
of code that we have here.

274
00:15:30.795 --> 00:15:34.765
Okay, so, uh, then we can go ahead and,

275
00:15:34.765 --> 00:15:37.565
and if you want to, of course you can very easily just make

276
00:15:37.565 --> 00:15:39.645
this an arrow function as well, right?

277
00:15:39.645 --> 00:15:43.005
So I could have just said constant count equals,

278
00:15:45.145 --> 00:15:48.605
and then just return that, um, Kitten HTML directly.

279
00:15:48.605 --> 00:15:51.165
So if that's, if that's more your style of doing things,

280
00:15:51.235 --> 00:15:52.285
then go ahead

281
00:15:52.285 --> 00:15:56.485
and use, uh, use, uh, closures, um, if it's less code,

282
00:15:56.565 --> 00:16:00.085
I guess so, alright, um, let's go ahead

283
00:16:00.145 --> 00:16:03.565
and instead of this diff here, use that fragment.

284
00:16:04.505 --> 00:16:06.245
So we are gonna start a tag

285
00:16:06.305 --> 00:16:10.245
and we're gonna use, uh, just again, um,

286
00:16:11.095 --> 00:16:14.005
basic interpolation, string interpolation to put the name

287
00:16:14.505 --> 00:16:18.085
of the, uh, component or fragment in this case.

288
00:16:18.385 --> 00:16:21.765
And the only difference between regular tags and fragments

289
00:16:21.765 --> 00:16:23.645
and components is that you do have

290
00:16:23.845 --> 00:16:25.565
to close the tag as you can see here.

291
00:16:26.425 --> 00:16:30.165
So I'm going to here as well

292
00:16:31.345 --> 00:16:32.845
now just replace that.

293
00:16:33.385 --> 00:16:37.365
Oh, sorry, actually lemme just replace the, uh, Kitten

294
00:16:37.365 --> 00:16:38.565
HTML I'm sending back.

295
00:16:38.745 --> 00:16:42.725
So I'm gonna replace that with the count

296
00:16:43.315 --> 00:16:45.605
that I have here.

297
00:16:46.145 --> 00:16:47.925
So there we go.

298
00:16:48.305 --> 00:16:50.285
So we're just sending that fragment back

299
00:16:50.505 --> 00:16:54.165
and that fragment gets the count from the database.

300
00:16:54.465 --> 00:16:58.805
So all we've really done is we have, um, refactored,

301
00:16:58.985 --> 00:17:00.765
so it should work exactly the same way.

302
00:17:01.185 --> 00:17:05.685
And here you can see that it does. Alright, again,

303
00:17:05.685 --> 00:17:06.685
we could call it a day,

304
00:17:07.225 --> 00:17:09.845
but, um, you know, that wouldn't be great

305
00:17:09.845 --> 00:17:11.685
because we haven't really tested it

306
00:17:11.685 --> 00:17:13.125
for accessibility, have we?

307
00:17:13.505 --> 00:17:15.685
Um, so is this a very accessible, uh,

308
00:17:15.915 --> 00:17:17.525
counter we don't know yet.

309
00:17:17.905 --> 00:17:21.445
Now I am running this right now under Fedora Linux

310
00:17:21.625 --> 00:17:24.925
and unfortunately, uh, Fedora Silverblue actually,

311
00:17:25.145 --> 00:17:28.685
and unfortunately Fedora Silverblue, like a lot of, uh,

312
00:17:29.265 --> 00:17:32.885
the main Linux distributions that exist today that default

313
00:17:32.885 --> 00:17:34.925
to Wayland, uh, is inaccessible.

314
00:17:35.145 --> 00:17:38.605
Uh, the, uh, screen readers that they come with, um,

315
00:17:38.625 --> 00:17:41.045
are broken and they have been for a while now,

316
00:17:41.045 --> 00:17:42.965
which is a terrible state of affairs, of course.

317
00:17:42.995 --> 00:17:45.725
It's, it's completely unacceptable, especially considering

318
00:17:45.725 --> 00:17:48.605
that of course, um, Linux is not just a volunteer effort

319
00:17:48.665 --> 00:17:51.845
by people who work on it in the afternoons or after work

320
00:17:51.865 --> 00:17:53.365
or whatever in the evenings.

321
00:17:53.665 --> 00:17:57.485
Um, it's, uh, there are many corporations, some

322
00:17:57.485 --> 00:17:58.645
of them trillion dollars, some

323
00:17:58.645 --> 00:18:01.325
of them a hundred million dollar corporations, uh,

324
00:18:01.325 --> 00:18:02.445
that profit from Linux.

325
00:18:02.445 --> 00:18:04.285
So it is a really terrible state of affairs.

326
00:18:04.585 --> 00:18:06.645
So unfortunately I'm gonna have to switch into Windows

327
00:18:06.865 --> 00:18:09.765
to show you… to test the accessibility, um,

328
00:18:09.785 --> 00:18:11.845
and Windows, which of course Linux people really

329
00:18:11.845 --> 00:18:12.965
don't like Windows that much.

330
00:18:13.305 --> 00:18:15.685
Um, but uh, you know, it's uh, I guess

331
00:18:16.355 --> 00:18:19.845
it's quite embarrassing that, um, windows is accessible

332
00:18:19.865 --> 00:18:22.445
and Linux isn't right now, so most Linux,

333
00:18:22.515 --> 00:18:24.285
most main Linux distributions anyway.

334
00:18:24.785 --> 00:18:26.685
Ooh, hope that changes soon.

335
00:18:26.985 --> 00:18:29.445
Um, so anyway, um, let's go ahead

336
00:18:29.665 --> 00:18:31.725
and skip into, uh, windows.

337
00:18:32.505 --> 00:18:35.445
Um, and, uh, we can use that

338
00:18:36.065 --> 00:18:37.965
to test our accessibility.

339
00:18:38.985 --> 00:18:43.325
So here I am with um, Microsoft Edge on Windows.

340
00:18:43.785 --> 00:18:46.645
Uh, so, uh, of course this is a different computer.

341
00:18:47.185 --> 00:18:49.685
So, um, here's uh, what I need to do.

342
00:18:49.925 --> 00:18:54.285
I can't actually, uh, I can't actually

343
00:18:55.145 --> 00:18:58.525
go ahead and, uh, access local host from there.

344
00:18:58.665 --> 00:19:02.725
So right now Kitten is running on local host, right?

345
00:19:03.145 --> 00:19:06.965
Um, so what I am gonna do is I'm going to say, uh,

346
00:19:07.655 --> 00:19:08.965
lemme just see if it's running.

347
00:19:09.315 --> 00:19:13.005
Nope. I'm going to quickly, uh, run

348
00:19:13.725 --> 00:19:18.165
uh WireGuard, uh, and create a VPN to my testing, um,

349
00:19:18.385 --> 00:19:20.365
and staging server dev.ar.al.

350
00:19:20.985 --> 00:19:24.405
Um, and I'm going to run kitten,

351
00:19:25.825 --> 00:19:29.925
um, at dev.ar.al.

352
00:19:30.865 --> 00:19:35.485
Uh, so there we go. Let's run it at that domain. And here.

353
00:19:35.825 --> 00:19:38.405
Now, if I want to access it here, I'd have to go to dev

354
00:19:38.425 --> 00:19:43.205
dot ar.al, and, uh, anyone who like currently right now,

355
00:19:43.205 --> 00:19:45.325
if there was someone hitting the site dev.ar.al,

356
00:19:45.325 --> 00:19:47.765
they would actually see this running on my computer as well.

357
00:19:48.185 --> 00:19:50.965
So let's leave that at seven, for example.

358
00:19:51.825 --> 00:19:55.925
And, uh, now I can switch to my

359
00:19:57.155 --> 00:19:58.325
Windows machine.

360
00:19:58.865 --> 00:20:00.485
Um, it's running in a virtual machine

361
00:20:00.945 --> 00:20:04.685
and I can go to dev.ar.al

362
00:20:05.065 --> 00:20:06.765
and we've got the same counter there.

363
00:20:06.765 --> 00:20:08.565
And I'm just gonna turn on Narrator

364
00:20:09.995 --> 00:20:13.165
[Narrator] Counter profile one, Microsoft Edge window counter,

365
00:20:13.645 --> 00:20:15.165
Microsoft Edge, region counter.

366
00:20:15.955 --> 00:20:17.885
[Aral] Okay, Cool. [Narrator] Counter at level one,

367
00:20:18.345 --> 00:20:19.345
[Aral] That's cool. [Narrator] Seven,

368
00:20:19.345 --> 00:20:20.565
[Aral] we've got the count

369
00:20:20.875 --> 00:20:24.045
[Narrator] Plus sign button, [Aral] “Plus sign button,” not that great

370
00:20:24.605 --> 00:20:25.605
[Narrator] Hyphen button.

371
00:20:25.705 --> 00:20:27.485
[Aral] Ooh “hyphen button.” Really terrible.

372
00:20:28.265 --> 00:20:33.165
Um, okay, so let's go ahead and uh, fix the hyphen button

373
00:20:33.545 --> 00:20:36.845
and the plus sign button issue first of all.

374
00:20:37.235 --> 00:20:41.605
Okay, so, uh, let me go back to my Linux machine here

375
00:20:42.865 --> 00:20:45.885
and I'm going to go over, um, here

376
00:20:45.985 --> 00:20:48.165
and take a look at my markup.

377
00:20:48.305 --> 00:20:49.525
So what's going on here?

378
00:20:50.435 --> 00:20:53.365
Well, for one thing that's not a minus sign,

379
00:20:53.585 --> 00:20:55.645
you could actually make it a minus sign,

380
00:20:55.905 --> 00:20:57.605
but uh, when I was testing earlier,

381
00:20:58.085 --> 00:21:00.925
Narrator actually then doesn't read anything at all.

382
00:21:01.105 --> 00:21:05.205
It doesn't understand the actual minus sign, uh, glyph.

383
00:21:05.665 --> 00:21:08.245
Um, so different, uh,

384
00:21:08.945 --> 00:21:11.285
screen readers have different ways of handling these things.

385
00:21:11.825 --> 00:21:14.925
So to be sure, let's do this.

386
00:21:15.305 --> 00:21:18.125
Uh, let's first of all, um, go ahead

387
00:21:18.905 --> 00:21:23.125
and write these out in a slightly more verbose

388
00:21:23.795 --> 00:21:27.765
fashion so that we can, you know, really see our, uh,

389
00:21:28.945 --> 00:21:32.365
really see our attributes here that we have.

390
00:21:33.505 --> 00:21:36.005
Um, and it doesn't just become a mess on this narrow

391
00:21:36.025 --> 00:21:37.565
screen that we're working on.

392
00:21:38.145 --> 00:21:42.725
And, uh, then let's add, uh, an aria-label, um, for these,

393
00:21:43.275 --> 00:21:45.885
okay, so I'm just gonna go ahead

394
00:21:46.425 --> 00:21:50.085
and over here, say aria-label

395
00:21:51.825 --> 00:21:54.005
equals, okay.

396
00:21:54.985 --> 00:21:57.125
And, uh, for the decrement button,

397
00:21:57.155 --> 00:21:59.285
I'll just call it ‘decrement.’

398
00:22:00.545 --> 00:22:04.285
And for the, uh, increment button, I'll call it ‘increment.’

399
00:22:05.425 --> 00:22:08.285
So let's see what that's like.

400
00:22:08.355 --> 00:22:09.605
[Narrator] Loading, page loading.

401
00:22:09.885 --> 00:22:12.405
Complete counter, counter has finished loading.

402
00:22:12.475 --> 00:22:13.685
Counter, counter.

403
00:22:14.795 --> 00:22:17.285
[Aral] Okay, so sorry about that.

404
00:22:17.825 --> 00:22:21.725
Let me go over and switch into my windows. There we go.

405
00:22:22.265 --> 00:22:25.405
Um, so let's go ahead and see what it read it as now.

406
00:22:25.545 --> 00:22:27.325
[Narrator] Count- sev- increment button.

407
00:22:27.665 --> 00:22:29.205
[Aral] That's nice. [Narrator] Hyphen button.

408
00:22:30.165 --> 00:22:32.765
[Aral] Hyphen button. That's not great. What happened?

409
00:22:33.215 --> 00:22:37.645
Let's take a look. Um, so we have increment over here

410
00:22:38.385 --> 00:22:43.165
and aria-label, ooh, I must have deleted the quote there.

411
00:22:44.545 --> 00:22:45.645
So loading, let's

412
00:22:45.645 --> 00:22:48.645
Go back [Narrator] Loading complete [Aral] Okay,

413
00:22:49.475 --> 00:22:52.045
[Narrator] Counter- sev- increment button,

414
00:22:52.645 --> 00:22:54.645
hyphen plus sign.

415
00:22:54.815 --> 00:22:56.645
[Aral] Sorry, let's just go back and do this again.

416
00:22:56.755 --> 00:22:59.925
[Narrator] Increment button. Decrement button [Aral] There we go.

417
00:22:59.925 --> 00:23:01.485
[Narrator] Increment button plus.

418
00:23:01.625 --> 00:23:04.685
Um, okay, so that's, that's pretty cool. [Narrator] Seven

419
00:23:04.685 --> 00:23:07.005
At level one- Increment button.

420
00:23:07.185 --> 00:23:11.285
[Aral] Now if I actually press these buttons though, ah,

421
00:23:11.635 --> 00:23:12.845
then we have a problem [Narrator] Decrement.

422
00:23:14.775 --> 00:23:17.605
[Aral] We're not hearing any of the updates that are happening.

423
00:23:18.065 --> 00:23:20.365
So, um, that's the final thing that we need to fix.

424
00:23:20.425 --> 00:23:22.205
In order to make this accessible, we need

425
00:23:22.205 --> 00:23:25.485
to actually have the screen reader read, um, the updates,

426
00:23:25.985 --> 00:23:27.245
uh, that are happening [Narrator] Not…

427
00:23:27.245 --> 00:23:28.245
On Table. [Aral] So

428
00:23:28.245 --> 00:23:30.485
let's go ahead and, uh,

429
00:23:31.105 --> 00:23:33.445
and have that happen. So [Narrator] at toolbar

430
00:23:33.625 --> 00:23:37.325
Settings and more alt and F button is pop

431
00:23:37.325 --> 00:23:38.325
Up. [Aral] Alright, Narrator's

432
00:23:38.325 --> 00:23:40.085
still reading stuff in the background.

433
00:23:40.745 --> 00:23:44.005
Um, okay, so let's, uh, let's do that.

434
00:23:44.495 --> 00:23:49.405
Let's go ahead and, uh, the way

435
00:23:49.405 --> 00:23:51.125
that we do that is we use an aria-live,

436
00:23:51.185 --> 00:23:52.685
we define an aria-live region

437
00:23:52.785 --> 00:23:54.045
for the region that's changing.

438
00:23:54.785 --> 00:23:59.205
And in this case, that is the div that has the, um,

439
00:23:59.985 --> 00:24:02.005
so let's go ahead and actually make

440
00:24:02.005 --> 00:24:04.125
that div a little easier to read as well.

441
00:24:05.465 --> 00:24:08.045
And uh, so this is the div that's changing.

442
00:24:08.145 --> 00:24:10.245
The count is changing. So if we just go in here

443
00:24:10.265 --> 00:24:13.765
and we say aria-live equals assertive

444
00:24:13.835 --> 00:24:15.325
because it's very important.

445
00:24:15.355 --> 00:24:18.565
This is, you know, the main, uh, [Narrator] Loading

446
00:24:18.565 --> 00:24:19.885
Page, five [Aral] reason It exists,

447
00:24:19.885 --> 00:24:22.285
[Narrator] Loading complete counter has finished loading.

448
00:24:22.425 --> 00:24:23.445
[Aral] So let's go ahead

449
00:24:24.105 --> 00:24:29.045
and move to Windows. [Narrator] Counter. [Aral] There we go.

450
00:24:29.825 --> 00:24:34.525
Um, [Narrator] (indecipherable) No next item… five… at level one. Heading level

451
00:24:34.525 --> 00:24:37.045
one count five [Aral] our counter [Narrator] Increment button.

452
00:24:37.135 --> 00:24:41.605
[Aral] Let's increment [Narrator] 6, 7, 8, 9.

453
00:24:41.745 --> 00:24:44.965
[Aral] That's working [Narrator] Decrement 8, 7, 6.

454
00:24:45.275 --> 00:24:48.325
[Aral] Okay, so that's working too now.

455
00:24:48.905 --> 00:24:52.805
Um, and so, uh, as you can see in

456
00:24:53.825 --> 00:24:57.765
how many lines of code do we have here, uh, in about

457
00:24:58.665 --> 00:25:01.885
36 lines of very, um,

458
00:25:02.675 --> 00:25:04.405
well spaced code, um,

459
00:25:05.705 --> 00:25:09.245
we basically created a streaming HTML uh,

460
00:25:11.515 --> 00:25:15.925
counter, um, where, um, our, um,

461
00:25:16.795 --> 00:25:19.605
interface is being updated from the server. State is always

462
00:25:19.925 --> 00:25:21.125
maintained on the server.

463
00:25:22.105 --> 00:25:25.965
And, uh, so hopefully this gives you some idea

464
00:25:26.305 --> 00:25:29.965
of the new Streaming HTML feature in Kitten.

465
00:25:29.965 --> 00:25:32.565
There is more to it and there is more that is going to come

466
00:25:32.565 --> 00:25:34.445
to, uh, that's going to be implemented.

467
00:25:35.425 --> 00:25:39.125
Um, and uh, behind the scenes if you wanna look into it, uh,

468
00:25:39.185 --> 00:25:41.125
go onto the Kitten website and look into it.

469
00:25:41.125 --> 00:25:44.525
Behind the scenes it's using HTMX, it's using WebSockets

470
00:25:44.865 --> 00:25:46.645
and it's using some syntactic sugar

471
00:25:46.675 --> 00:25:48.485
that is unique to Kitten.

472
00:25:48.745 --> 00:25:50.285
So I hope you enjoyed this video

473
00:25:50.905 --> 00:25:53.125
and um, I hope you'll check out Kitten

474
00:25:53.225 --> 00:25:54.645
and I hope you’ll have a little play

475
00:25:54.645 --> 00:25:56.405
with the Streaming HTML workflow

476
00:25:56.465 --> 00:25:57.965
and let me know what you think.

477
00:25:58.225 --> 00:25:59.525
Thanks. Take care.
