PHPackages                             humanmade/hm-rewrite - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. humanmade/hm-rewrite

ActiveWordpress-muplugin[Utility &amp; Helpers](/categories/utility)

humanmade/hm-rewrite
====================

HM\_Rewrite is a wrapper for the WordPress WP Rewrite system. http://hmn.md/wordpress-rewrite-rules-hm-core-style/

1.2.0(2y ago)16115.9k↓50%17[7 issues](https://github.com/humanmade/hm-rewrite/issues)GPL-2.0-or-laterPHPPHP &gt;=5.2

Since Apr 22Pushed 2y ago26 watchersCompare

[ Source](https://github.com/humanmade/hm-rewrite)[ Packagist](https://packagist.org/packages/humanmade/hm-rewrite)[ RSS](/packages/humanmade-hm-rewrite/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (4)Used By (0)

hm-rewrite
==========

[](#hm-rewrite)

`HM_Rewrite` and `HM_Rewrite_Rule` are wrappers for the WordPress rewrite / wp\_query system.

The goal of HM\_Rewrite and associated fuctions / classes is to make it very easy to add new routing points with new pages (as in dynamic pages, `post_type_archive` etc). It basically wraps a few tasks into a nice API. Everything (almost) you need for setting up a new routing page can be done all at once, relying heavily on PHP Closures. It essentially wraps adding to the `rewrite_rules`, adding your template file to `template_redirect`, `wp_title` hook, `body_class` hook, `parse_query` hook etc. Also also provides some callbacks for conveniance. Each rewrite rule is an instance of `HM_Rewrite_Rule`. Here you add the regex / `wp_query` vars and any other options for the "page". For example a callback function to `parse_request` to add additional query vars, or a callback \* `body_class`. There is also a wrapper function for all of this in one call `hm_add_rewrite_rule()`. `hm_add_rewrite_rule()` is generally the recommended interface, you can interact with the underlying objects for more advanced stuff (and also tacking onto other rewrite rules)Simple use case example:

```
hm_add_rewrite_rule( array(
  'regex'     => '^users/([^/]+)/?',
  'query'     => 'author_name=$matches[1]',
  'template'  => 'user-archive.php',
  'body_class_callback' => function( $classes ) {
    $classes[] = 'user-archive';
    $classes[] = 'user-' . get_query_var( 'author_name' );

    return $classes;
  },
  'title_callback' => function( $title, $seperator ) {
    return get_query_var( 'author_name' ) . ' ' . $seperator . ' ' . $title;
  }
) );
```

A more advanced example using more callbacks:

```
hm_add_rewrite_rule( array(
  'regex'    => '^reviews/([^/]+)/?', // a review category page
  'query'    => 'review_category=$matches[1]',
  'template' => 'review-category.php',
  'request_callback' => function( WP $wp ) {
    // if the review category is "laptops" then only show items in draft
    if ( $wp->query_vars['review_category'] == 'laptops' )
      $wp->query_vars['post_status'] = 'draft';
  },
  'query_callback' => function( WP_Query $query ) {
    //overwrite is_home because WordPress gets it wrong here
    $query->is_home = false;
  },
  'body_class_callback' => function( $classes ) {
    $classes[] = get_query_var( 'review_category' );
    return $classes;
  },
  'title_callback' => function( $title, $seperator ) {
    return review_category . ' ' . $seperator . ' ' . $title;
  },
  'rewrite_tests_callback' => function() {
    return array(
      'Review Category' => array(
        '/reviews/foo/',
        '/reviews/bar/',
      ),
    );
  }
) );
```

Contribution guidelines
-----------------------

[](#contribution-guidelines)

see

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity43

Moderate usage in the ecosystem

Community28

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor3

3 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1128 days

Total

3

Last Release

1057d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/21655?v=4)[Ryan McCue](/maintainers/rmccue)[@rmccue](https://github.com/rmccue)

![](https://avatars.githubusercontent.com/u/208434?v=4)[John Blackbourn](/maintainers/johnbillion)[@johnbillion](https://github.com/johnbillion)

![](https://www.gravatar.com/avatar/f1d0ffccdc5d339ff98a91e1b224a0d92f93dc8c2f772124473a76655b83129c?d=identicon)[joehoyle](/maintainers/joehoyle)

---

Top Contributors

[![joehoyle](https://avatars.githubusercontent.com/u/161683?v=4)](https://github.com/joehoyle "joehoyle (19 commits)")[![rmccue](https://avatars.githubusercontent.com/u/21655?v=4)](https://github.com/rmccue "rmccue (10 commits)")[![johnbillion](https://avatars.githubusercontent.com/u/208434?v=4)](https://github.com/johnbillion "johnbillion (8 commits)")[![MaximeCulea](https://avatars.githubusercontent.com/u/5576409?v=4)](https://github.com/MaximeCulea "MaximeCulea (5 commits)")[![willmot](https://avatars.githubusercontent.com/u/308507?v=4)](https://github.com/willmot "willmot (4 commits)")[![richardswain](https://avatars.githubusercontent.com/u/888319?v=4)](https://github.com/richardswain "richardswain (3 commits)")[![tcrsavage](https://avatars.githubusercontent.com/u/907521?v=4)](https://github.com/tcrsavage "tcrsavage (3 commits)")[![asadowski10](https://avatars.githubusercontent.com/u/2150735?v=4)](https://github.com/asadowski10 "asadowski10 (3 commits)")[![jmslbam](https://avatars.githubusercontent.com/u/145887?v=4)](https://github.com/jmslbam "jmslbam (1 commits)")[![roborourke](https://avatars.githubusercontent.com/u/23417?v=4)](https://github.com/roborourke "roborourke (1 commits)")[![drubbaraisin](https://avatars.githubusercontent.com/u/268353305?v=4)](https://github.com/drubbaraisin "drubbaraisin (1 commits)")[![herewithme](https://avatars.githubusercontent.com/u/898608?v=4)](https://github.com/herewithme "herewithme (1 commits)")[![ericandrewlewis](https://avatars.githubusercontent.com/u/1087646?v=4)](https://github.com/ericandrewlewis "ericandrewlewis (1 commits)")

### Embed Badge

![Health badge](/badges/humanmade-hm-rewrite/health.svg)

```
[![Health](https://phpackages.com/badges/humanmade-hm-rewrite/health.svg)](https://phpackages.com/packages/humanmade-hm-rewrite)
```

###  Alternatives

[rainlab/blog-plugin

Blog plugin for October CMS

17257.7k](/packages/rainlab-blog-plugin)[rainlab/builder-plugin

Builder plugin for October CMS

17147.2k1](/packages/rainlab-builder-plugin)[pfefferle/wordpress-activitypub

The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format.

5671.4k1](/packages/pfefferle-wordpress-activitypub)[civicrm/civicrm-drupal-8

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

18238.1k2](/packages/civicrm-civicrm-drupal-8)[mediawiki/semantic-glossary

A terminology markup extension with a Semantic MediaWiki back-end

1352.4k](/packages/mediawiki-semantic-glossary)[humanmade/lottie-lite

A lightweight Lottie Animations Extension for WordPress

374.3k](/packages/humanmade-lottie-lite)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
