Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/johnlockefoundation/property-tax-bill/archive/refs/heads/main.zipNC Property Tax Bill — WordPress plugin
The property-tax-demo tool (currently on GitHub Pages) as a WordPress plugin, with the
in-tool "How we calculated this" methodology disclosure and the long-form
Methodology Notes both carried across.
Nothing about the calculation, the data, or the receipt changes. The plugin is the same tool, re-hosted.
- Shortcode:
[ptx_bill] - Block: "NC Property Tax Bill" (Gutenberg)
- Methodology page:
[ptx_methodology]
Placed two ways, with different settings — see PLACEMENT.md for the copy-and-paste version:
| Placement | Permalink | Shortcode |
|---|---|---|
| Standalone page | /property-tax-savings-calculator |
[ptx_bill heading_level="h2"] |
| Article | inside the post | [ptx_bill layout="compact" heading_level="h2" show_header="no"] |
Install
Requires WordPress 6.0+ and PHP 7.4+. No build step, no runtime dependencies.
wp-content/plugins/nc-property-tax-bill/ <- this directory
Zip it, or wp plugin install from a checkout, or copy it in over SSH and activate
NC Property Tax Bill in Plugins. The bundled logo and county data go with it.
Then put [ptx_bill] on a page, or insert the block. Assets load only on views that
actually contain the tool, and are cache-busted on file mtime so a plugin update
invalidates CDN and page caches without a version bump.
npm install is only needed to run the tests. node_modules is not used at runtime.
What is on the page
Enter your address, pick the matching residential parcel, and the tool prints a receipt for FY2025-26: what you paid, what you could have paid, and what you could have saved, as dollars and as a percent.
It covers all 100 counties. County-wide property tax only — municipal, school and special district taxes are out of scope, and the receipt says so.
39 counties (including Alamance, Franklin, Moore and Richmond) are at or below the benchmark and get an explanation instead of a receipt.
Where a receipt is not possible
For 56 of the 100 counties the reader gets a receipt for their parcel. Two things stop a receipt, and the tool says so rather than reporting a failed search:
| Situation | Counties | What the reader gets |
|---|---|---|
| At or below the benchmark | 39, including Alamance, Franklin, Moore and Richmond | The no-savings sentence |
| No parcel address is published anywhere the tool can reach | Franklin, Hoke, Perquimans, Richmond | The county's savings rate, and why there is no receipt |
| Address resolves, but the parcel layer carries no assessed value | Camden, Chowan, Yancey | The county's savings rate, and why there is no receipt |
| Apartment blocks rather than an ordinary residence | any county, by parcel | No match |
Franklin and Richmond appear in two rows: they are county-level-only and at or below the
benchmark, so they get the no-savings sentence rather than a rate. The seven are decided by
FIPS in calc.js, so a county moving between lists is a one-line change. The reader's
address is never stored; see the note under the search box.
Methodology
Two pieces, both preserved verbatim from the demo:
| Where | What it is |
|---|---|
| The "How we calculated this" disclosure under the tool | The short, in-context note. Rendered by templates/method-disclosure.php. Suppress with show_method="no". |
The [ptx_methodology] page |
The long-form notes: sources, benchmark construction, the calculation contract, caveats. Rendered by templates/methodology.php. |
The calculation contract is unchanged:
paid = V * act / x
could_have = paid * (1 - savings_rate)
saved = paid * savings_rate # paid - could_have
percent = 100 * savings_rate # the "NN% lower" figure; kept as a fraction below 1%
assets/js/ptx-calc.js is a byte-identical copy of the demo's calc.js and
data/benchmarks.json a byte-identical copy of its build output. A test enforces both, so
if either is edited here instead of upstream, the suite fails.
Migration map
| Demo | Plugin |
|---|---|
index.html ` |