mirror of
https://github.com/caddyserver/website.git
synced 2025-06-15 18:54:49 -04:00
noot
This commit is contained in:
parent
985e365c9d
commit
ecf57209ec
1 changed files with 12 additions and 38 deletions
|
@ -10,7 +10,7 @@ This means that if you wish for your plugin to support placeholders, you must ex
|
||||||
|
|
||||||
If you are not yet familiar with placeholders, start by reading [here](/docs/conventions#placeholders)!
|
If you are not yet familiar with placeholders, start by reading [here](/docs/conventions#placeholders)!
|
||||||
|
|
||||||
## Placeholder Internals
|
## Placeholders Overview
|
||||||
|
|
||||||
Placeholders are a string in the format `{foo.bar}` used as dynamic configuration values, which is later evaluated at runtime.
|
Placeholders are a string in the format `{foo.bar}` used as dynamic configuration values, which is later evaluated at runtime.
|
||||||
|
|
||||||
|
@ -82,29 +82,25 @@ Since `srv1` used `{env.HOST}`, a normal placeholder, it was parsed as its own r
|
||||||
Some users may immediately notice that this means it is impossible to use the `{$ENV}` syntax in a JSON config. The solution to this is to process such placeholders at Provision time, which is covered below.
|
Some users may immediately notice that this means it is impossible to use the `{$ENV}` syntax in a JSON config. The solution to this is to process such placeholders at Provision time, which is covered below.
|
||||||
|
|
||||||
|
|
||||||
## How to use placeholders in your plugin
|
## Implementing placeholder support
|
||||||
|
|
||||||
#### Parse the raw placeholder value in your unmarshaler
|
You should not process placeholders when ummarshaling your Caddyfile. Instead, unmarshal the placeholders as strings in your configuration and evaluate them during either your module's execution or `Provision()` using a `caddy.Replacer`.
|
||||||
|
|
||||||
Placeholders are not evaluated at Caddyfile parse time, and should be preserved for later use. They are used as their raw string values.
|
|
||||||
|
|
||||||
In other words, parsing a placeholder is no different from parsing any other string.
|
### Examples
|
||||||
|
|
||||||
|
|
||||||
|
In this example, we are using a newly constructed replacer to process placeholders. It has access to placeholders such as `{env.HOST}`, but NOT `{http.request.uri}`
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (g *Gizmo) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
func (g *Gizmo) Provision(ctx caddy.Context) error {
|
||||||
d.Next()
|
repl := caddy.NewReplacer()
|
||||||
if !d.Args(&g.Name) {
|
g.Name = repl.ReplaceAll(g.Name,"")
|
||||||
// not enough args
|
return nil
|
||||||
return d.ArgErr()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Evaluate the placeholder during Match or Serve
|
Here, we extract a replacer out of the `context.Context` inside the `*http.Request`. This replacer has access to http placeholers, such as `{http.request.uri}`
|
||||||
|
|
||||||
In order to now correctly read our `g.Name` placeholder in a plugin matcher or middleware, we must extract the replacer from the context and use that replacer on our saved placeholder string.
|
|
||||||
|
|
||||||
This gives us a string with all valid replacements done, which we can then use in whichever way we want. In the example, we write those bytes to output
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (g *Gizmo) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
|
func (g *Gizmo) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
|
||||||
|
@ -116,25 +112,3 @@ func (g *Gizmo) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp
|
||||||
return next.ServeHTTP(w, r)
|
return next.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Alternatively, resolve the placeholder during Provision
|
|
||||||
|
|
||||||
If you only use global placeholders, like `env`, then you may initialize a global replacer at provision time, and use it to replace such values. This also allows users of config file formats other than Caddyfile to use environmental variables.
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (g *Gizmo) Provision(ctx caddy.Context) error {
|
|
||||||
repl := caddy.NewReplacer()
|
|
||||||
g.Name = repl.ReplaceAll(g.Name,"")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func (g *Gizmo) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
|
|
||||||
// in this case, you don't need to replace at serve-time anymore
|
|
||||||
_, err := w.Write([]byte(g.Name))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return next.ServeHTTP(w, r)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue