diff --git a/config_example.toml b/config_example.toml index 7b22feb..e0e3d57 100644 --- a/config_example.toml +++ b/config_example.toml @@ -1,9 +1,8 @@ -admin = "zedshaw" +admin = "admin" views = "./views" layouts = "layouts/main" port = ":7001" - [database] driver = "sqlite3" url = "db.sqlite3" diff --git a/pages/index.md b/pages/index.md index 11ba517..413804b 100644 --- a/pages/index.md +++ b/pages/index.md @@ -8,6 +8,38 @@ holding people back when they first start, and also the easiest to get wrong. In fact, if you look at how I do it in this first version it is _WRONG_ so do not use this in production yet until I can make it correct. Just use it to learn for now. +## The Stack + +Currently I'm using the following components in a tastefully crafted stack similar to a Crepe Cake: + +* [goose](https://github.com/pressly/goose) -- This manages the database migrations. +* [sqlx](https://github.com/jmoiron/sqlx) -- This is the database driver. +* [squirrel](https://github.com/Masterminds/squirrel) -- This is the SQL query generator. +* [Fiber](https://gofiber.io/) -- This is the main web API and does most everything you need. +* [tailwind](https://tailwindcss.com/) -- This makes your sites perty and is easy to use, but I + reject the `@apply` slander and use `@apply` to give you nice things. +* [Alpine.js](https://alpinejs.dev/) -- This gives you just enough reactivity to not be annoyed, but + not so much that you hate the web. +* [ssgod](https://git.learnjsthehardway.com/learn-code-the-hard-way/ssgod) -- A static site + generator I wrote that _only_ does static site generation. +* [chromedp](https://github.com/chromedp/chromedp) -- This does your automated testing for you. + +I then add a few little "sweetener" APIs on top of this for simple things like, making the tests +nicer or making it easier to quickly return a page from a view. + +### Isn't Fiber Banned?! + +First off, nobody has the right to "ban" a project. If you're hanging out in the Go discord and +you've seen Fiber on some ban list then whoever did that is a fucking asshole. Just ignore that +bullshit and use the best tech you can. + +Second, if you're only supposed to use the Go standard library then why [is there a whole fucking +document on the official go website explaining how to use Gin to make an API?](https://go.dev/doc/tutorial/web-service-gin). It seems like whoever is claiming that you are only allowed to use the Go standard library is in disagreement with the _actual fucking Go project_. + +Finally, you don't have to do what you're told, especially when the person telling you what to do is +some random asshole hiding in a chat room being a random asshole. Use what you want, and Fiber is +in that sweet spot of being a nice API that isn't slow dogshit like [Gin](https://www.techempower.com/benchmarks/). + ## Getting Started You can get use this project working by doing this: @@ -50,7 +82,143 @@ the code (but _NOT_ HTML/CSS, because that's annoying). ## Configuration +There's 3 basic moving parts to the whole system: `webapp.exe`, `ssgod`, `tailwind`, and `air`. + +You can configure the `webapp.exe` using the `config.toml` which you copied over from `config_example.toml`. The options are fairly self-explanatory. + +You can configure [ssgod](https://git.learnjsthehardway.com/learn-code-the-hard-way/ssgod) using the +`ssgod.toml` file. You'll notice that there's _two_ layouts with this setup, one for `webapp.exe` +and another for `ssgod`. You can just point `ssgod` at your `views/layouts/main.html` file if you +want, but it seems people want two different layouts for their static site vs. "the app." + +You can configure `tailwind` using the `static/input_style.css` and editing the `Makefile` to have +it run how you want. I use the `@apply` heavily because I'm a programmer and no programmer would +ever tell someone they should sprinkle repetitive bullshit all over their HTML. Resist the +authority. Use `@apply`. + +Finally, you can configure the [Air](https://github.com/air-verse/air) tool with `.air.toml` to make +it work how you want. I configured it to only do a reload when I change `.go` code. This works +better because build times for Go on Windows are heinously slow for some reason, and even on +Linux/OSX it's still slower than just letting `tailwindcss` and `ssgod` do their own auto-build. ## Tour of Directories -## More... +The directories are organized in a way that separates "App Stuff" from "Content Stuff". + +* `admin` App The code for the built-in database admin tool. +* `api` App Where you put your JSON API and `views` handlers. +* `common`App Common helper functions. +* `config` App The configuration for your site, which is `config.toml` loaded into Go structs. +* `data` App Your database stuff. You put your SQL models in here, and then add them to the bottom `Map` to +make them magically show up in the `/admin/table/` tool. +* `migrations` App When you use [goose](https://github.com/pressly/goose) it puts the migrations in here. +* `tests` App Your tests go in here. I use [chromedp](https://github.com/chromedp/chromedp) but the `chromedp` +API is too low level (and weird) to be useful so look in `tests/tools.go` for what I use. +* `tools` App I put my little automation tools here. I'll be adding an `admin` tool that will let you admin the +database from the CLI, plus probably a tool to run all the things and manage them. +* `views` App This is where you put the _App_ contents, not the static content. See the _Dev Workflow_ section +on how to work to make dev faster but also use static files in production when things are working. + +These directories then control you _static_ content, but are also used by the _App_ content. For +example, `static/` contains the `static/input_style.css` which is turned into `static/style.css`. +The `static/style.css` is used by everything to--you guessed it--style your whole site. + +* `pages` Static This is the static content you want generated by `ssgod`. See _Dev Workflow_ for how I + use this. +* `static` Static This is static content like `.js`, images, and `.css` files that are only _copied_ over + by `ssgod`. + +The following directories are considered "build junk" and you _should not_ commit them to your git. + +* `public` Junk This is generated by `ssgod` and then served by your `webapp.exe`. Don't + edit anything in here, and instead edit in `pages` or `static`. +* `tmp` Junk This is made during the build/testing process. + +## Dev Workflow + +> __Warning__ Parts of this are not optimal. I have to work on how to make this easier, parmarily +> how to run all the things with one command and manage them. + +The first thing I do is run each of these commands in different terminals, either with tmux or just +using my fingers to run multiple tabs in PowerShell: + +```shell +# these are run in separate terminals +make docs +make dev +make tailwind_watch +make site_watch +``` + +Yes, this is annoying, so if you have a suggestion on a way to manage these that works on Windows +let me know at help@learncodethehardway.com. + +### Working on Pages + +Once those are running in different terminals I mostly have everything I need to work in my editor +of choice and have things autobuild. I then put my content into `pages/` and manually reload after +`ssgod`/`tailwind` autoruns. + +### Working on Views + +Another way is to put your content into views, and then add this one line +of code to your `api/handlers.go`. For example, if I want to create `/mypage/` I do this: + +```go +# make the file with an editor on Windows +echo "Test" > views/mypage.html + +# edit api/handlers.go +app.Get("/mypage/", Page("mypage")) +``` + +> __Warning__ On windows the above `echo` command creates garbage in the output because Windows is +> weird. Just make the file with a text editor. + +## Using the Tailwind Starter + +I've included [tailwind](https://tailwindcss.com/) in this setup, since it's decent at getting +things working quickly right in the HTML. The only thing I've fully rejected is the idea that +"@apply is bad m'kay." No, `@apply` makes it so I don't rage at all the idiots who think 92 +repeated CSS classes on every `div` is "good practice." + +> __NOTE__ You can view a sample page with all of these in [/examples/sample.html](/examples/sample.html) and you can look at the other files in `examples` to get an idea of what you can do. Some of these just use tailwind, others use my starter kit. + +In my setup there's a `static/input_style.css` that is used to generate a `static/style.css` and it +comes preconfigured with many of the things you'll need to get a page up and running. In theory +you can prototype a first page with just HTML and a bit of tailwind as needed. It also uses many of +the stock HTML tags like `aside` and `mark` so you can keep things nice. + +I've added 4 additional layout tags for you to use: + +* `grid` -- For stuff in a grid. Add `class="grid-cols-2"` from tailwind to change its layout. +* `block` -- A simple pre-configured vertical flex box. Put it around vertical stuff. +* `bar` -- A simple pre-configured horizontal flex box. Pit it around horizontal stuff. +* `stack` -- A simple way to stack stuff on top of other stuff. You know, like in every single 2d compositional system since the 1500s. +* `shape` -- A simple 2d box to use for placeholders where you'll put images. It's a lot quicker to drop a little `shape` than to go find an image. I think it also makes it easier to focus on the design. + +### Is that "Accessible"?! What about SEO?! + +Yes, I actually tested all of this with [NV Access](https://www.nvaccess.org/) and the only thing NV +Access seems to have a problem with is the `pre` and `code` tags. That's because apparently those +are deemed as "images" so they get ignored...which is about the dumbest fucking shit I've ever +heard. I'm working on a way to fix that. + +Anyone telling you that my `grid`, `bar`, `block`, or `stack` tags impact accessibility most likely +has never ran NV Access one time so they're just wrong. Additionally, it's better to have these be +_ignored_ by screen readers because they're just 2D layout junk, so they're kind of irrelevant to a +linear 1D screen reader. + +Finally, SEO isn't impacted because Google has literally said HTML quality doesn't matter for SEO +ranking. Think about it, if Google went around dictating exact HTML they would get in so much +Monopoly trouble. Instead they tend to focus more on content and organization, and I believe the +official quote is, "Making everyone use the same HTML would make the web boring." + +However, take this with a grain of salt because the same Google people who've said this also said +that backlinks didn't impact performance and many SEO experts say this is totally not true. Do your +own testing, and if it impact your SEO than just change them after you get your initial design up. + +## Conclusion + +Hopefully that gets you started in this project. I'll be improving the usability of this as I use it +myself, but if you have suggestions please email me at help@learncodethehardway.com. diff --git a/static/input_style.css b/static/input_style.css index 6ac287e..5bcc992 100644 --- a/static/input_style.css +++ b/static/input_style.css @@ -119,7 +119,7 @@ button { } blockquote { - @apply rounded-sm shadow-sm bg-gray-700 text-gray-50 dark:bg-gray-700 dark:text-white p-2; + @apply border-l-5 border-gray-800 dark:border-black bg-gray-200 text-black dark:bg-gray-700 dark:text-white p-2; } @utility btn-hover { diff --git a/static/style.css b/static/style.css index d721bef..b54f0a1 100644 --- a/static/style.css +++ b/static/style.css @@ -241,6 +241,9 @@ .flex { display: flex; } + .grid { + display: grid; + } .inline { display: inline; } @@ -823,12 +826,15 @@ button { } } blockquote { - border-radius: var(--radius-sm); - background-color: var(--color-gray-700); + border-left-style: var(--tw-border-style); + border-left-width: 5px; + border-color: var(--color-gray-800); + background-color: var(--color-gray-200); padding: calc(var(--spacing) * 2); - color: var(--color-gray-50); - --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + color: var(--color-black); + @media (prefers-color-scheme: dark) { + border-color: var(--color-black); + } @media (prefers-color-scheme: dark) { background-color: var(--color-gray-700); }