📺 Develpreneur YouTube Episode

Video + transcript

Thymeleaf - Loops and String Concatenation

2023-12-19 •Youtube

Detailed Notes

We are continuing a series of tutorials focused on Spring Boot. The crux of the project is to convert/migrate an old JSP/Tomcat application to a modern Spring Boot application and Java 7/8 to a current version. Thymeleaf is an important piece of Spring Boot applications. In this episode, we explore iterating over a collection (list) and related variables as well as building strings with Thymeleaf.

You can learn more through our online classes at https://school.develpreneur.com and register for free. Registration will add you to our email list, and you will periodically receive coupons for courses and notifications of the latest releases.

Transcript Text
[Music]
well hello and welcome back we are
continuing working on our app that we
have moved around uh we moved it over
from playing from a patchy Tomcat old
school Java server Pages all that kind
of good stuff into a modern new fangled
bootstrap 5 and spring boot uh
Standalone
application uh Standalone web
application and this episode we're going
to look uh we're going to get back into
time Leaf a little bit because what we
want to do is we want to be able to
generate this in time Leaf now uh let me
go ahead and log out here and if you
remember last time we were playing
around with stuff we've got some Basics
showing up here as far as our login and
registration information we're able to
store some stuff but there were some
additional things that we needed to do
for example here we have a whole list of
objects and so what we want to do is
want to be able to iterate over the list
and using time Leaf uh within there
generate this uh the HTML behind this so
we're going to have a couple things
we're going to look
at and I want to start with the the
iteration itself so if we do something
very simple we can do within a like in
this case a div we can do a th for the
time Leaf colon each and what it's going
to do is it's going to say for this
value that I sent across so list
projects which if I look at the uh hello
controller that is an attribute that
I've added so I have list
projects and here I'm just using a Dao
so I go in I generate a list of these
you know just an actual Java list of
projects if you look at list current uh
and the project Dao implementation let's
just go look that real quick and you can
see here all we're doing is we're just
doing a select and then we're going to
return a jdpc template actually within
that it's going to take that query it's
going to go to the row mapper which if
we go to Project row mapper then you can
see so for each of these it's just it's
going to create a project right here if
you see at the top of the
line and then we just assign out all the
values based on the result set we pass
it a result set it gives us out a
project for each row and so this is and
we've talked about I think this
separately we but it's a something we'll
go in deeper at another Point as far as
using row mappers but it's a pretty
straightforward way to get from our our
query which basically just says Hey like
I've got a column name project I or
project ID it's an INT I'm going to set
the ID for the project class the project
instance and with the r mapper just for
each row it's going to go through and do
that and then that's going to kick that
back out to my list which going to pick
kick it out to my
controller and I can see here where I'm
adding a bunch of different
attributes now some of these I think
we'd already looked at before so I'm
basically just going in here putting a
little bit information um actually here
the user is USR so I can probably do let
me go look at that real quick because
that was one of the things I wanted to
do if I look at user does he have a get
display name he
has uh he does not have he has a
username let's just do first name so if
we go to the
dashboard uh one of the things we do is
it's dashboard for here but what we
really want this to
be is uh
user we're just going to do th
text
equals
I'll put that
there and it's going to be uh what do we
call first name I
think let's see if that works uh
probably if I do it like
this okay anyways slight side trip there
uh let's go back to our Loop so in our
Loop the most basic version is going to
be whatever the attribute is and then
you're going to sign it a value so what
what I've done here which we'll talk
about a second so if
I if I come here and let me do this let
me just get rid of
that and here this is most simple thing
let me make sure this still works that I
didn't break something in my
demo so if I log in boom it gives
me these uh these entries but it looks
like I probably blew something up in
[Music]
there not sure
oh oh no there's
that okay well oh it's because of the
way it's set up in the
diff um so I don't have a lot of
information about that oh and that was
because here is that where it
is uh I think that might be it so
let's uh let's see can I get reduce
it
sorry d g it all right I lost it um well
let's do it for here cuz what I want is
class equals
row so we'll come back to this in a
second okay so if I do
that and I'll show you in a second what
this looks like when it loads there we
go so now I've got each of these values
on a row but what I want to do is
something like this I want to actually
give myself like some background and do
a couple other things within uh with
this data and what we can do there is
what I did before is we have a second
value which we'll call status and you
can name it whatever you want you call
it status I've seen it I status and
things like
that and uh it has
did I get rid of that I did oh there it
is it has the status itself has a bunch
of different properties it's got count
size first last odd even and so what we
can do is we can actually tweak the
class itself and this is a CSS style
class so we have to have it you know set
up properly but if I have an even and an
odd for my rows then what I can do
is there's a couple ways I can look at
it in this one I'm going to say index
oops which is also one I can do the
index which says which row number am I
on so count tells me the total number of
rows and uh so for example I could
say h I probably don't want to do it
within
this yeah I'm not going to do it within
this uh but it'll give me but so for my
index I can give each row so if I had
five if I have five uh result rows in
this result set then I've got 1 2 3 4 5
are my indexes or actually I'm sorry 0 1
2 3 4 it starts with zero and basically
I'm just doing a mod here which says
divide by two and what is the remainder
and so the remainder when you divide by
two is either going to be zero or one so
if it's zero it's an even row and if
it's odd it's an odd row so now if I do
that what I'm going to
get is my little zebra stripe thing boom
because now it's going to go and if you
look how easy you're going to be able to
read this but if you look in here you
can see where it says row even row odd
it's a little bit small text but there
you go so row odd and row even is how
it's generating that so now I can get my
little stripe now the other thing I want
to do is I want to be able to add a
click which is fun oh before I do that
the way I'm going through is each one of
these it goes through projects and
assigns it to this project variable so
if you note here I can do project do
whatever and in this case projects
are uh here it is just a straight up
pojo so what I got
here any one of these as long as it has
a get so if I come in here and I look
down here like get
fixed fixed is a value that I could use
here am I using it on here let's find
out uh I am so that is the second from
last column if we look at it here we go
this is the
fixed fixed
created oh I'm sorry it's up here second
to last here is it fixed and then you
can see the creative value so all you
have to do and what it's going to do is
just going to assume that this is a git
whatever and you do have uh let me go
back to where my project
was
oh do I have status string I think I
do there we go status string so it is um
case sensitive and it's going to assume
that your format is going to be
basically it's going to assume that it's
get and set get get and set and then
it's going to assume that the next
character after the get or the set is
going to be a uppercase even though
you're going to do it in lowercase so
like you can see like get name is
actually get name with a capital
in however and then if you want
additional words within there if it's
camel case like here bid amount is get
bid capital B amount capital A but if
you don't have it like I do here this is
not treated as two separate words and
you'll see it's going to look for get
status capital S string lowercase s and
that's because here wherever I put that
I don't have the capital S otherwise I
need to do that if I capitalize that in
one case or other we're going to have a
a disconnect so now I can load my values
in and let's do one more thing within
this playing around with uh some of the
values we've
got is I can actually add an
event and in this case
I'm going to do an
onclick and I'm going to do it based on
the I think I called it project so I'm
going to do it based on the project ID
if I spell project correctly so I'm just
going to do project do ID now there's a
couple of ways let me show you this and
I'm going to come back to how I just did
that so now if we look
if we look
here we can see that we've got this on
click or actually it's a yeah we have
the onclick and it does a select project
and it gives you the ID which is the
project the ID for that project so that
that way we can actually click through
we have an event now notice that here
we've got these old
pipes and this is excellent if you're
building a string that has within it
only uh Boolean or
integer values so here this project ID
because it is an INT it allows me to
just refer to build a hard string which
is basically it says because I'm between
the
pipes use this this string that's right
here and then I can go in and I can just
do a straight with the uh you know the
squiggly brackets dollar squiggly
brackets and then the name or the
variable name but if I take this and I
change it to name which is a
string it's going to not like
that and there we go and I'm going to
get an error because I've got a mapping
issue so I want to keep that as an
INT and there are a couple of ways that
we can put strings together uh this one
is going to be probably one of our
easier ways there are as far as like if
I just want to build like in this case
something where I'm sending an an ID if
I want to do it with the name itself
then I'm going to have to come in and do
something
like uh let's see I can do oh did I have
my user let me rebuild this let me do
here uh where is here we go so I can do
user first name oh because I did that
here so this is
oh I bet it's not liking it let's see
what did it do let's see what I got here
and it may be because it I needed that
in because it was part of the uh the
JavaScript that I was
using which I apologize for if I come in
here let's see what does it give me for
the dashboard for Rob yes so it does
pickup user. first name and I can do I
believe it's like
this since I'm within uh a pipe
uh
user. last
name and if I rebuild
it what does it give
me and there we go so it gives me first
name last name so I can I can either
just do a a straight variable like if we
want to do just user first name or I can
actually build a string within that base
based on those there's a couple other
ways we could do stuff if we wanted to
build it on a display uh we could do it
within the th text and try to make it
work that way or we could like you know
put a couple spans together or something
like that if it's just a simple uh
display of a name or you know a string
or a series of strings so there's a
couple different ways we can uh skin
that cat as it were but right now I just
wanted to sort of say hey this is like
dive in and talk a little bit about
the couple more of the uh timely uh
things and um I'm just going to get rid
of some of my oh that's not going to
like that but I need to get rid of my
ch's
uh okay any or I'm sorry my C colons not
my ch's and uh um I wonder if I have
some
more okay good I got rid of all of
those and now since that if's not
there when I log in I'm going to see
those those
fields yep dashboard and then if there's
a message it's going to show up but
there isn't a message right now so
that'll do it for now we will come back
and there are some more there are some
more things that we can do within time
Leaf but I want to get that basic one
laid out and and uh we're just going to
continue along next episode we will uh
continue building out our application
and just keep on going until we have
something that is functional and have
covered most of our pieces to convert
our app over if you have any questions
shoot us an email at info@ developer.com
and otherwise whether you have questions
or not I want you to go out there and
have yourself a great day a great week
and we will talk to you next
time
[Music]
Transcript Segments
1.35

[Music]

27.279

well hello and welcome back we are

30.08

continuing working on our app that we

31.96

have moved around uh we moved it over

34.6

from playing from a patchy Tomcat old

38.12

school Java server Pages all that kind

40.079

of good stuff into a modern new fangled

43.52

bootstrap 5 and spring boot uh

46.879

Standalone

48.199

application uh Standalone web

50.44

application and this episode we're going

52.48

to look uh we're going to get back into

53.96

time Leaf a little bit because what we

55.719

want to do is we want to be able to

58.32

generate this in time Leaf now uh let me

61.519

go ahead and log out here and if you

64

remember last time we were playing

64.96

around with stuff we've got some Basics

67

showing up here as far as our login and

69.64

registration information we're able to

71.439

store some stuff but there were some

74

additional things that we needed to do

75.56

for example here we have a whole list of

78.479

objects and so what we want to do is

80.56

want to be able to iterate over the list

82.759

and using time Leaf uh within there

85.56

generate this uh the HTML behind this so

89.92

we're going to have a couple things

90.72

we're going to look

91.92

at and I want to start with the the

95.479

iteration itself so if we do something

98.52

very simple we can do within a like in

102.439

this case a div we can do a th for the

104.759

time Leaf colon each and what it's going

107.6

to do is it's going to say for this

110.799

value that I sent across so list

112.84

projects which if I look at the uh hello

117.719

controller that is an attribute that

119.68

I've added so I have list

123

projects and here I'm just using a Dao

127.079

so I go in I generate a list of these

129.44

you know just an actual Java list of

132.84

projects if you look at list current uh

135.56

and the project Dao implementation let's

138.8

just go look that real quick and you can

141.44

see here all we're doing is we're just

145.16

doing a select and then we're going to

147.319

return a jdpc template actually within

150.879

that it's going to take that query it's

155.08

going to go to the row mapper which if

157.599

we go to Project row mapper then you can

160.68

see so for each of these it's just it's

162.8

going to create a project right here if

164.84

you see at the top of the

166.48

line and then we just assign out all the

168.76

values based on the result set we pass

171.959

it a result set it gives us out a

174.959

project for each row and so this is and

178.599

we've talked about I think this

179.76

separately we but it's a something we'll

182.56

go in deeper at another Point as far as

184.12

using row mappers but it's a pretty

185.76

straightforward way to get from our our

189.28

query which basically just says Hey like

191.64

I've got a column name project I or

194.84

project ID it's an INT I'm going to set

197.64

the ID for the project class the project

201.08

instance and with the r mapper just for

203.519

each row it's going to go through and do

205.12

that and then that's going to kick that

206.72

back out to my list which going to pick

209.159

kick it out to my

211.439

controller and I can see here where I'm

213.36

adding a bunch of different

215

attributes now some of these I think

216.84

we'd already looked at before so I'm

219.28

basically just going in here putting a

221.2

little bit information um actually here

224.159

the user is USR so I can probably do let

227.48

me go look at that real quick because

228.599

that was one of the things I wanted to

229.48

do if I look at user does he have a get

231.319

display name he

234.68

has uh he does not have he has a

241.76

username let's just do first name so if

244.68

we go to the

248.319

dashboard uh one of the things we do is

250.56

it's dashboard for here but what we

252.36

really want this to

254.159

be is uh

259.68

user we're just going to do th

263.88

text

268.6

equals

272.68

I'll put that

274.36

there and it's going to be uh what do we

277.12

call first name I

278.6

think let's see if that works uh

282.24

probably if I do it like

284.24

this okay anyways slight side trip there

289.6

uh let's go back to our Loop so in our

291.6

Loop the most basic version is going to

294.72

be whatever the attribute is and then

297.56

you're going to sign it a value so what

299.56

what I've done here which we'll talk

301.52

about a second so if

304.6

I if I come here and let me do this let

309.56

me just get rid of

312.6

that and here this is most simple thing

315.88

let me make sure this still works that I

317.44

didn't break something in my

321.12

demo so if I log in boom it gives

325.8

me these uh these entries but it looks

329

like I probably blew something up in

331.6

[Music]

335.88

there not sure

338.199

oh oh no there's

341.919

that okay well oh it's because of the

344.52

way it's set up in the

347.52

diff um so I don't have a lot of

351.12

information about that oh and that was

352.8

because here is that where it

356.8

is uh I think that might be it so

361.72

let's uh let's see can I get reduce

365.68

it

370.08

sorry d g it all right I lost it um well

374.72

let's do it for here cuz what I want is

377

class equals

380.4

row so we'll come back to this in a

382.599

second okay so if I do

387

that and I'll show you in a second what

389

this looks like when it loads there we

393.28

go so now I've got each of these values

395.8

on a row but what I want to do is

397.639

something like this I want to actually

399.28

give myself like some background and do

401.72

a couple other things within uh with

404.16

this data and what we can do there is

407.52

what I did before is we have a second

409.319

value which we'll call status and you

411.72

can name it whatever you want you call

413.039

it status I've seen it I status and

415.039

things like

416.28

that and uh it has

422.879

did I get rid of that I did oh there it

424.56

is it has the status itself has a bunch

427.16

of different properties it's got count

429.639

size first last odd even and so what we

434

can do is we can actually tweak the

437.44

class itself and this is a CSS style

440.68

class so we have to have it you know set

442.759

up properly but if I have an even and an

445.879

odd for my rows then what I can do

450.44

is there's a couple ways I can look at

451.759

it in this one I'm going to say index

453.599

oops which is also one I can do the

456.56

index which says which row number am I

458.56

on so count tells me the total number of

461.52

rows and uh so for example I could

465.56

say h I probably don't want to do it

467.52

within

469.44

this yeah I'm not going to do it within

471.479

this uh but it'll give me but so for my

473.4

index I can give each row so if I had

475.08

five if I have five uh result rows in

478.759

this result set then I've got 1 2 3 4 5

481.28

are my indexes or actually I'm sorry 0 1

483.879

2 3 4 it starts with zero and basically

486.4

I'm just doing a mod here which says

488.52

divide by two and what is the remainder

491.159

and so the remainder when you divide by

492.8

two is either going to be zero or one so

494.96

if it's zero it's an even row and if

498.159

it's odd it's an odd row so now if I do

502.8

that what I'm going to

507.56

get is my little zebra stripe thing boom

512.159

because now it's going to go and if you

514.24

look how easy you're going to be able to

516.2

read this but if you look in here you

518.479

can see where it says row even row odd

520.76

it's a little bit small text but there

522.279

you go so row odd and row even is how

524.68

it's generating that so now I can get my

526.88

little stripe now the other thing I want

528.8

to do is I want to be able to add a

531.519

click which is fun oh before I do that

535

the way I'm going through is each one of

537.56

these it goes through projects and

539.959

assigns it to this project variable so

542.399

if you note here I can do project do

545.519

whatever and in this case projects

549.04

are uh here it is just a straight up

553.839

pojo so what I got

556.36

here any one of these as long as it has

558.8

a get so if I come in here and I look

561

down here like get

562.68

fixed fixed is a value that I could use

565.36

here am I using it on here let's find

567.399

out uh I am so that is the second from

571.2

last column if we look at it here we go

573.839

this is the

577.64

fixed fixed

579.8

created oh I'm sorry it's up here second

582.68

to last here is it fixed and then you

584.44

can see the creative value so all you

586.92

have to do and what it's going to do is

588.72

just going to assume that this is a git

590.76

whatever and you do have uh let me go

594.76

back to where my project

598.12

was

604.56

oh do I have status string I think I

610.36

do there we go status string so it is um

614.24

case sensitive and it's going to assume

617.64

that your format is going to be

619.72

basically it's going to assume that it's

620.8

get and set get get and set and then

625.6

it's going to assume that the next

627.36

character after the get or the set is

629.56

going to be a uppercase even though

632.399

you're going to do it in lowercase so

634.079

like you can see like get name is

636.279

actually get name with a capital

640.04

in however and then if you want

642.399

additional words within there if it's

644.2

camel case like here bid amount is get

649.16

bid capital B amount capital A but if

652.959

you don't have it like I do here this is

655.519

not treated as two separate words and

657.36

you'll see it's going to look for get

659.48

status capital S string lowercase s and

662.959

that's because here wherever I put that

666.32

I don't have the capital S otherwise I

668.12

need to do that if I capitalize that in

670.16

one case or other we're going to have a

671.72

a disconnect so now I can load my values

675.88

in and let's do one more thing within

678.839

this playing around with uh some of the

680.959

values we've

682.279

got is I can actually add an

687

event and in this case

691.36

I'm going to do an

693

onclick and I'm going to do it based on

696.72

the I think I called it project so I'm

699.12

going to do it based on the project ID

700.72

if I spell project correctly so I'm just

703.279

going to do project do ID now there's a

707.48

couple of ways let me show you this and

709.079

I'm going to come back to how I just did

715.8

that so now if we look

720.8

if we look

722.8

here we can see that we've got this on

726.88

click or actually it's a yeah we have

729.12

the onclick and it does a select project

731

and it gives you the ID which is the

732.48

project the ID for that project so that

734.639

that way we can actually click through

736.399

we have an event now notice that here

740.6

we've got these old

742.12

pipes and this is excellent if you're

744.519

building a string that has within it

747.079

only uh Boolean or

750.92

integer values so here this project ID

755

because it is an INT it allows me to

758.16

just refer to build a hard string which

761.199

is basically it says because I'm between

764.399

the

765.519

pipes use this this string that's right

769.959

here and then I can go in and I can just

772.56

do a straight with the uh you know the

775.12

squiggly brackets dollar squiggly

776.76

brackets and then the name or the

779.279

variable name but if I take this and I

781.16

change it to name which is a

785.88

string it's going to not like

791.44

that and there we go and I'm going to

793.32

get an error because I've got a mapping

795.079

issue so I want to keep that as an

799.079

INT and there are a couple of ways that

801.639

we can put strings together uh this one

805.48

is going to be probably one of our

806.76

easier ways there are as far as like if

809.959

I just want to build like in this case

811.56

something where I'm sending an an ID if

813.68

I want to do it with the name itself

815.92

then I'm going to have to come in and do

817.88

something

819.56

like uh let's see I can do oh did I have

824.079

my user let me rebuild this let me do

828.839

here uh where is here we go so I can do

834.24

user first name oh because I did that

837.639

here so this is

839.68

oh I bet it's not liking it let's see

841.759

what did it do let's see what I got here

844.6

and it may be because it I needed that

847.56

in because it was part of the uh the

849.959

JavaScript that I was

851.8

using which I apologize for if I come in

854.6

here let's see what does it give me for

855.959

the dashboard for Rob yes so it does

859.279

pickup user. first name and I can do I

863.24

believe it's like

864.759

this since I'm within uh a pipe

870.12

uh

871.04

user. last

874.8

name and if I rebuild

881.839

it what does it give

884.88

me and there we go so it gives me first

887.48

name last name so I can I can either

890.519

just do a a straight variable like if we

893.88

want to do just user first name or I can

896.399

actually build a string within that base

898.68

based on those there's a couple other

901.639

ways we could do stuff if we wanted to

903.079

build it on a display uh we could do it

905.88

within the th text and try to make it

908.16

work that way or we could like you know

911.16

put a couple spans together or something

912.6

like that if it's just a simple uh

914.56

display of a name or you know a string

917.32

or a series of strings so there's a

919.759

couple different ways we can uh skin

921.839

that cat as it were but right now I just

924.279

wanted to sort of say hey this is like

926.16

dive in and talk a little bit about

929.56

the couple more of the uh timely uh

933.48

things and um I'm just going to get rid

937.12

of some of my oh that's not going to

939.04

like that but I need to get rid of my

942.639

ch's

953.079

uh okay any or I'm sorry my C colons not

956.319

my ch's and uh um I wonder if I have

959.68

some

960.56

more okay good I got rid of all of

963.519

those and now since that if's not

969.44

there when I log in I'm going to see

972.639

those those

974.6

fields yep dashboard and then if there's

976.759

a message it's going to show up but

978

there isn't a message right now so

980.04

that'll do it for now we will come back

981.56

and there are some more there are some

983.48

more things that we can do within time

984.8

Leaf but I want to get that basic one

986.639

laid out and and uh we're just going to

989.36

continue along next episode we will uh

992.36

continue building out our application

994.56

and just keep on going until we have

996.16

something that is functional and have

998.04

covered most of our pieces to convert

1000.16

our app over if you have any questions

1002.04

shoot us an email at info@ developer.com

1005.279

and otherwise whether you have questions

1007.279

or not I want you to go out there and

1008.519

have yourself a great day a great week

1010.48

and we will talk to you next

1017.48

time

1020.96

[Music]