Skip to main content

Turn local-business data into structured, SEO-ready HTML with a zero-dependency template engine and Schema.org JSON-LD builder.

Project description

localbiz-page

CI PyPI Python versions License: MIT

Turn local-business data into structured, SEO-ready HTML — with zero runtime dependencies.

localbiz-page pairs a tiny HTML template engine with deterministic parsers for Japanese local-business data (postal codes, addresses, opening hours, languages) and a Schema.org JSON-LD builder. Feed it a plain dict and an HTML template; get back a rendered page plus valid structured data for rich search results.

  • No dependencies. Pure Python standard library. pip install pulls in nothing else.
  • Deterministic. Same input → same output. No AI, no network calls.
  • Composable. Use the template engine, the parsers, or the JSON-LD builder independently.

日本語の説明は下のほうにあります

Install

pip install localbiz-page

Or just copy src/localbiz_page/ into your project — it has no dependencies.

Quick start

from localbiz_page import (
    TemplateEngine, build_local_business, to_script_tag,
    format_postal_code, parse_address, parse_opening_hours, map_languages,
)

# 1. Build Schema.org JSON-LD from raw fields.
jsonld = build_local_business(
    "青葉珈琲店",
    business_type="CafeOrCoffeeShop",
    url="https://example.com",
    telephone="03-1234-5678",
    postal_code=format_postal_code("1600021"),          # -> "160-0021"
    address=parse_address("東京都渋谷区神南1-2-3"),       # -> region / locality / street
    opening_hours=parse_opening_hours("09:00-18:00", "水"),
    languages=map_languages([{"対応可能な外国語名": "英語"}]),  # -> ["ja", "en"]
)

# 2. Render an HTML template against your data.
html = TemplateEngine().render(
    "<h1>{{ name }}</h1>{{ json_ld }}",
    {"name": "青葉珈琲店", "json_ld": to_script_tag(jsonld)},
)

See examples/generate.py for a full cafe.json + cafe_template.html → HTML pipeline.

The template engine

Double-brace syntax (so it never clashes with the single braces in inline CSS/JS or serialized JSON), three constructs:

Syntax Meaning
{{ name }} / {{ shop.city }} Variable substitution, with dotted paths
{{#if path}}...{{/if}} Conditional block (truthiness of path); nests freely
{{#for item in items}}...{{/for}} Loop over a list; item is exposed in the body
from localbiz_page import render

render("{{#if open}}Welcome, {{ name }}!{{/if}}", {"open": True, "name": "Aoba"})
# "Welcome, Aoba!"

# {{#if}} works inside {{#for}}, and outer variables stay in scope:
render("{{#for m in menu}}<li>{{ m.item }}{{#if m.hot}} 🔥{{/if}}</li>{{/for}}",
       {"menu": [{"item": "Coffee", "hot": True}]})
# "<li>Coffee 🔥</li>"

Rendering is recursive-descent, so conditionals and loops nest correctly and a loop body can reference both the loop variable and outer variables. Empty/missing values render as an empty string; None, "", [], {} and False are falsy for {{#if}}. An unclosed block raises ValueError.

No auto-escaping. Values are inserted verbatim — intended for trusted, structured input (you often want to embed HTML). Escape untrusted values yourself (e.g. html.escape) before putting them in the data dict. Single braces in the template pass through untouched, so inline CSS/JS is safe.

Local-business parsers

All functions are pure and side-effect free:

Function Input → Output
format_postal_code("1600021") "160-0021"
parse_address("東京都渋谷区…") {"addressRegion": "東京都", "addressLocality": "渋谷区", "streetAddress": "…"}
parse_opening_hours("09:00-18:00", "水") Schema.org OpeningHoursSpecification[]
parse_days_off("木 日 祝日") ["Thursday", "Sunday"]
map_languages([...]) ISO 639-1 codes, always including "ja"
should_display(value) filters Japanese "no data" markers (-, 無し, …)
safe_get(data, "a.b.c") nested dict access with default

JSON-LD builder

build_local_business(name, ...) returns a Schema.org JSON-LD dict. It accepts any LocalBusiness subtype via business_type ("Restaurant", "Store", "BeautySalon", …), omits empty fields, and takes an extra= dict for any additional Schema.org property. to_script_tag(jsonld) wraps it in a ready-to-embed <script type="application/ld+json"> tag.

Develop & test

PYTHONPATH=src python -m unittest discover -s tests -v
python examples/generate.py

No test dependencies — everything runs on the standard library.

Why "local business"?

The parsers encode conventions specific to Japanese local businesses (prefecture splitting, weekday-based opening hours, language-name mapping), so they shine for restaurants, cafes, salons, shops, studios and similar listing/directory pages. The template engine and JSON-LD builder, however, are entirely domain-agnostic — use them for any structured-content page.

License

MIT — see LICENSE.


日本語

ローカルビジネスの情報を、外部依存ゼロで構造化された SEO 向け HTML に変換するツールキットです。

  • 軽量 HTML テンプレートエンジン({{#if}} / {{#for}} / {{ 変数 }} の二重ブレース構文)
  • 日本のローカルビジネス向けパーサ(郵便番号・住所・営業時間・対応言語)
  • Schema.org LocalBusiness の JSON-LD ビルダ

いずれも Python 標準ライブラリのみで動作し、確定的(同じ入力なら同じ出力、AI 推論なし)です。 飲食店・サロン・クリニック・店舗など、住所と営業時間を持つ施設ページの生成に向いています。 テンプレートエンジンと JSON-LD ビルダ自体は業種非依存で、あらゆる用途に使えます。

使い方は examples/generate.pycafe.json から HTML を生成する一連の流れ)を参照してください。

ライセンスは MIT です。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

localbiz_page-0.1.0.tar.gz (15.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

localbiz_page-0.1.0-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file localbiz_page-0.1.0.tar.gz.

File metadata

  • Download URL: localbiz_page-0.1.0.tar.gz
  • Upload date:
  • Size: 15.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for localbiz_page-0.1.0.tar.gz
Algorithm Hash digest
SHA256 804f6ac94aad3bcb87614c04cee72cb1de46b767fb4af4a5f600ba6834dd665c
MD5 09b369fbc34b431ddc7922433894bbae
BLAKE2b-256 0d77a49e1fc4005f5cbbb826a4cf0f367c3b1f4f343a0d11930426874794fdbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for localbiz_page-0.1.0.tar.gz:

Publisher: publish.yml on asapura/localbiz-page

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file localbiz_page-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: localbiz_page-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for localbiz_page-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1bc01e1c03ea15e833ca5ccac97632158c68d522561afec5fca697d46ee20c29
MD5 0fde68bdd796a1fd3559d4fe3d72a156
BLAKE2b-256 b15e3c3c99ac3d3629e5c51fc49fe3db44b2f6e7730626358fd0c2eb64a01a82

See more details on using hashes here.

Provenance

The following attestation bundles were made for localbiz_page-0.1.0-py3-none-any.whl:

Publisher: publish.yml on asapura/localbiz-page

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page