Skip to content

Commit dbb47fb

Browse files
committed
docs: merged next and 0.3.x
1 parent 37acece commit dbb47fb

File tree

9 files changed

+44
-30
lines changed

9 files changed

+44
-30
lines changed

docs/0.3.x/en-US/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
- [The `tinker` Action](/docs/plugins/tinker)
4848
- [Writing Plugins](/docs/plugins/writing)
4949
- [Security Considerations](/docs/plugins/security)
50+
- [Publishing Plugins](/docs/plugins/publishing)
5051
- [Deploying](/docs/deploying/intro)
5152
- [Server Deployment](/docs/deploying/serverful)
5253
- [Serverless Deployment](/docs/deploying/serverless)

docs/0.3.x/en-US/advanced/arch.md

+9-11
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,23 @@ What is intended to be used directly is the `Template<G>` `struct`, which is int
1717

1818
The other commonly used system from this crate is the `Translator` system, explained in detail in [the i18n section](:i18n/intro). `Translator`s are passed around in `Rc`s, and `TranslationsManager` on the server caches all translations by default in memory on the server.
1919

20-
## Actix Web Integration
20+
## Server Integrations
2121

22-
The core of Perseus provides very few systems to set up a functional Perseus server though, which requires a significant amount of additional work. To this end, [`perseus-actix-web`](https://docs.rs/perseus-actix-web) is used to make this process easy. If you've ejected, you'll be working with this directly, which should be relatively simple, as it just accepts configuration options and then should simply work.
23-
24-
Note that this module provides a `configurer` function, which allows it to be modularly added to any existing Actix Web server, which is particularly useful if you want to run other endpoint on your server, or a system like [Diana](https://github.com/arctic-hen7/diana).
22+
The core of Perseus provides very few systems to set up a functional Perseus server though, which requires a significant amount of additional work. To this end, server integration crates are used to make this process easy. If you've ejected, you'll be working with these directly, which should be relatively simple, as they just accept configuration options and then should simply work.
2523

2624
## CLI
2725

28-
As documented in [this section](:cli), the CLI simply runs commands to execute the last two components of the Perseus system, acting as a convenience. It also contains these two components inside its binary (using [`include_dir!`](https://github.com/Michael-F-Bryan/include_dir))
26+
As documented in [this section](:cli), the CLI simply runs commands to execute the last two components of the Perseus system, acting as a convenience. It also contains these two components inside its binary (using [`include_dir!`](https://github.com/Michael-F-Bryan/include_dir)).
2927

30-
## CLI Builder
28+
### CLI Builder
3129

3230
This system can be further broken down into two parts.
3331

34-
### Static Generator
32+
#### Static Generator
3533

36-
This is a single binary that just imports the user's templates and some other information (like locales) and then calls `build_app`. This will result in generating a number of files to `.perseus/dist`, which will be served by the server to any clients, which will then hydrate those static pages into fully-fledged Sycamore templates.
34+
This is a single binary that just imports the user's templates and some other information (like locales) and then calls `build_app`. This will result in generating a number of files to `.perseus/dist/`, which will be served by the server to any clients, which will then hydrate those static pages into fully-fledged Sycamore templates.
3735

38-
### App Shell
36+
#### App Shell
3937

4038
This is encapsulated in `.perseus/src/lib.rs`, and it performs a number of integral functions:
4139

@@ -46,6 +44,6 @@ This is encapsulated in `.perseus/src/lib.rs`, and it performs a number of integ
4644
- Invokes the core app shell to manage initial/subsequent loads and translations
4745
- Handles error page displaying
4846

49-
## CLI Server
47+
### CLI Server
5048

51-
This is just an invocation of the `perseus-actix-web` module's systems with the data provided by the user through the `define_app!` macro. This also sets the default location for static content and the `index.html` file.
49+
This is just an invocation of the the appropriate server integration's systems with the data provided by the user through the `define_app!` macro. This also sets the default location for static content and the `index.html` file.

docs/0.3.x/en-US/hello-world.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,11 @@ Now, create a new directory called `src` and add a new file inside called `lib.r
5252
First, we import some things that'll be useful:
5353

5454
- `perseus::{define_app, ErrorPages, Template}` -- the -`define_app!` macro, which tells Perseus how your app works; the `ErrorPages` `struct`, which lets you tell Perseus how to handle errors (like _404 Not Found_ if the user goes to a nonexistent page); and the `Template` `struct`, which is how Perseus manages pages in your app
55-
- `std::rc::Rc` -- a [reference-counted smart pointer](https://doc.rust-lang.org/std/rc/struct.Rc.html) (you don't _have_ to understand these to use Perseus, but reading that link would be helpful)
56-
- `sycamore::template` -- Sycamore's [`template!` macro], which lets you write HTML-like code in Rust
55+
- `sycamore::view` -- Sycamore's `view!` macro, which lets you write HTML-like code in Rust
5756

58-
Then, we use the `define_app!` macro to declare the different aspects of the app, starting with the _templates_. We only have one template, which we've called `index` (a special name that makes it render at the root of your app), and then we define how that should look, creating a paragraph (`p`) containing the text `Hello World!`. Perseus does all kinds of clever stuff with this under the hood, and we put it in an `Rc` to enable that.
57+
Then, we use the `define_app!` macro to declare the different aspects of the app, starting with the _templates_. We only have one template, which we've called `index` (a special name that makes it render at the root of your app), and then we define how that should look, creating a paragraph (`p`) containing the text `Hello World!`.
5958

60-
Finally, we tell Perseus what to do if something in your app fails, like if the user goes to a page that doesn't exist. This requires creating a new instance of `ErrorPages`, which is a `struct` that lets you define a separate error page for every [HTTP status code](https://httpstatuses.com), as well as a fallback. Here, we've just defined the fallback. That page is given the URL that caused the error, the HTTP status code, and the actual error message, all of which we display with a Sycamore `template!`, with seamless interpolation.
59+
Finally, we tell Perseus what to do if something in your app fails, like if the user goes to a page that doesn't exist. This requires creating a new instance of `ErrorPages`, which is a `struct` that lets you define a separate error page for every [HTTP status code](https://httpstatuses.com), as well as a fallback. Here, we've just defined the fallback. That page is given the URL that caused the error, the HTTP status code, and the actual error message, all of which we display with a Sycamore `view!`, with seamless interpolation.
6160

6261
</details>
6362

docs/0.3.x/en-US/pitfalls-and-bugs.md

+4
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ wasm-opt = false
2020
```
2121

2222
This will disable optimizations for your Wasm bundle, which prevents this issue from occurring. Note however that you'll end up with very large bundles if you compile on your M1 Mac. Again though, this issue is set to be fixed very soon.
23+
24+
## I want to apply X to my `Cargo.toml`, but it doesn't work
25+
26+
Perseus has a rather unique code structure that will foil most attempts at modifying your own `Cargo.toml`. For example, if you wanted to change the `codegen_units` in the release profile of your app, you couldn't do this in your own `Cargo.toml`, it would have no effect. The reason for this is that the code your write is actually a library that's imported by the CLI's engines, so any custom configuration has to be made directly on the engines. In other words, you'll need to apply your changes on `.perseus/Cargo.toml` instead. You can also apply customizations on the server and the builder, which are separate crates under `.perseus/`. Note that modifying `.perseus/` and retaining your changes requires [ejecting](:ejecting), or you could [write a plugin](:plugins/writing) if it's a change you make a lot.
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Publishing Plugins
2+
3+
After you've written a plugin, you can either use it locally, or you can publish it to the world on <https://crates.io>, Rust's package registry. That will mean anyone in the world can use it in their own code, and you'll be contributing to the Perseus community! It's usual to name plugins beginning with `perseus-` (e.g. `perseus-size-opt`), but this isn't required.
4+
5+
Perseus also maintains a registry of all plugins that have been published, but we rely on users to let us know about their plugins. You can do this by [opening an issue](https://github.com/arctic-hen7/perseus/issues/new/choose) on the Perseus repository, and we'll be happy to include your project!
6+
7+
## Trusted Plugins
8+
9+
You may have noticed that some plugins in the Perseus registry have ticks next to them. These plugins are _trusted_, meaning they've been reviewed by the Perseus team and are considered to be high quality and safe to use. Note however that this is in no way a guarantee of quality, and that a trusted plugin may still contain malware or bugs, and that the Perseus team is in no way responsible for any plugin on the registry.
10+
11+
If you'd like to apply for your plugin to be trusted after it's been listed on the registry, reach out to the Perseus maintainer [by email](mailto:[email protected]), and a code review will be happily undertaken.
12+
13+
By the same token though, an untrusted plugin is not in any way an indication that a plugin is low quality or malicious, it just means it hasn't been reviewed by the Perseus team. If you don't want to have your plugin reviewed, no problem!

docs/0.3.x/en-US/second-app.md

+8-9
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Before we get to the cool part of building the actual pages of the app, we shoul
5151

5252
This is a little more advanced than the last time we did this, and there are a few things we should note.
5353

54-
The first is the import of `GenericNode`, which we define as a type parameter on the `get_error_pages` function. As we said before, this means your error pages will work on the client or the server, and they're needed in both environments. If you're interested, this separation of browser and server elements is done by Sycamore, and you can learn more about it [here](https://docs.rs/sycamore/0.6/sycamore/generic_node/trait.GenericNode.html).
54+
The first is the import of [`Html`](https://docs.rs/sycamore/0.7/sycamore/generic_node/trait.Html.html), which we define as a type parameter on the `get_error_pages` function. This makes sure that we can compile these views on the client or the server as long as they're targeting HTML (Sycamore can also target other templating formats for completely different systems, like MacOS desktop apps).
5555

5656
In this function, we also define a different error page for a 404 error, which will occur when a user tries to go to a page that doesn't exist. The fallback page (which we initialize `ErrorPages` with) is the same as last time, and will be called for any errors other than a _404 Not Found_.
5757

@@ -78,16 +78,15 @@ First, we import a whole ton of stuff:
7878
- `perseus`
7979
- `RenderFnResultWithCause` -- see below for an explanation of this
8080
- `Template` -- as before
81-
- `GenericNode` -- as before
81+
- `Html` -- as before (this is from Sycamore, but is re-exported by Perseus for convenience)
8282
- `http::header::{HeaderMap, HeaderName}` -- some types for adding HTTP headers to our page
8383
- `serde`
8484
- `Serialize` -- a trait for `struct`s that can be turned into a string (like JSON)
8585
- `Deserialize` -- a trait for `struct`s that can be *de*serialized from a string (like JSON)
86-
- `std::rc::Rc` -- same as before, you can read more about `Rc`s [here](https://doc.rust-lang.org/std/rc/struct.Rc.html)
8786
- `sycamore`
8887
- `component` -- a macro that turns a function into a Sycamore component
89-
- `template` -- the `template!` macro, same as before
90-
- `Template as SycamoreTemplate` -- the output of the `template!` macro, aliased as `SycamoreTemplate` so it doesn't conflict with `perseus::Template`, which is very different
88+
- `view` -- the `view!` macro, same as before
89+
- `View` -- the output of the `view!` macro
9190
- `SsrNode` -- Sycamore's representation of a node that will only be rendered on the server (this is re-exported from Perseus as well for convenience)
9291

9392
Then we define a number of different functions and a `struct`, each of which gets a section now.
@@ -100,17 +99,17 @@ Any template can take arguments in Perseus, which should always be given inside
10099

101100
### `index_page()`
102101

103-
This is the actual component that your page is. By annotating it with `#[component(IndexPage<G>)]`, we tell Sycamore to turn it into a complex `struct` that can be called inside `template!` (which we do in `template_fn()`), and the `#[perseus::template(IndexPage)]` tells Perseus to do a little bit of work behind the scenes so that you can use `index_page` directly in the later `.template()` call. In previous versions of Perseus, you needed to do that boilerplate work yourself.
102+
This is the actual component that your page is. By annotating it with `#[component(IndexPage<G>)]`, we tell Sycamore to turn it into a complex `struct` that can be called inside `view!` (which we do in `template_fn()`), and the `#[perseus::template(IndexPage)]` tells Perseus to do a little bit of work behind the scenes so that you can use `index_page` directly in the later `.template()` call. In previous versions of Perseus, you needed to do that boilerplate work yourself.
104103

105-
Note that `index_page()` takes `IndexPageProps` as an argument, which it can then access in the `template!`. This is Sycamore's interpolation system, which you can read about [here](https://sycamore-rs.netlify.app/docs/basics/template), but all you need to know is that it's basically seamless and works exactly as you'd expect.
104+
Note that `index_page()` takes `IndexPageProps` as an argument, which it can then access in the `view!`. This is Sycamore's interpolation system, which you can read about [here](https://sycamore-rs.netlify.app/docs/basics/template), but all you need to know is that it's basically seamless and works exactly as you'd expect.
106105

107106
The only other thing we do here is define an `<a>` (an HTML link) to `/about`. This link, and any others you define, will automatically be detected by Sycamore's systems, which will pass them to Perseus' routing logic, which means your users **never leave the page**. In this way, Perseus only pulls in the content that needs to change, and gives your users the feeling of a lightning-fast and weightless app.
108107

109108
_Note: external links will automatically be excluded from this, and you can exclude manually by adding `rel="external"` if you need._
110109

111110
### `head()`
112111

113-
This function is very similar to `index_page()`, except that it isn't a fully fledged Sycamore component, it just returns a `template! {}` instead. What this is used for is to define the content of the `<head>`, which is metadata for your website, like its `<title>`. As you can see, this is given the properties that `index_page()` takes, but we aren't using them for anything in this example. The `#[perseus::head]` macro tells Perseus to do some boilerplate work behind the scenes that's very similar to that done with `index_page`, but specialized for the `<head>`.
112+
This function is very similar to `index_page()`, except that it isn't a fully fledged Sycamore component, it just returns a `view! {}` instead. What this is used for is to define the content of the `<head>`, which is metadata for your website, like its `<title>`. As you can see, this is given the properties that `index_page()` takes, but we aren't using them for anything in this example. The `#[perseus::head]` macro tells Perseus to do some boilerplate work behind the scenes that's very similar to that done with `index_page`, but specialized for the `<head>`.
114113

115114
What's really important to note about this function is that it only renders to an `SsrNode`, which means you cannot use reactivity in here! Whatever is rendered the first time will be turned into a `String` and then statically interpolated into the document's `<head>`.
116115

@@ -140,7 +139,7 @@ This is just the equivalent of `.template()` for the `head()` function, and it d
140139

141140
This function is part of Perseus' secret sauce (actually _open_ sauce), and it will be called when the CLI builds your app to create properties that the template will take (it expects a string, hence the serialization). Here, we just hard-code a greeting in to be used, but the real power of this comes when you start using the fact that this function is `async`. You might query a database to get a list of blog posts, or pull in a Markdown documentation page and parse it, the possibilities are endless!
142141

143-
This function returns a rather special type, `RenderFnResultWithCause<IndexPageProps>`, which declares that your function will return `IndexPageProps` if it succeeds, and a special error if it fails. That error can be anything you want (it's a `Box<dyn std::error::Error>` internally), but it will also have a blame assigned to it that records whether it was the server or the client that caused the error, which will impact the final HTTP status code. You can use the `blame_err!` macro to create these errors easily, but any time you use `?` in functions that return this type will simply use the default of blaming the server and returning an HTTP status code of *500 Internal Server Error*.
142+
This function returns a rather special type, `RenderFnResultWithCause<IndexPageProps>`, which declares that your function will return `IndexPageProps` if it succeeds, and a special error if it fails. That error can be anything you want (it's a `Box<dyn std::error::Error>` internally), but it will also have a blame assigned to it that records whether it was the server or the client that caused the error, which will impact the final HTTP status code. You can use the `blame_err!` macro to create these errors easily, but any time you use `?` in functions that return this type will simply use the default of blaming the server and returning an HTTP status code of _500 Internal Server Error_.
144143

145144
It may seem a little pointless to blame the client in the build process, but the reason this can happen is because, in more advanced uses of Perseus (particularly [incremental generation](:strategies/incremental)), this function could be called as a result of a client's request with parameters that it provides, which could be invalid. Essentially, know that it's a thing that's important in more complex use-cases of Perseus.
146145

docs/0.3.x/en-US/templates/intro.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,4 @@ It's often necessary to make sure you're only running some logic on the client-s
6060

6161
This is a very contrived example, but what you should note if you try this is the flash from `server` to `client` (when you go to the page from the URL bar, not when you go in from the link on the index page), because the page is pre-rendered on the server and then hydrated on the client. This is an important principle of Perseus, and you should be aware of this potential flashing (easily solved by a less contrived example) when your users [initially load](:advanced/initial-loads) a page.
6262

63-
One important thing to note with this macro is that it will only work in a _reactive scope_ because it uses Sycamore's [context system](https://sycamore-rs.netlify.app/docs/advanced/contexts). In other words, you can only use it inside a `template!`, `create_effect`, or the like.
63+
One important thing to note with this macro is that it will only work in a _reactive scope_ because it uses Sycamore's [context system](https://sycamore-rs.netlify.app/docs/advanced/contexts). In other words, you can only use it inside a `view!`, `create_effect`, or the like.

0 commit comments

Comments
 (0)