Building a linkblog with Hugo, Tailwind and Netlify
- Publish Date
- Authors
- Justin Searls
- Location
- Orlando, FL, USA
Transcript
With Twitter on shaky ground, there’s a sudden interest in open social platforms and protocols as well as a return to hosting traditional web sites and blogs. But because we’ve become accustomed to low-friction publishing workflows (type a bit in a box, click Tweet), routinely writing real blog posts can feel daunting.
This video provides a brief overview of one way to organize a personal blog that’s structurally similar to daringfireball.net—allowing for short-and-sweet posts—but with modern architecture of Hugo for static site generation, Tailwind for styling, and Netlify (plus NetlifyCMS) for hosting and on-the-go publishing—enabling very low-friction publishing.
Resources
- Hugo
- Tailwind
- Netlify
- NetlifyCMS
- Justin’s CSS overrides to make NetlifyCMS more mobile-friendly
- Static CMS - a maintained fork of NetlifyCMS (see this issue for more background)
- 00:00
- (ethereal music)
- 00:02
- - Hello friends, I woke up this morning
- 00:04
- and I decided that even though I've got a cold,
- 00:06
- and even though I've done very little
- 00:08
- to prepare for this,
- 00:10
- I've been working on something I'd like to share
- 00:11
- with you and talk through it.
- 00:12
- Because, I don't know if you feel this way,
- 00:15
- but with the impending implosion of twitter.com,
- 00:20
- I feel, suddenly, like,
- 00:22
- a renewed sense that maybe I should own
- 00:25
- a bigger portion of the parts of the internet
- 00:28
- that I contribute to,
- 00:30
- which leads to the classic programmer
- 00:32
- who is dangerous enough with website stuff,
- 00:36
- a conundrum of building a blog
- 00:38
- over the course of a weekend,
- 00:39
- with the hope that maybe I'll start blogging.
- 00:43
- In this case, because I'd been down that road a bunch,
- 00:46
- I wanted to take a turn that would allow me
- 00:49
- to publish much more effortlessly.
- 00:53
- Like, the reason I was always tweeting so much
- 00:55
- was that I was, like, really easy to just,
- 00:57
- you know, fire them off from my phone.
- 00:59
- And so, I needed a workflow that allowed me
- 01:00
- to write quick and dirty posts for my phone,
- 01:03
- as well as a permission structure
- 01:06
- to write very, very short posts.
- 01:07
- Whereas, I typically can write way too much.
- 01:11
- And so, my inspiration right out of the gate
- 01:13
- was "Daring Fireball".
- 01:15
- It's one of my favorite blogs.
- 01:16
- John Gruber is, you know,
- 01:18
- just sort of an institution with blogging.
- 01:21
- But weirdly enough, his linkblog style of blogging
- 01:25
- is not very well understood,
- 01:26
- and not very, you know, often imitated these days.
- 01:30
- So if you're not familiar,
- 01:30
- just to walk through the information architecture
- 01:32
- of like, what "Daring Fireball" is,
- 01:33
- is there are posts, but not very many of them.
- 01:36
- If you go to the archive, you know,
- 01:37
- maybe he turns out 2, 3, 4 real posts a month.
- 01:42
- You go in, it's like,
- 01:42
- "Okay this's his Apple Watch Ultra post."
- 01:45
- You know, it is a permalink,
- 01:47
- you look at the RSS and this's the alternate link,
- 01:50
- this's the canonical link for that.
- 01:52
- But most of the stuff that he posts're just, like,
- 01:54
- links to other stuff.
- 01:55
- So like, in this instance, this's a link
- 01:58
- to, you know, a third-party website
- 02:00
- and its article.
- 02:01
- And what he's just doing is providing color commentary,
- 02:04
- or giving his take on something,
- 02:05
- usually with pull quotes.
- 02:08
- And if you want to, you know,
- 02:10
- share the "Daring Fireball" link,
- 02:13
- the permalink, here,
- 02:15
- is just available on this little star.
- 02:17
- And then you can go and...
- 02:18
- Now the URL is, you know,
- 02:19
- updated to have that full thing.
- 02:21
- So I've always really liked this approach,
- 02:24
- because it seems like something that if I could do that,
- 02:27
- then I would have...
- 02:30
- I would more fluidly share things that I'm thinking
- 02:33
- instead of just, like, texting them to a friend
- 02:35
- or tweeting them into the ether.
- 02:38
- So I undertook a little bit of a journey, here.
- 02:42
- And I had an existing app,
- 02:46
- at justin.searls.co,
- 02:48
- that was written in Hugo.
- 02:49
- And Hugo's a great, super-fast static-site generator.
- 02:52
- It's a very basic blog.
- 02:53
- Basically, it was just (chuckles)
- 02:55
- dealing with medium.com's impending implosion,
- 02:58
- and pulling down all of my posts
- 02:59
- as quickly as possible into markdown,
- 03:01
- and grabbing their images, and so forth,
- 03:03
- so that I could have a place for them to live
- 03:05
- in the event that Medium went away.
- 03:06
- Medium didn't go away, which, you know,
- 03:08
- probably says something about whether we should
- 03:10
- be predicting the literal demise of Twitter
- 03:12
- or just its, you know, descent.
- 03:15
- But I had the bones of a site there,
- 03:18
- so I'd already kind of gone
- 03:18
- through some of the motions.
- 03:20
- And Hugo is also very flexible.
- 03:22
- You know, I'm not going to explain
- 03:23
- how to build a Hugo app here,
- 03:24
- because it's written in Go lang.
- 03:26
- Like, a lot of the configuration
- 03:28
- is kind of arcane, to be honest.
- 03:32
- And the community forums can sometimes seem hostile
- 03:34
- to users asking questions.
- 03:36
- But otherwise, it's really fast and really good.
- 03:38
- I know I'm really selling it.
- 03:40
- But it's very future rich,
- 03:41
- it's very flexible for doing things like,
- 03:44
- in this exact case, we have two kinds of posts.
- 03:47
- We have two different content sections.
- 03:49
- And we have a main feed that needs to be able
- 03:52
- to merge them together nicely,
- 03:53
- and we also need to be able to use those data types
- 03:56
- to build things like an Atom XML RSS feed.
- 04:00
- All right, so that was the first piece.
- 04:01
- Second piece was I had written that original site
- 04:04
- with a particular style, lightweight,
- 04:07
- nothing too fancy, in SAS,
- 04:10
- and just raw SAS and light,
- 04:11
- I got really, like, bent out of shape
- 04:14
- with a lot of confusing, overly-complex selectors.
- 04:18
- And every time I changed anything, you know,
- 04:20
- it was just the Peter Griffin blinds GIF happening on me.
- 04:24
- My friend, Derek Briggs, over from PlanetScale.
- 04:28
- He paired with me on Tailwind
- 04:29
- just enough, for an afternoon,
- 04:31
- for me to see the light,
- 04:33
- and realize that the locality of writing
- 04:35
- in utility classes and scoping them
- 04:37
- down as I work through a page
- 04:39
- allows me to think
- 04:40
- outside-in about how the page is structured
- 04:42
- in a way that I was never able to do
- 04:43
- when I was balancing a CSS file and a markup page.
- 04:46
- So the first order of business
- 04:49
- when I was doing this work
- 04:51
- was to throw away all the original styles
- 04:53
- and restyle it from the ground up,
- 04:54
- even though it looks very similar in Tailwind.
- 04:57
- And amazingly, it took, like, an hour and a half.
- 05:00
- Which is a level of productivity
- 05:02
- that in, you know,
- 05:03
- 20 years of tootling around on the web,
- 05:06
- I've never experienced before.
- 05:07
- So, you haven't played with Tailwind yet.
- 05:09
- check it out.
- 05:11
- For hosting, for static sites,
- 05:13
- I really like Netlify.
- 05:14
- Normally I use Heroku for running a lot of my apps,
- 05:18
- and simple SaaS services.
- 05:19
- Because like, you know, the managed Postgres is amazing.
- 05:22
- As awesome as Heroku's managed Postgres is,
- 05:25
- it provides no CDN story out of the box.
- 05:28
- So like, you know, edge network delivery of content
- 05:31
- in a cached and performant way
- 05:32
- that's not going to completely obliterate your server
- 05:34
- if you ever get, you know, fireballed,
- 05:38
- or linked to from "Hacker News", or something.
- 05:41
- Netlify is the opposite.
- 05:43
- Where Netlify is highly optimized
- 05:45
- for static-site delivery,
- 05:47
- and everything that you post up to it
- 05:49
- goes into a CDN right away.
- 05:51
- So, here's what the site ends up looking like.
- 05:55
- You know, you can see, instead of a star,
- 05:57
- I've got, like, a little salt shaker. (laughs)
- 06:00
- So this's like my first link post of commentary
- 06:03
- on Meta's very flawed Quest Pro product.
- 06:08
- And if I click in here,
- 06:10
- I apparently stopped my server.
- 06:11
- So that's...(laughs)
- 06:13
- I'm on my local host.
- 06:15
- So let's go ahead and start that up.
- 06:17
- So script/server.
- 06:22
- and that'll do things.
- 06:24
- I always turn caching off 'cause it's so fast.
- 06:26
- I'd rather have the confidence to know
- 06:28
- everything was from scratch.
- 06:30
- So I click in here,
- 06:32
- and now I'm at the permalink URL.
- 06:34
- But if I go back to this page, you know,
- 06:36
- you can see I scroll
- 06:38
- back and I'm back in March,
- 06:39
- 'cause I don't blog here very often.
- 06:41
- But I'm hoping to write more soon,
- 06:43
- and you can see there's links on the side
- 06:45
- that just show me the posts,
- 06:47
- and then just show me,
- 06:48
- like, the link posts, the linkblog.
- 06:50
- An About page, the RSS feed,
- 06:52
- which I learned RSS 2 is not a particularly great spec.
- 06:57
- And so, if you want to write this kind of blog,
- 06:59
- you actually need to use an Atom XML feed,
- 07:01
- because it allows you to specify both a alternate,
- 07:06
- which is like the real page link tag,
- 07:09
- as well as a related link tag.
- 07:11
- And that's what this is.
- 07:13
- So it allows RSS readers to be able to link
- 07:15
- to both your permalink of your post
- 07:17
- as well as to the source link
- 07:20
- when you're writing a linkblog-style post.
- 07:22
- And then, of course, other links over here.
- 07:26
- If you haven't gotten on the Mastodon train yet,
- 07:29
- or if you're about to,
- 07:31
- I encourage you to do it.
- 07:32
- It's less of a ghost town than you'd think.
- 07:34
- Again, I'm really good at sales.
- 07:36
- I am searls@mastodon.social,
- 07:39
- and I hope that you'll be my friend.
- 07:42
- People are really hopping on this week,
- 07:44
- so that's exciting.
- 07:45
- All right, so, right.
- 07:48
- So here's, you know, where it lives on GitHub.
- 07:50
- Everything that I do just pushes up to here.
- 07:53
- And we're going to just make a quick change.
- 07:56
- Oh, I guess before I do that,
- 07:58
- was there anything else I wanted to show you?
- 07:59
- So I got into the link posts.
- 08:02
- Oh yeah, so responsiveness was important, right?
- 08:04
- Because, like, most of the stuff
- 08:05
- is happening on my phone.
- 08:07
- I love Safari's responsive editor for stuff like this.
- 08:10
- So here I am.
- 08:11
- Even though it hasn't been updated
- 08:12
- since the iPhone 8 was the new phone,
- 08:15
- it's an easy, quick way for me to be able to see,
- 08:17
- "Okay, so here's what it looks like on a phone."
- 08:19
- You can see that the nav just simplifies
- 08:21
- to just post links about the important stuff.
- 08:24
- And you can scroll through.
- 08:27
- The other thing that this can do
- 08:30
- is you can actually size dynamically,
- 08:32
- just like skoshing it up a little bit, up and down.
- 08:35
- So even if it doesn't fit
- 08:36
- a particular, exact size of a device.
- 08:40
- Or, you know, I can pick an iPad mini,
- 08:41
- you can click here and it can, you know,
- 08:43
- do the split-screen thing
- 08:44
- or do what it looks like in portrait mode.
- 08:47
- So if I just play with this,
- 08:49
- you can sort of see the break points are,
- 08:50
- it's like, full screen 'cause you don't have
- 08:51
- a lot of screen space.
- 08:52
- And then it kind of becomes a page on the screen.
- 08:54
- And, in fact, one of my little touches
- 08:56
- is the page curl animates as the page loads.
- 08:59
- And you scroll a little bit further, and then,
- 09:01
- or you widen the view port a little bit more.
- 09:03
- And then, the navigation shifts
- 09:05
- from the top of the screen over to the side,
- 09:06
- 'cause now there's enough room to render that.
- 09:09
- So I work in this mode all the time,
- 09:11
- and it's one way for me to consistently be switching
- 09:14
- between 2x and 1x view ports
- 09:18
- of point density
- 09:20
- as well as, you know,
- 09:21
- big and small view port sizes.
- 09:26
- So that's that.
- 09:29
- And then, also, light and dark mode.
- 09:31
- So I'm going to use Raycast, here,
- 09:33
- 'cause Raycast is a spotlight-like app
- 09:35
- that makes it very easy to switch
- 09:36
- between light and dark mode,
- 09:37
- which I've been doing constantly
- 09:38
- for the last few days.
- 09:40
- Okay, so here you can see
- 09:43
- that light mode and dark mode,
- 09:44
- the color schemes all transfer, you know,
- 09:46
- it's just a matter of taste.
- 09:48
- The shadows and all that,
- 09:50
- you know, they, they adjust.
- 09:51
- So Tailwind makes that, again,
- 09:54
- absurdly easy to show you
- 09:55
- what that, like, configuration looks like,
- 09:57
- is it's really just all CSS variables,
- 10:00
- which I think is really kind of cool.
- 10:02
- So here at the top of the CSS file,
- 10:04
- I just have, you know, a handful of colors.
- 10:06
- Those purple accent colors,
- 10:07
- background, border, text.
- 10:09
- And so, in light mode,
- 10:10
- this's those RGB values, space delimited.
- 10:14
- And then in dark mode,
- 10:14
- here's all of those same values,
- 10:16
- again, space delimited and just eyeballed.
- 10:19
- The reason that they're RGB and space delimited
- 10:22
- is this's sort of a new thing in Tailwind,
- 10:27
- but you can actually apply alpha modifiers
- 10:30
- to these values if you set them
- 10:32
- up in your theme a particular way.
- 10:34
- So in this case, you can see, you know,
- 10:37
- BG primary, that's actually getting, ah...
- 10:39
- I wrote a (laughs) premature abstraction.
- 10:42
- I wrote a variable, or a function,
- 10:44
- to extract this out.
- 10:45
- But like, basically you take the variable name here,
- 10:47
- and then you divide by the alpha value.
- 10:51
- You just give it that magical string,
- 10:52
- and then all of a sudden,
- 10:53
- all of these colors are usable
- 10:55
- in every single Tailwind construct really easily
- 10:57
- between light and dark mode with.
- 10:59
- And that's the last time
- 11:00
- that I really had to think about dark mode
- 11:01
- when I was making this.
- 11:03
- All right, so that's a little bit
- 11:04
- what the site looks like.
- 11:04
- Let's make a quick edit
- 11:06
- to show you what the publishing workflow looks
- 11:08
- like when I'm writing from my computer.
- 11:10
- So let's make a quick change to this post.
- 11:14
- You know, there's a traditional, kind of like,
- 11:15
- you know, YAML-style front matter
- 11:17
- at the top of the markdown file.
- 11:19
- Let's just change this
- 11:20
- from 10 minutes to five minutes.
- 11:24
- And then, we'll hop over here into this view,
- 11:27
- and we will just say, "All right, change the..."
- 11:34
- I don't know, I never know.
- 11:37
- When I'm writing prose, like,
- 11:38
- my commit messages don't matter.
- 11:40
- I'll just commit it, whatever.
- 11:41
- And then update prod.
- 11:45
- When I do that, of course, you know,
- 11:46
- it goes into GitHub.
- 11:48
- We're very used to stuff going into GitHub.
- 11:50
- So you can see that prose link came.
- 11:53
- Now, here I am in Netlify's backend
- 11:56
- and I want to look at the deploys, right?
- 11:57
- So I go into production deploys,
- 11:59
- you can see it's already building pros.
- 12:00
- And we'll see how long this takes.
- 12:02
- It'll be long enough for me to wait on, I hope,
- 12:05
- because it's surprisingly quick.
- 12:07
- I mean, you can look at the historical speeds.
- 12:09
- It's about 20 seconds to launch,
- 12:11
- which is, like, a lot faster than I'm used to.
- 12:13
- Especially considering that, like,
- 12:15
- it's installing a bunch of NPM stuff,
- 12:16
- it's running Hugo.
- 12:19
- Alright, so if we're here, our real page, now,
- 12:22
- I'm going to switch to light mode real quick.
- 12:24
- We're at our real page.
- 12:27
- And now, it's just five minutes.
- 12:29
- Okay, so that, like, that was reflected.
- 12:31
- Now that's great.
- 12:32
- I don't know why I decided to switch to light mode.
- 12:33
- It's dark, it's morning, I'm getting over a cold.
- 12:37
- I need to keep things chill.
- 12:39
- That's me, I'm super chill.
- 12:42
- (laughs) And also have had
- 12:45
- too much cold medicine this week.
- 12:47
- So, here's the thing.
- 12:52
- All of this is great.
- 12:54
- All of this is a fun little project,
- 12:56
- but it requires me sitting at my computer
- 12:59
- and kind of treating blogging as work.
- 13:03
- Which it is very much not work,
- 13:05
- it's just a thing that I like to do
- 13:08
- when I've got some spare time.
- 13:09
- And, like, the idea of spending, you know,
- 13:11
- time after hours, or time on weekends,
- 13:13
- just kind of holed up into a, you know,
- 13:16
- like, a work-like posture just because I want to share
- 13:19
- something quickly on my blog
- 13:21
- is all kinds of no fun to me.
- 13:23
- So what I did was I adopted this thing
- 13:26
- called Netlify CMS.
- 13:28
- So Netlify published an open-source CMS
- 13:30
- that is not technically tightly coupled to Netlify,
- 13:32
- but is totally kind of much easier
- 13:34
- if you roll with the Netlify server-side stuff.
- 13:40
- And all I did was add
- 13:41
- a static admin folder over here,
- 13:44
- with a index html file that simply sprinkles
- 13:48
- in, you know, their CDN link to...
- 13:52
- So basically, this whole page is like a bookmarklet.
- 13:56
- It'll just kind of take over the whole UI.
- 13:59
- And then I wrote some mobile overrides,
- 14:00
- because it's actually, surprisingly and sadly,
- 14:03
- not a responsive app.
- 14:05
- And so, when I'm on a phone,
- 14:06
- I just kind of hijack all the styles
- 14:08
- and make sure that they contort
- 14:10
- to the viewport,
- 14:13
- which I can share in a gist after this's done.
- 14:17
- All right, and then, additionally,
- 14:19
- the only real kind of configuration
- 14:20
- is just for it to learn a little bit
- 14:22
- about the file structure.
- 14:23
- That's the Netlify proper,
- 14:25
- where is the
- 14:31
- YAML, it's a config YAML file.
- 14:33
- Static admin, I scrolled right past it.
- 14:35
- All right, so like, it uses Git,
- 14:37
- it wants to know where to upload things.
- 14:39
- It converts slugs, it has, like,
- 14:42
- you know, separate collections, right?
- 14:44
- So like, the links pages and how those look,
- 14:46
- and then the post pages and how those look,
- 14:48
- and then what parameters you need.
- 14:50
- So that's the setup.
- 14:52
- And additionally, for identity,
- 14:53
- you can use Netlify's own identity thing.
- 14:56
- So I'm going to go ahead and unlock here.
- 14:59
- So I'm logging in here with my Netlify account
- 15:01
- against my own, you know, URL.
- 15:04
- But it's all happening over JavaScript
- 15:06
- via, you know, XHRs.
- 15:08
- And so, now I can see
- 15:10
- I've got, you know, my link posts.
- 15:13
- So posts are here,
- 15:15
- and linkblog posts are here.
- 15:18
- You know, I can go in,
- 15:19
- I can edit any of this stuff and click Publish,
- 15:21
- it'll commit to Git right away.
- 15:24
- So just kind of walk through what that feels like,
- 15:26
- and what ends up resulting on the file system.
- 15:30
- Let's make a quick post now.
- 15:31
- So I've got a post that I drafted
- 15:35
- that's sitting on my second screen.
- 15:38
- And this's a link to a really cool blog.
- 15:40
- I don't know how to pronounce this blog, "Salooned"?
- 15:44
- But this blogger has produced
- 15:45
- some very, very good blog post
- 15:47
- about the Ruby programming language
- 15:49
- over the last few years.
- 15:50
- And it is starting to take over the Google PageRank
- 15:52
- because it's just so accurate and informative.
- 15:56
- And he just wrote a post,
- 15:58
- or they just wrote a post about Ruby 3.2
- 16:01
- adding a new data class.
- 16:03
- So here's a post, I'm just going to blat it in there,
- 16:06
- that I wrote in advance,
- 16:07
- about why I'm excited about this data class
- 16:09
- as an alternative to struct.
- 16:11
- Here you can see I've got, like,
- 16:12
- my first code example ever on this blog,
- 16:15
- so we'll see what that looks like.
- 16:17
- All right, so when I have all this stuff ready,
- 16:19
- Draft is just going to skip it from,
- 16:21
- you know, being shown a prod.
- 16:23
- But we're, we're going to just go straight to prod
- 16:25
- and hope this works.
- 16:26
- 'Kay, so I'm going to hit Plug, Publish.
- 16:29
- When publish happens,
- 16:30
- it should immediately update GitHub
- 16:32
- so we can see it's got one new commit.
- 16:36
- The new commit has a conventionally-built file name,
- 16:40
- so I don't have to think about file names.
- 16:41
- It's just year, month, date.
- 16:42
- And then a slugified version of the the title
- 16:46
- that I gave it.
- 16:48
- And if I ever change that title,
- 16:49
- I can hard code the URL so it doesn't change.
- 16:51
- And then, if I...
- 16:53
- Well this, okay, I'll hit Refresh on this page.
- 16:56
- And it's already published.
- 16:59
- So I refresh the page now, and here it is.
- 17:01
- And you can see I've got,
- 17:03
- syntax highlighting and all that
- 17:04
- is handled very easily by Hugo.
- 17:06
- There's a couple manual steps to do,
- 17:08
- but it's not hard to figure
- 17:08
- out when you're reading the docs.
- 17:10
- And I kind of enjoy this sort of, like,
- 17:12
- cut out view of the code,
- 17:13
- because it looks like it's sitting
- 17:15
- right underneath, like, the document paper.
- 17:18
- 'Cause it's the cool code,
- 17:19
- it's underneath the covers.
- 17:21
- And then, you know,
- 17:22
- got different code syntax highlighters
- 17:25
- for light and dark mode.
- 17:27
- So yeah, that's what I've been,
- 17:30
- you know, up to in this, you know,
- 17:33
- the beginning of the aftertime,
- 17:37
- with not being so reliant
- 17:39
- on Twitter anymore.
- 17:43
- And I'm also starting to get excited
- 17:44
- about other means of distribution.
- 17:46
- Like, so, for example, I showed off Mastodon a minute ago.
- 17:50
- Mastodon, like, implements a thing called ActivityPub.
- 17:52
- And I don't really know what ActivityPub looks like,
- 17:54
- except it seems to be a neato way
- 17:57
- to both publish, and consume,
- 17:59
- and subscribe to content
- 18:00
- from heterogeneous types of sources.
- 18:02
- So instead of just following Mastodon users,
- 18:05
- you could presumably, like, follow a blog
- 18:10
- that implemented ActivityPub appropriately.
- 18:12
- And so, that's the next thing
- 18:13
- I'm going to look into, is try to figure
- 18:14
- out whether or not I can make
- 18:16
- more things that I'm doing on the internet,
- 18:19
- sort of, passively be subscribable
- 18:21
- through anything that adheres to Activity Pub.
- 18:24
- And I have no idea if it's just like the next XHTML
- 18:27
- and we're all going to forget about it,
- 18:28
- or if it's actually going to become, like, you know,
- 18:31
- the plumbing for, you know,
- 18:33
- a new, more open set of of tools
- 18:36
- and experiences on the web.
- 18:38
- So anyway, exciting times if you, like me,
- 18:41
- are getting the itch to start blogging more,
- 18:43
- or owning your portion of the internet
- 18:47
- and it means that you control a little bit more
- 18:49
- rather than being beholden
- 18:50
- to the social media companies.
- 18:52
- I hope that this was a little bit of inspiration.
- 18:54
- And then check out the description notes,
- 18:56
- and I'll share some links
- 18:58
- for how to get started, yourself.
- 19:00
- All right, I'll catch you later.
Justin Searls
- Status
- Double Agent
- Code Name
- Agent 002
- Location
- Orlando, FL