Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Typograph Bundle Laravel Package

meniam/typograph-bundle

Symfony bundle that adds a Twig filter for typographing text using E. Muravjev's Typograph. Install via Composer, register the bundle, then apply {{ content | typograph }} in templates. Supports multiple named configs so different content types, like articles or news, can use their own typography se...

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The single most important finding is that this is not a Laravel package — it is a Symfony bundle whose registration model (new TypographBundle\FenrizbesTypographBundle() in AppKernel.php) predates Symfony Flex and has no Laravel equivalent. There is no TypographServiceProvider, no facade, no package auto-discovery. Architecturally, the bundle is a thin adapter: a Twig extension plus a DependencyInjection/Configuration.php tree that forwards options to E. Muravjev's Typograph algorithm. That means roughly 90% of the package's value lives in the underlying meniam/typograph library and the algorithm it wraps; the bundle layer is the part that does not fit.

For a Laravel codebase, the correct framing is: we are evaluating an algorithm plus a reference implementation, not a dependency we install. The bundle is a readable, MIT-licensed spec for how to wire the typographer and what options it accepts. That is a meaningful asset, but it changes the integration cost model from "composer require" to "extract and adapt," and it changes the ownership model from "upstream maintains this" to "we maintain this."

Integration feasibility. High, and bounded. The work decomposes cleanly: read vendor/meniam/typograph-bundle/src to identify the service class and config keys, translate Configuration.php into config/typograph.php, bind a singleton, expose a Blade directive or typograph() helper, and apply it at the presentation layer. The reference assessment estimates ~30 minutes of vendor reading; a realistic end-to-end estimate including fixture tests and one production surface is 1–3 engineer-days. Because the transformation is a pure, stateless string → string function with no I/O, no schema, and no external service, the blast radius is cosmetic: if it fails, content still renders, just with straight quotes and spaced dashes. This is one of the rare integrations where a failed pilot costs almost nothing to reverse.

Technical risk. The risk is concentrated in supply chain and silent failure, not in the algorithm:

  • Supply chain. Zero stars, zero dependents, last release December 2021, and evidence the repo was renamed (it-blaster/typograph-bundle → meniam/...). The Packagist metadata and badges still reference the old name. This is a vendor-or-fork candidate, not a platform dependency. The mitigation is cheap and must be mandatory: pin an exact version, commit composer.lock, and mirror to internal VCS or a private Satis registry so a repo deletion cannot break our build.
  • Silent failure. Typographers of this vintage tend to return the input unchanged on internal error rather than throwing. "No exception" does not mean "it worked." Any adoption must be gated on a fixture suite asserting on known inputs ('"Привет" - мир' → «Привет» — мир), plus negative fixtures for code blocks, URLs, and emails.
  • Content-domain risk. This is tuned for Russian typography. On English-only content the benefit is marginal and the weirdness is real. The decision to adopt should be scoped to Russian-language or Eastern-European-locale surfaces, not applied globally "because we have it."
  • HTML boundary. The typographer operates on plain text. Run it over rendered HTML and it will mangle attributes, alt text, and code samples. This is a design constraint the product must absorb: typography applies to source text, before Markdown/HTML rendering, on a whitelist of fields — never as a response-level middleware.

Key questions for the decision meeting.

  1. Is Russian (or a comparable locale) a real, prioritized market for rendered content, or a hypothetical?
  2. Is typographic correctness a first-class editorial quality bar, or a cosmetic nice-to-have? The answer determines whether we staff an owner for the rule configuration.
  3. Render-time or store-time? (Store-time destroys the author's raw text; render-time costs CPU per request. This is a product decision about editorial reversibility, not a technical one.)
  4. Do we depend on meniam/typograph directly, fork the bundle, or reimplement the rules? Note that the algorithm itself (mdash.ru) is a third-party asset whose rules are essentially frozen — which lowers churn risk but also means no future improvements.
  5. What is the reversal cost if we abandon this in six months? (Answer: low, if it is behind an interface from day one. That is the argument for trialing rather than debating.)

Integration Approach

Stack fit. Poor at the packaging layer, good at the domain layer. The bundle's Twig filter ({{ content | typograph }}) is incompatible with Blade — Blade has no pipe syntax, so copy-pasting the README produces a syntax error, not a typography bug. The Laravel-native equivalents are a global typograph() helper, a @typograph($text) directive, or a facade with @method annotations for IDE support. The bundle's AppKernel registration must be dropped entirely; there is no shim worth building.

Migration path. Do not install the bundle and try to make it behave like a Laravel package. Instead:

  1. Install it, read src/ and DependencyInjection/Configuration.php, and treat those as the specification.
  2. Decide whether to depend on meniam/typograph directly (preferred — fewer layers, fewer abandoned layers) or to vendor the bundle source into app/Services/ under our own namespace. Forking into our namespace is defensible here precisely because the upstream is dormant; we will be maintaining it regardless.
  3. Translate the Symfony config tree into config/typograph.php, preserving the named-config concept (default, articles, news) since per-content-type rules are the one genuinely product-relevant feature.
  4. Bind a TypographService singleton, then layer on the helper/directive, the Eloquent accessor, and the queued bulk pass for retrofitting existing content.

Compatibility. Three compatibility surfaces need explicit verification before committing: PHP version against the 2021-era codebase (expect older type-hint conventions), charset/locale end-to-end (MySQL charset, request encoding, and the typographer's configured charset must agree — a mismatch surfaces as mojibake that reads like a typography bug and will burn support time), and the HTML/Markdown boundary. Explicitly set locale and charset; unset values default to something we did not choose and the wrapper may silently pass text through unchanged. Confirm the exact FQCN of the typographer class in vendor/ before writing the service — do not trust the README.

Sequencing. Because the cost of reversal is low and the blast radius is cosmetic, sequence for fastest signal:

  1. Pilot on one surface — article bodies in a Russian-locale section — behind a feature flag.
  2. Build the fixture set first: 20–30 real strings from production content, run before/after, diff. Non-breaking spaces are invisible; regressions ship unnoticed without this step. Get editorial sign-off on the diffs, not engineering sign-off.
  3. Service + interface, then helper/directive, then the one template.
  4. Instrument: measure render time on a list page before and after. Typographing is regex-heavy and not free; if the delta is material, add a cached text_formatted column plus a queued bulk pass before expanding.
  5. Expand field-by-field via a whitelist. Never a blacklist — the typographer will happily rewrite --> and straight quotes inside code samples, JSON, URLs, and email addresses.

Operational Impact

Maintenance. Assume we own this. The package is dormant (last release December 2021, zero dependents, renamed repo), so there will be no upstream security patches, no PHP 8.x compatibility fixes, and no rule updates. The offsetting factor is that the underlying algorithm is essentially frozen — Muravjev's rules do not change — so the realistic maintenance burden is low-frequency compatibility work (PHP upgrades, framework upgrades) rather than active development. Concretely: mirror the package to internal VCS, pin the version, commit the lock file, and record in the ADR that a fork exists and who owns it. Budget a few hours per major PHP or Laravel upgrade. The larger ongoing cost is not code maintenance but rule governance — someone must own the YAML config, because typography settings are an editorial policy decision that will otherwise drift between content types.

Support. This is the underappreciated operational cost. Typography defects are invisible (a missing non-breaking space), subjective (which quote style is "correct"), and intermittent (locale- or encoding-dependent). Tier-1 support cannot triage "the dash looks wrong" reports. Two mitigations: (a) route typography issues to the editorial/content owner rather than engineering, and (b) keep the fixture suite as the contract — if the fixtures pass, the reported issue is a rule-configuration request, not a bug. Expect a small but persistent trickle of these in the first quarter after launch, tapering as the rule config stabilizes. Also expect the English-content question to come back: someone will ask why the marketing pages are not typographed, and the answer needs to be a documented scope decision, not an ad-hoc one.

Scaling. CPU cost is the scaling axis, and it is per-render, not per-user. On detail pages the cost is invisible; on list pages rendering 50 excerpts it is the difference between a ~40 ms and a ~4 ms rendering path. The mitigation is standard and cheap: cache formatted output per model (Cache::remember("article:{$id}:typographed", ...)), bust on saved, and for retrofits use a queued chunked bulk pass into an indexed text_formatted column. There is no horizontal-scaling concern — the transformation is stateless, so it scales trivially with app workers once caching is in place. Do not put this in API response middleware; walking JSON bodies to format string leaves will hit slugs, emails, and URLs and will be a recurring incident source.

Failure modes. Ranked by likelihood and cost:

  1. Silent no-op — input returned unchanged, no error, content renders with wrong quotes. Detectable only by fixture assertions; without them this can persist for months undetected.
  2. Mojibake — charset disagreement between database, request, and typographer. Looks like a typography bug, is actually an encoding bug, and will consume disproportionate triage time.
  3. HTML/code mangling — running over rendered HTML or unprotected technical fields. Highest severity because it can corrupt displayed code samples and attributes; prevented by whitelisting fields and formatting plain text before Markdown/HTML rendering.
  4. Stale cache — formatted column not invalidated on edit; editor changes text, page shows old typography. Low severity, high visibility, erodes editorial trust.
  5. English-content weirdness — marginal benefit, occasional artifacts, no clear owner to complain to.

None of these take the site down. That is precisely why this is a trial-and-instrument decision rather than a risk-committee decision — but it is also why it needs a named owner and a fixture suite, because cosmetic failures do not page anyone.

Ramp-up. Engineering ramp-up is genuinely low: a mid-level developer can read the vendor source and have a working singleton in half a day, and the pattern is well-trodden (helper, accessor, queued bulk pass). The real ramp-up is organizational: the editorial team needs to review typographed fixtures and own the rule configuration, and support needs to know this class of ticket exists and where to route it. Budget for a short editorial review session and a one-page internal note on scope (which locales, which fields, which exclusions) — that document, more than the code, is what prevents a year of low-grade confusion about why some pages are typographed and some are not.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle