Skip to content

Commit ce9fde2

Browse files
authored
README for pgml-components (#981)
1 parent b7fa637 commit ce9fde2

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# pgml-components
2+
3+
`pgml-components` is a CLI for working with Rust web apps written with Rocket, Sailfish and SQLx, our toolkit of choice. It's currently a work in progress and only used internally by us, but the long term goal is to make it into a comprehensive framework for building web apps in Rust.
4+
5+
## Installation
6+
7+
`pgml-components` is available on crates.io and can be installed with `cargo install cargo-pgml-components`.
8+
9+
## Usage
10+
11+
To get a list of available commands:
12+
13+
```bash
14+
cargo pgml-components --help
15+
```
16+
17+
The CLI operates on a project directory, which is a directory containing a `Cargo.toml` file. You can specify the project directory with the `--project-path` flag, or you can run the CLI from the project directory itself.
18+
19+
### Commands
20+
21+
#### `bundle`
22+
23+
```bash
24+
cargo pgml-components bundle
25+
```
26+
27+
This command will read all the JavaScript and Sass files in the project and bundle them into a JS bundle and a CSS bundle accordingly. The JS bundle is created with [Rollup](https://rollupjs.org/) and the CSS bundle is created with the [Sass compiler](https://sass-lang.com/install/).
28+
29+
The `bundle` command should be ran after making any changes to JavaScript or Sass files. In our app, we added it to `build.rs` and run it on every change to the `src/` directory, but another way of running it without having to rebuild the app can be with `watch`:
30+
31+
```bash
32+
cargo watch \
33+
--exec 'pgml-components bundle' \
34+
--watch src/ \
35+
--watch static/ \
36+
--ignore bundle.*.*
37+
```
38+
39+
The bundles are placed in `static/css/style.css` and `static/js/bundle.js`. Both bundles are also copied into files with a short hash of their contents appended to their names, e.g. `static/css/style.6c1a4abc.css`. The bundles with the hash in their names are used in production, while the bundles without the hash are used in development. The hash is used to bust our caching of assets.
40+
41+
#### `add`
42+
43+
This command is used to add elements to the project. Currently, only frontend components are supported. Support for SQLx models and Rocket controllers is on the roadmap.
44+
45+
##### `add component`
46+
47+
```bash
48+
cargo pgml-components add component <path>
49+
```
50+
51+
This command will create a new frontend component in the specified path. The name of the component will be the absolute name of the Rust module. For example, if the path of the component is `dropdown`, then the component will be added to `src/components/dropdown` and it's name will be `crate::components::Dropdown`. If the component path is `controls/button/primary`, then component name will be `crate::components::controls::button::Primary` and the component will be placed into the `src/components/controls/button/primary` directory.
52+
53+
Frontend components use Sailfish templates, Hotwired Stimulus for JavaScript, and Sass stylesheets. The command creates all of these automatically and links both the JS and the Sass into the bundles produced by the `bundle` command.
54+
55+
For example, if creating the `dropdown` component, you'll get the following files:
56+
57+
```
58+
# Sailfish template
59+
src/components/dropdown/template.html
60+
61+
# Stimulus controller
62+
src/components/dropdown/dropdown_controller.js
63+
64+
# Sass stylesheet
65+
src/components/dropdown/dropdown.sass
66+
67+
# Rust module
68+
src/components/dropdown/mod.rs
69+
```
70+
71+
Initially, the component will be very barebones, but it will have all the necessary dependencies connected automatically.
72+
73+
###### `template.html`
74+
75+
The HTML template will just have a `<div>` that's connected to the Stimulus controller.
76+
77+
```html
78+
<div data-controller="dropdown">
79+
</div>
80+
```
81+
82+
###### `dropdown_controller.js`
83+
84+
The Stimulus controller is connected to the `<div>` in the template above, and can be used immediately.
85+
86+
```javascript
87+
import { Controller } from '@hotwired/stimulus'
88+
89+
export default class extends Controller {
90+
initiliaze() {
91+
console.log('Initialized dropdown controller')
92+
}
93+
}
94+
```
95+
96+
###### `dropdown.sass`
97+
98+
The Sass stylesheet doesn't have much, but you can start adding styles into it immediately. We don't have to use `data-controller` CSS selectors, the typical class selectors are fine. The command just generates something that will immediately work without any further configuration.
99+
100+
```css
101+
div[data-controller="dropdown"] {
102+
width: 100%;
103+
height: 100px;
104+
105+
background: red;
106+
}
107+
```
108+
109+
###### `mod.rs`
110+
111+
Everything is linked together ultimately with Rust. This file defines a struct that implements `sailfish::TemplateOnce`.
112+
113+
```rust
114+
use sailfish::TemplateOnce;
115+
116+
#[derive(TemplateOnce)]
117+
#[template(path = "dropdown/template.html")]
118+
pub struct Dropdown {
119+
pub value: String,
120+
}
121+
```
122+
123+
Once the component is created, it can be used in any Sailfish template:
124+
125+
```html
126+
<% use crate::components::Dropdown; %>
127+
128+
<div class="row">
129+
<div class="col-6">
130+
<%+ Dropdown::new() %>
131+
</div>
132+
</div>
133+
```
134+
135+
Components can be placed into any directory under `src/components`. They have to be in their own folder, so to have components organized neatly, you'd need to have folders that only contain other components and not be a component by itself.
136+
137+
For example, all buttons can be placed in `controls/buttons`, e.g. `controls/buttons/primary`, `controls/buttons/secondary`, but there cannot be a component in `controls/buttons`. There is no inherent limitation in our framework, but it's good to keep things tidy.
138+
139+
`pgml-components` does all of this automatically and makes sure that you don't accidently add components into a directory that already has one.
140+
141+
##### Deleting a component
142+
143+
There is no command for deleting a component yet, but you can do so by just deleting its directory and all the files in it, and bundling.
144+
145+
For example, to delete the `dropdown` component, you'd run:
146+
147+
```bash
148+
rm -r src/components/dropdown
149+
cargo pgml-components bundle
150+
```
151+
152+
## Philosophy
153+
154+
`pgml-components` is an opinionated framework for building web apps in Rust based on our experience of using Rocket, SQLx, and Sailfish (and other template engines). That being said, its philosophy is to generate code based on its own templates, and doesn't force its user to use any specific parts of it. Therefore, all elements generated by `pgml-components` are optional. When creating a new component, you can remove the Stimulus controller or the Sass stylesheet. If removed, they won't be added into the bundle.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy