diff --git a/data/hc_campaigns/hc_nppes_outdated.html b/data/hc_campaigns/hc_nppes_outdated.html index d7643ef..533be90 100644 --- a/data/hc_campaigns/hc_nppes_outdated.html +++ b/data/hc_campaigns/hc_nppes_outdated.html @@ -14,7 +14,7 @@

Hi {{ .Subscriber.Name }},

We pulled the public records for NPI {{ .Subscriber.Attribs.npi }} — here’s a free check

-

As a quick example, the public NPPES NPI Registry shows the record for {{ .Subscriber.Attribs.practice }} was last updated on {{ .Subscriber.Attribs.nppes_last_updated }} — about {{ .Subscriber.Attribs.nppes_years_stale }} years ago. That’s usually fine, but it’s only one of several things payers and CMS check. Our free tool runs your NPI against the public government sources in one place — no signup, no cost — and tells you exactly where you stand.

+

{{ if .Subscriber.Attribs.nppes_last_updated }}As a quick example, the public NPPES NPI Registry shows the record for {{ .Subscriber.Attribs.practice }} was last updated on {{ .Subscriber.Attribs.nppes_last_updated }} — about {{ .Subscriber.Attribs.nppes_years_stale }} years ago. That’s usually fine, but it’s only one of several things payers and CMS check. {{ else }}Your NPI touches several public government records — NPPES, the Medicare revalidation list, and the federal exclusion lists — and any one of them being off can hold up your payments. {{ end }}Our free tool runs your NPI against those public sources in one place — no signup, no cost — and tells you exactly where you stand.

Your free check covers:

@@ -31,7 +31,9 @@
Payers, clearinghouses, and CMS pull from NPPES. A stale address, taxonomy, or contact can cause claim denials, mail you never receive, and failed credentialing. CMS requires you to correct your NPPES record within 30 days of any change.
- + + {{ if .Subscriber.Attribs.nppes_last_updated }}
@@ -49,6 +51,7 @@
+ {{ end }}
diff --git a/scripts/build_healthcare_campaigns.py b/scripts/build_healthcare_campaigns.py index 530954b..39bfae0 100644 --- a/scripts/build_healthcare_campaigns.py +++ b/scripts/build_healthcare_campaigns.py @@ -140,6 +140,32 @@ def template_path(seg_key: str) -> str: return os.path.join(OUT_DIR, SEGMENTS[seg_key]["template"]) +def _eval_conditionals(html: str, attribs: dict) -> str: + """Minimal evaluator for the listmonk/Go `{{ if .Subscriber.Attribs.X }}A + {{ else }}B{{ end }}` blocks used in the templates, so TEST/PREVIEW renders + match what listmonk produces at send time (listmonk itself evaluates these + server-side; this is only for the standalone preview/test-send path). Treats + an attribute as truthy when it is present and non-empty. Supports an optional + {{ else }} and is non-nested (which is all the templates use).""" + import re + pat = re.compile( + r"\{\{\s*if\s+\.Subscriber\.Attribs\.(\w+)\s*\}\}(.*?)" + r"(?:\{\{\s*else\s*\}\}(.*?))?\{\{\s*end\s*\}\}", + re.DOTALL, + ) + + def repl(m: "re.Match") -> str: + key, if_body, else_body = m.group(1), m.group(2), m.group(3) or "" + return if_body if str(attribs.get(key, "")).strip() else else_body + + # Loop until stable so adjacent/multiple blocks all resolve. + prev = None + while prev != html: + prev = html + html = pat.sub(repl, html) + return html + + def render(seg_key: str, *, test: bool = False) -> tuple[str, str]: """Return (subject, html) for a segment. The html is the canonical data/hc_campaigns/