Move the Alert Digest into a shared partial template, and add it to the today, tomorrow, and daily reports
This commit is contained in:
@@ -76,9 +76,10 @@ fail rendering instead of producing incomplete Markdown.
|
|||||||
|
|
||||||
Daily and Tomorrow call the shared `daypart_forecast` partial. Today calls
|
Daily and Tomorrow call the shared `daypart_forecast` partial. Today calls
|
||||||
`today_daypart_forecast` so it can omit elapsed or missing dayparts. Daily,
|
`today_daypart_forecast` so it can omit elapsed or missing dayparts. Daily,
|
||||||
Today, Tomorrow, and Hourly call the shared `precipitation_timing` partial.
|
Today, Tomorrow, and Hourly call the shared `alert_digest` and
|
||||||
Partial files are parsed with each top-level template at render time and
|
`precipitation_timing` partials. Partial files are parsed with each top-level
|
||||||
receive the same typed render context as the caller.
|
template at render time and receive the same typed render context as the
|
||||||
|
caller.
|
||||||
|
|
||||||
## Schema Contract
|
## Schema Contract
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ are:
|
|||||||
|
|
||||||
Shared named partials live under `internal/reporttemplate/templates/partials/`:
|
Shared named partials live under `internal/reporttemplate/templates/partials/`:
|
||||||
|
|
||||||
|
- `alert_digest.md.tmpl`, used by Daily, Today, Tomorrow, and Hourly
|
||||||
- `daypart_forecast.md.tmpl`, used by Daily and Tomorrow
|
- `daypart_forecast.md.tmpl`, used by Daily and Tomorrow
|
||||||
- `today_daypart_forecast.md.tmpl`, used by Today
|
- `today_daypart_forecast.md.tmpl`, used by Today
|
||||||
- `precipitation_timing.md.tmpl`, used by Daily, Today, Tomorrow, and Hourly
|
- `precipitation_timing.md.tmpl`, used by Daily, Today, Tomorrow, and Hourly
|
||||||
@@ -113,8 +114,8 @@ Tomorrow generated text uses the same `.GeneratedText.Summary`,
|
|||||||
Hourly. `.GeneratedText.ForecastDiscussion` is a slice of paragraphs and should
|
Hourly. `.GeneratedText.ForecastDiscussion` is a slice of paragraphs and should
|
||||||
be rendered with `range`.
|
be rendered with `range`.
|
||||||
|
|
||||||
Tomorrow uses the shared `daypart_forecast` and `precipitation_timing`
|
Tomorrow uses the shared `alert_digest`, `daypart_forecast`, and
|
||||||
partials.
|
`precipitation_timing` partials.
|
||||||
|
|
||||||
Tomorrow modules include the Hourly module fields plus:
|
Tomorrow modules include the Hourly module fields plus:
|
||||||
|
|
||||||
@@ -144,7 +145,8 @@ Daily generated text uses `.GeneratedText.Summary`,
|
|||||||
`.GeneratedText.Confidence`. Forecast discussion is a slice of paragraphs and
|
`.GeneratedText.Confidence`. Forecast discussion is a slice of paragraphs and
|
||||||
should be rendered with `range`.
|
should be rendered with `range`.
|
||||||
|
|
||||||
Daily uses the shared `daypart_forecast` and `precipitation_timing` partials.
|
Daily uses the shared `alert_digest`, `daypart_forecast`, and
|
||||||
|
`precipitation_timing` partials.
|
||||||
|
|
||||||
Daily uses template ID `daily`, generated-text schema ID `daily`, and prompt
|
Daily uses template ID `daily`, generated-text schema ID `daily`, and prompt
|
||||||
source `internal/reporttemplate/prompts/daily.generated_text.md`.
|
source `internal/reporttemplate/prompts/daily.generated_text.md`.
|
||||||
@@ -179,7 +181,7 @@ should be rendered with `range`.
|
|||||||
|
|
||||||
Today uses the `today_daypart_forecast` partial so elapsed or missing dayparts
|
Today uses the `today_daypart_forecast` partial so elapsed or missing dayparts
|
||||||
can be omitted while Daily and Tomorrow keep their fallback row. It also uses
|
can be omitted while Daily and Tomorrow keep their fallback row. It also uses
|
||||||
the shared `precipitation_timing` partial.
|
the shared `alert_digest` and `precipitation_timing` partials.
|
||||||
|
|
||||||
Today uses template ID `today`, generated-text schema ID `today`, and prompt
|
Today uses template ID `today`, generated-text schema ID `today`, and prompt
|
||||||
source `internal/reporttemplate/prompts/today.generated_text.md`.
|
source `internal/reporttemplate/prompts/today.generated_text.md`.
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ var templates = map[string]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var templatePartials = []string{
|
var templatePartials = []string{
|
||||||
|
"templates/partials/alert_digest.md.tmpl",
|
||||||
"templates/partials/daypart_forecast.md.tmpl",
|
"templates/partials/daypart_forecast.md.tmpl",
|
||||||
"templates/partials/precipitation_timing.md.tmpl",
|
"templates/partials/precipitation_timing.md.tmpl",
|
||||||
"templates/partials/today_daypart_forecast.md.tmpl",
|
"templates/partials/today_daypart_forecast.md.tmpl",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func TestTemplateLookup(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Template() error = %v", err)
|
t.Fatalf("Template() error = %v", err)
|
||||||
}
|
}
|
||||||
for _, want := range []string{"# {{ .Report.Title }}", "**Updated:**", "## Current Conditions", "## Hourly Forecast", "## Forecast Discussion"} {
|
for _, want := range []string{"# {{ .Report.Title }}", "**Updated:**", `{{ template "alert_digest" . }}`, "## Current Conditions", "## Hourly Forecast", "## Forecast Discussion"} {
|
||||||
if !strings.Contains(source, want) {
|
if !strings.Contains(source, want) {
|
||||||
t.Fatalf("template missing %q:\n%s", want, source)
|
t.Fatalf("template missing %q:\n%s", want, source)
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ func TestTomorrowTemplateLookup(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Template() error = %v", err)
|
t.Fatalf("Template() error = %v", err)
|
||||||
}
|
}
|
||||||
for _, want := range []string{"# {{ .Report.Title }}", "**Forecast date:**", `{{ template "daypart_forecast" . }}`, `{{ template "precipitation_timing" . }}`, "## Forecast Discussion"} {
|
for _, want := range []string{"# {{ .Report.Title }}", "**Forecast date:**", `{{ template "alert_digest" . }}`, `{{ template "daypart_forecast" . }}`, `{{ template "precipitation_timing" . }}`, "## Forecast Discussion"} {
|
||||||
if !strings.Contains(source, want) {
|
if !strings.Contains(source, want) {
|
||||||
t.Fatalf("template missing %q:\n%s", want, source)
|
t.Fatalf("template missing %q:\n%s", want, source)
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ func TestDailyTemplateLookup(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Template() error = %v", err)
|
t.Fatalf("Template() error = %v", err)
|
||||||
}
|
}
|
||||||
for _, want := range []string{"# {{ .Report.Title }}", "**Forecast date:**", `{{ template "daypart_forecast" . }}`, `{{ template "precipitation_timing" . }}`, "## Forecast Discussion"} {
|
for _, want := range []string{"# {{ .Report.Title }}", "**Forecast date:**", `{{ template "alert_digest" . }}`, `{{ template "daypart_forecast" . }}`, `{{ template "precipitation_timing" . }}`, "## Forecast Discussion"} {
|
||||||
if !strings.Contains(source, want) {
|
if !strings.Contains(source, want) {
|
||||||
t.Fatalf("template missing %q:\n%s", want, source)
|
t.Fatalf("template missing %q:\n%s", want, source)
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func TestTodayTemplateLookup(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Template() error = %v", err)
|
t.Fatalf("Template() error = %v", err)
|
||||||
}
|
}
|
||||||
for _, want := range []string{"# {{ .Report.Title }}", "**Forecast date:**", "## Current Conditions", `{{ template "today_daypart_forecast" . }}`, `{{ template "precipitation_timing" . }}`, "## Forecast Discussion"} {
|
for _, want := range []string{"# {{ .Report.Title }}", "**Forecast date:**", `{{ template "alert_digest" . }}`, "## Current Conditions", `{{ template "today_daypart_forecast" . }}`, `{{ template "precipitation_timing" . }}`, "## Forecast Discussion"} {
|
||||||
if !strings.Contains(source, want) {
|
if !strings.Contains(source, want) {
|
||||||
t.Fatalf("template missing %q:\n%s", want, source)
|
t.Fatalf("template missing %q:\n%s", want, source)
|
||||||
}
|
}
|
||||||
@@ -285,8 +285,8 @@ func TestRenderHourly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assertOrderedText(t, text, []string{
|
assertOrderedText(t, text, []string{
|
||||||
"# Hourly Report",
|
"# Hourly Report",
|
||||||
"## Current Conditions",
|
|
||||||
"## Active Alerts",
|
"## Active Alerts",
|
||||||
|
"## Current Conditions",
|
||||||
"## Hourly Forecast",
|
"## Hourly Forecast",
|
||||||
"## Precipitation Timing",
|
"## Precipitation Timing",
|
||||||
"## Forecast Discussion",
|
"## Forecast Discussion",
|
||||||
@@ -351,6 +351,9 @@ func TestRenderTomorrow(t *testing.T) {
|
|||||||
{PeriodBeginsHourLabel: "3:00 PM", PeriodEndsHourLabel: "6:00 PM", MaxPopPercent: intPtr(70), MaxPopHourLabel: "3:00 PM", ExpectationPhrase: "Expect showers."},
|
{PeriodBeginsHourLabel: "3:00 PM", PeriodEndsHourLabel: "6:00 PM", MaxPopPercent: intPtr(70), MaxPopHourLabel: "3:00 PM", ExpectationPhrase: "Expect showers."},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AlertDigest: &testAlertDigest{
|
||||||
|
Relevant: []testAlert{{Event: "Wind Advisory", Headline: "Wind Advisory until 8:00 PM", Severity: "Moderate"}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -362,6 +365,8 @@ func TestRenderTomorrow(t *testing.T) {
|
|||||||
"**Forecast date:** Monday, June 15, 2026",
|
"**Forecast date:** Monday, June 15, 2026",
|
||||||
"**Updated:** Sunday, June 14, 2026 at 9:14 AM",
|
"**Updated:** Sunday, June 14, 2026 at 9:14 AM",
|
||||||
"Tomorrow starts dry before showers return later in the day.",
|
"Tomorrow starts dry before showers return later in the day.",
|
||||||
|
"## Active Alerts",
|
||||||
|
"- **Wind Advisory**: Wind Advisory until 8:00 PM",
|
||||||
"- **Overnight:** Partly cloudy, with temperatures falling from the mid 60s to the upper 50s.",
|
"- **Overnight:** Partly cloudy, with temperatures falling from the mid 60s to the upper 50s.",
|
||||||
"- **Morning:** Sunny, with temperatures rising from the upper 50s to the upper 60s.",
|
"- **Morning:** Sunny, with temperatures rising from the upper 50s to the upper 60s.",
|
||||||
"- **Afternoon:** Sunny, with temperatures in the upper 70s. Chance of precipitation is 70%.",
|
"- **Afternoon:** Sunny, with temperatures in the upper 70s. Chance of precipitation is 70%.",
|
||||||
@@ -384,6 +389,8 @@ func TestRenderTomorrow(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assertOrderedText(t, text, []string{
|
assertOrderedText(t, text, []string{
|
||||||
"# Monday's Weather",
|
"# Monday's Weather",
|
||||||
|
"Tomorrow starts dry before showers return later in the day.",
|
||||||
|
"## Active Alerts",
|
||||||
"## Daypart Forecast",
|
"## Daypart Forecast",
|
||||||
"- **Overnight:**",
|
"- **Overnight:**",
|
||||||
"- **Morning:**",
|
"- **Morning:**",
|
||||||
@@ -442,6 +449,9 @@ func TestRenderDaily(t *testing.T) {
|
|||||||
{PeriodBeginsHourLabel: "3:00 PM", PeriodEndsHourLabel: "6:00 PM", MaxPopPercent: intPtr(70), MaxPopHourLabel: "3:00 PM", ExpectationPhrase: "Expect showers."},
|
{PeriodBeginsHourLabel: "3:00 PM", PeriodEndsHourLabel: "6:00 PM", MaxPopPercent: intPtr(70), MaxPopHourLabel: "3:00 PM", ExpectationPhrase: "Expect showers."},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AlertDigest: &testAlertDigest{
|
||||||
|
Relevant: []testAlert{{Event: "Flood Watch", Headline: "Flood Watch until 6:00 PM", Severity: "Moderate"}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -453,6 +463,8 @@ func TestRenderDaily(t *testing.T) {
|
|||||||
"**Forecast date:** Monday, June 15, 2026",
|
"**Forecast date:** Monday, June 15, 2026",
|
||||||
"**Updated:** Sunday, June 14, 2026 at 9:14 AM",
|
"**Updated:** Sunday, June 14, 2026 at 9:14 AM",
|
||||||
"The selected day starts dry before showers return later in the day.",
|
"The selected day starts dry before showers return later in the day.",
|
||||||
|
"## Active Alerts",
|
||||||
|
"- **Flood Watch**: Flood Watch until 6:00 PM",
|
||||||
"- **Morning:** Sunny, with temperatures rising from the upper 50s to the upper 60s.",
|
"- **Morning:** Sunny, with temperatures rising from the upper 50s to the upper 60s.",
|
||||||
"- **Afternoon:** Showers, with temperatures in the upper 70s. Chance of precipitation is 70%.",
|
"- **Afternoon:** Showers, with temperatures in the upper 70s. Chance of precipitation is 70%.",
|
||||||
"- **3:00 PM** to **6:00 PM**: Expect showers. The peak precipitation chance is 70% at 3:00 PM.",
|
"- **3:00 PM** to **6:00 PM**: Expect showers. The peak precipitation chance is 70% at 3:00 PM.",
|
||||||
@@ -466,6 +478,8 @@ func TestRenderDaily(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assertOrderedText(t, text, []string{
|
assertOrderedText(t, text, []string{
|
||||||
"# Monday's Weather",
|
"# Monday's Weather",
|
||||||
|
"The selected day starts dry before showers return later in the day.",
|
||||||
|
"## Active Alerts",
|
||||||
"## Daypart Forecast",
|
"## Daypart Forecast",
|
||||||
"- **Morning:**",
|
"- **Morning:**",
|
||||||
"- **Afternoon:**",
|
"- **Afternoon:**",
|
||||||
@@ -535,6 +549,9 @@ func TestRenderToday(t *testing.T) {
|
|||||||
{PeriodBeginsHourLabel: "3:00 PM", PeriodEndsHourLabel: "6:00 PM", MaxPopPercent: intPtr(70), MaxPopHourLabel: "3:00 PM", ExpectationPhrase: "Expect showers."},
|
{PeriodBeginsHourLabel: "3:00 PM", PeriodEndsHourLabel: "6:00 PM", MaxPopPercent: intPtr(70), MaxPopHourLabel: "3:00 PM", ExpectationPhrase: "Expect showers."},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AlertDigest: &testAlertDigest{
|
||||||
|
Relevant: []testAlert{{Event: "Wind Advisory", Headline: "Wind Advisory until 8:00 PM", Severity: "Moderate"}},
|
||||||
|
},
|
||||||
TodayPlanning: &testTodayPlanning{
|
TodayPlanning: &testTodayPlanning{
|
||||||
MorningReadiness: []string{"Morning weather looks routine."},
|
MorningReadiness: []string{"Morning weather looks routine."},
|
||||||
LateDayChangeWatch: []string{"Watch late-day shower timing."},
|
LateDayChangeWatch: []string{"Watch late-day shower timing."},
|
||||||
@@ -550,6 +567,8 @@ func TestRenderToday(t *testing.T) {
|
|||||||
"**Forecast date:** Monday, June 15, 2026",
|
"**Forecast date:** Monday, June 15, 2026",
|
||||||
"**Updated:** Monday, June 15, 2026 at 7:14 AM",
|
"**Updated:** Monday, June 15, 2026 at 7:14 AM",
|
||||||
"Today starts dry before showers return later in the day.",
|
"Today starts dry before showers return later in the day.",
|
||||||
|
"## Active Alerts",
|
||||||
|
"- **Wind Advisory**: Wind Advisory until 8:00 PM",
|
||||||
"Currently, it is 58°F and clear. It feels like 57°F, with a relative humidity of 61% and winds from the northwest at 9 mph.",
|
"Currently, it is 58°F and clear. It feels like 57°F, with a relative humidity of 61% and winds from the northwest at 9 mph.",
|
||||||
"- **Morning:** Sunny, with temperatures rising from the upper 50s to the upper 60s.",
|
"- **Morning:** Sunny, with temperatures rising from the upper 50s to the upper 60s.",
|
||||||
"- **Afternoon:** Showers, with temperatures in the upper 70s. Chance of precipitation is 70%.",
|
"- **Afternoon:** Showers, with temperatures in the upper 70s. Chance of precipitation is 70%.",
|
||||||
@@ -564,6 +583,8 @@ func TestRenderToday(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assertOrderedText(t, text, []string{
|
assertOrderedText(t, text, []string{
|
||||||
"# Today's Weather",
|
"# Today's Weather",
|
||||||
|
"Today starts dry before showers return later in the day.",
|
||||||
|
"## Active Alerts",
|
||||||
"## Current Conditions",
|
"## Current Conditions",
|
||||||
"## Daypart Forecast",
|
"## Daypart Forecast",
|
||||||
"- **Morning:**",
|
"- **Morning:**",
|
||||||
@@ -652,6 +673,12 @@ func TestRenderDaypartTemplatesUseRichHelperFields(t *testing.T) {
|
|||||||
t.Fatalf("rendered template missing %q:\n%s", want, text)
|
t.Fatalf("rendered template missing %q:\n%s", want, text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if strings.Contains(text, "## Active Alerts") {
|
||||||
|
t.Fatalf("rendered template includes empty Active Alerts section:\n%s", text)
|
||||||
|
}
|
||||||
|
if strings.Contains(text, "\n\n\n") {
|
||||||
|
t.Fatalf("rendered template includes excess blank lines:\n%s", text)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,18 +930,21 @@ type testModules struct {
|
|||||||
type testTomorrowModules struct {
|
type testTomorrowModules struct {
|
||||||
Dayparts []testTomorrowDaypart
|
Dayparts []testTomorrowDaypart
|
||||||
PrecipTiming *testPrecipTiming
|
PrecipTiming *testPrecipTiming
|
||||||
|
AlertDigest *testAlertDigest
|
||||||
}
|
}
|
||||||
|
|
||||||
type testTodayModules struct {
|
type testTodayModules struct {
|
||||||
CurrentConditions *testCurrentConditions
|
CurrentConditions *testCurrentConditions
|
||||||
Dayparts []testTomorrowDaypart
|
Dayparts []testTomorrowDaypart
|
||||||
PrecipTiming *testPrecipTiming
|
PrecipTiming *testPrecipTiming
|
||||||
|
AlertDigest *testAlertDigest
|
||||||
TodayPlanning *testTodayPlanning
|
TodayPlanning *testTodayPlanning
|
||||||
}
|
}
|
||||||
|
|
||||||
type testDailyModules struct {
|
type testDailyModules struct {
|
||||||
Dayparts []testDailyDaypart
|
Dayparts []testDailyDaypart
|
||||||
PrecipTiming *testPrecipTiming
|
PrecipTiming *testPrecipTiming
|
||||||
|
AlertDigest *testAlertDigest
|
||||||
}
|
}
|
||||||
|
|
||||||
type testTodayPlanning struct {
|
type testTodayPlanning struct {
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
|
|
||||||
{{ .GeneratedText.Summary }}
|
{{ .GeneratedText.Summary }}
|
||||||
|
|
||||||
{{ template "daypart_forecast" . }}
|
{{ template "alert_digest" . }}{{ template "daypart_forecast" . }}{{ if and .Modules.PrecipTiming .Modules.PrecipTiming.PrecipitationWindows }}{{ template "precipitation_timing" . }}{{ else }}{{ end -}}
|
||||||
|
|
||||||
{{ template "precipitation_timing" . }}
|
|
||||||
## Forecast Discussion
|
## Forecast Discussion
|
||||||
{{ range .GeneratedText.ForecastDiscussion }}
|
{{ range .GeneratedText.ForecastDiscussion }}
|
||||||
{{ . }}
|
{{ . }}
|
||||||
|
|||||||
@@ -4,16 +4,10 @@
|
|||||||
|
|
||||||
{{ .GeneratedText.Summary }}
|
{{ .GeneratedText.Summary }}
|
||||||
|
|
||||||
## Current Conditions
|
{{ template "alert_digest" . }}## Current Conditions
|
||||||
|
|
||||||
{{ with .Modules.CurrentConditions }}{{ with .TemperatureF }}Currently, it is {{ . }}°F{{ with $.Modules.CurrentConditions.ConditionTextLower }} and {{ . }}{{ end }}.{{ else }}{{ with .ConditionText }}Currently, it is {{ . }}.{{ else }}Current conditions are unavailable.{{ end }}{{ end }}{{ with .ApparentTemperatureF }} It feels like {{ . }}°F{{ with $.Modules.CurrentConditions.RelativeHumidityPercent }}, with a relative humidity of {{ . }}%{{ end }}{{ with $.Modules.CurrentConditions.WindDirectionText }} and winds from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}{{ end }}.{{ else }}{{ with .RelativeHumidityPercent }} Relative humidity is {{ . }}%.{{ end }}{{ with .WindDirectionText }} Winds are from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}.{{ end }}{{ end }}{{ else }}Current conditions are unavailable.{{ end }}
|
{{ with .Modules.CurrentConditions }}{{ with .TemperatureF }}Currently, it is {{ . }}°F{{ with $.Modules.CurrentConditions.ConditionTextLower }} and {{ . }}{{ end }}.{{ else }}{{ with .ConditionText }}Currently, it is {{ . }}.{{ else }}Current conditions are unavailable.{{ end }}{{ end }}{{ with .ApparentTemperatureF }} It feels like {{ . }}°F{{ with $.Modules.CurrentConditions.RelativeHumidityPercent }}, with a relative humidity of {{ . }}%{{ end }}{{ with $.Modules.CurrentConditions.WindDirectionText }} and winds from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}{{ end }}.{{ else }}{{ with .RelativeHumidityPercent }} Relative humidity is {{ . }}%.{{ end }}{{ with .WindDirectionText }} Winds are from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}.{{ end }}{{ end }}{{ else }}Current conditions are unavailable.{{ end }}
|
||||||
|
|
||||||
{{ if and .Modules.AlertDigest .Modules.AlertDigest.Relevant }}## Active Alerts
|
|
||||||
{{ range .Modules.AlertDigest.Relevant -}}
|
|
||||||
- **{{ if .Event }}{{ .Event }}{{ else }}{{ .Headline }}{{ end }}**{{ with .Headline }}: {{ . }}{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end -}}
|
|
||||||
## Hourly Forecast
|
## Hourly Forecast
|
||||||
{{ with .Modules.HourlyForecast }}{{ range .Periods -}}
|
{{ with .Modules.HourlyForecast }}{{ range .Periods -}}
|
||||||
- **{{ if .HourLabel }}{{ .HourLabel }}{{ else }}{{ .Name }}{{ end }}:**{{ with .TemperatureF }} {{ . }}°F{{ end }}{{ with .TextDescriptionLower }} and {{ . }}{{ else }}{{ with .TextDescription }} and {{ . }}{{ end }}{{ end }}.{{ if .MentionPrecipitation }}{{ with .ProbabilityOfPrecipitationPercent }} Probability of precipitation is {{ . }}%.{{ end }}{{ end }}
|
- **{{ if .HourLabel }}{{ .HourLabel }}{{ else }}{{ .Name }}{{ end }}:**{{ with .TemperatureF }} {{ . }}°F{{ end }}{{ with .TextDescriptionLower }} and {{ . }}{{ else }}{{ with .TextDescription }} and {{ . }}{{ end }}{{ end }}.{{ if .MentionPrecipitation }}{{ with .ProbabilityOfPrecipitationPercent }} Probability of precipitation is {{ . }}%.{{ end }}{{ end }}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{{ define "alert_digest" }}{{ if and .Modules.AlertDigest .Modules.AlertDigest.Relevant }}## Active Alerts
|
||||||
|
{{ range .Modules.AlertDigest.Relevant -}}
|
||||||
|
- **{{ if .Event }}{{ .Event }}{{ else }}{{ .Headline }}{{ end }}**{{ with .Headline }}: {{ . }}{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ end }}{{ end }}
|
||||||
@@ -5,14 +5,12 @@
|
|||||||
|
|
||||||
{{ .GeneratedText.Summary }}
|
{{ .GeneratedText.Summary }}
|
||||||
|
|
||||||
{{ with .Modules.CurrentConditions }}
|
{{ template "alert_digest" . }}{{ with .Modules.CurrentConditions }}
|
||||||
## Current Conditions
|
## Current Conditions
|
||||||
{{ with .TemperatureF }}Currently, it is {{ . }}°F{{ with $.Modules.CurrentConditions.ConditionTextLower }} and {{ . }}{{ end }}.{{ else }}{{ with .ConditionText }}Currently, it is {{ . }}.{{ else }}Current conditions are unavailable.{{ end }}{{ end }}{{ with .ApparentTemperatureF }} It feels like {{ . }}°F{{ with $.Modules.CurrentConditions.RelativeHumidityPercent }}, with a relative humidity of {{ . }}%{{ end }}{{ with $.Modules.CurrentConditions.WindDirectionText }} and winds from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}{{ end }}.{{ else }}{{ with .RelativeHumidityPercent }} Relative humidity is {{ . }}%.{{ end }}{{ with .WindDirectionText }} Winds are from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}.{{ end }}{{ end }}
|
{{ with .TemperatureF }}Currently, it is {{ . }}°F{{ with $.Modules.CurrentConditions.ConditionTextLower }} and {{ . }}{{ end }}.{{ else }}{{ with .ConditionText }}Currently, it is {{ . }}.{{ else }}Current conditions are unavailable.{{ end }}{{ end }}{{ with .ApparentTemperatureF }} It feels like {{ . }}°F{{ with $.Modules.CurrentConditions.RelativeHumidityPercent }}, with a relative humidity of {{ . }}%{{ end }}{{ with $.Modules.CurrentConditions.WindDirectionText }} and winds from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}{{ end }}.{{ else }}{{ with .RelativeHumidityPercent }} Relative humidity is {{ . }}%.{{ end }}{{ with .WindDirectionText }} Winds are from the {{ . }}{{ with $.Modules.CurrentConditions.WindSpeedMph }} at {{ . }} mph{{ end }}.{{ end }}{{ end }}
|
||||||
|
|
||||||
{{ end }}
|
{{ end -}}
|
||||||
{{ template "today_daypart_forecast" . }}
|
{{ template "today_daypart_forecast" . }}{{ if and .Modules.PrecipTiming .Modules.PrecipTiming.PrecipitationWindows }}{{ template "precipitation_timing" . }}{{ else }}{{ end -}}
|
||||||
|
|
||||||
{{ template "precipitation_timing" . }}
|
|
||||||
## Forecast Discussion
|
## Forecast Discussion
|
||||||
{{ range .GeneratedText.ForecastDiscussion }}
|
{{ range .GeneratedText.ForecastDiscussion }}
|
||||||
{{ . }}
|
{{ . }}
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
|
|
||||||
{{ .GeneratedText.Summary }}
|
{{ .GeneratedText.Summary }}
|
||||||
|
|
||||||
{{ template "daypart_forecast" . }}
|
{{ template "alert_digest" . }}{{ template "daypart_forecast" . }}{{ if and .Modules.PrecipTiming .Modules.PrecipTiming.PrecipitationWindows }}{{ template "precipitation_timing" . }}{{ else }}{{ end -}}
|
||||||
|
|
||||||
{{ template "precipitation_timing" . }}
|
|
||||||
## Forecast Discussion
|
## Forecast Discussion
|
||||||
{{ range .GeneratedText.ForecastDiscussion }}
|
{{ range .GeneratedText.ForecastDiscussion }}
|
||||||
{{ . }}
|
{{ . }}
|
||||||
|
|||||||
Reference in New Issue
Block a user