Title: Alphabetical Pagination
Author: mansoormunib
Published: <strong>2012 年 10 月 25 日</strong>
Last modified: 2026 年 6 月 9 日

---

搜索插件

![](https://s.w.org/plugins/geopattern-icon/wp-snap-extended.svg)

# Alphabetical Pagination

 作者：[mansoormunib](https://profiles.wordpress.org/mansoormunib/)

[下载](https://downloads.wordpress.org/plugin/wp-snap-extended.2.4.2.zip)

 * [详情](https://cn.wordpress.org/plugins/wp-snap-extended/#description)
 * [评价](https://cn.wordpress.org/plugins/wp-snap-extended/#reviews)
 *  [安装](https://cn.wordpress.org/plugins/wp-snap-extended/#installation)
 * [开发进展](https://cn.wordpress.org/plugins/wp-snap-extended/#developers)

 [支持](https://wordpress.org/support/plugin/wp-snap-extended/)

## 描述

**Alphabetical Pagination** (formerly _WP-SNAP Extended!_) builds an alphabetical
index of post titles across any public post type. Visitors jump straight to a letter(
A, B, C …), browse a paginated list of matching posts, and click through to each
post’s permalink.

Built for modern WordPress: PHP 8.1+ typed classes, schema-validated options, prepared
SQL throughout, semantic markup, no jQuery dependency, no bundled CSS framework,
zero front-end JS by default.

#### Why use it

 * **Modern PHP 8.1+ architecture** — typed `final` classes under `includes/`, every
   superglobal sanitised, every echoed value escaped, every DB call prepared.
 * **Three embedding surfaces** — `[alphabetical_pagination]` shortcode, `alphabetical_pagination()`
   template tag, and a native Gutenberg block (`wp-snap-ext/index`).
 * **WooCommerce auto-mount** — one click renders the index above the shop loop 
   or product category archives via the native `woocommerce_before_shop_loop` action.
   No DOM hacks, no `posts_where` SQL filter injection.
 * **15 bundled alphabet packs** — English, Arabic, Chinese (Pinyin), German, Spanish,
   French, Greek, Hebrew, Hindi, Hungarian, Korean (Hangul Jamo), Russian, Thai,
   Turkish, Urdu.
 * **WPML + Polylang aware** — the letter cache keys on current language, so translated
   post sets render and cache per-language automatically.
 * **REST API** — `GET /wp-json/wp-snap-ext/v1/letters` and `/posts` for headless/
   React / app integrations.
 * **Documented developer hook API** — `do_action`/`apply_filters` at every render
   path so agencies can customise without forking.
 * **Transient letter-availability cache** — letter counts cached as transients,
   busted on `save_post`. Configurable TTL.
 * **ACF excerpt fallback** — supports top-level, sub-field, and deep flexible-content/
   repeater / group lookups via recursive `get_fields()` walk.
 * **WCAG 2.1 AA** — `<nav aria-label>`, `aria-current="page"`, `aria-disabled` 
   on empty letters, explicit `role="list"` / `role="listitem"` (Safari + VoiceOver
   list-stripping fix), descriptive per-letter `aria-label`, visible focus outlines.
 * **Zero front-end JS dependency by default** — no jQuery, no Bootstrap, no FontAwesome.
   Stylesheet is ~1 KB.

#### 2.3.0 feature surface

 * **Gutenberg block** — server-rendered `wp-snap-ext/index` block (no JS build 
   pipeline required). Renders identically to the shortcode + template tag.
 * **WooCommerce auto-mount** — toggle in **Settings  Alphabetical Pagination  WooCommerce**.
   Mount hook selectable: `woocommerce_before_shop_loop` (default), `woocommerce_archive_description`,
   or `woocommerce_before_main_content`.
 * **REST API endpoints** — `/wp-json/wp-snap-ext/v1/letters` returns `[{ letter,
   count, href }]`; `/wp-json/wp-snap-ext/v1/posts` returns paginated post payloads.
 * **Developer hooks**:
    - `do_action( 'wp_snap_ext/before_render', $context )`
    - `apply_filters( 'wp_snap_ext/pre_render', $html, $post_type, $display, $args)`—
      short-circuit
    - `apply_filters( 'wp_snap_ext/query_args', $args, $context )`
    - `apply_filters( 'wp_snap_ext/letter_href', $href, $letter, $base )`
    - `apply_filters( 'wp_snap_ext/excerpt', $excerpt, $post_id )`
    - `apply_filters( 'wp_snap_ext/render', $html, $post_type, $display, $args )`
    - `do_action( 'wp_snap_ext/after_render', $html, $context )`
 * **Transient letter-availability cache** — keyed by post_type, taxonomy, term,
   current language, alphabet pack, and menumisc setting. Invalidated on `save_post`,`
   deleted_post`, `trashed_post`, `untrashed_post`, and `switch_blog`. Default TTL
   1 hour, configurable.
 * **WPML + Polylang awareness** — cache key includes `wpml_current_language` or`
   pll_current_language()`; WP_Query runs with `suppress_filters => false` so translated
   post sets get filtered.
 * **15 multi-language alphabet packs** — pick a script from the dropdown, the freeform
   Local Alphabet field is overwritten on save.
 * **Appearance toggles** — Horizontal / Vertical layout, Uppercase / Lowercase 
   letter case, Disable Empty Letters (renders empty buckets as muted + `aria-disabled`),
   Hide Pagination If One Page.
 * **Generic taxonomy filter** — restrict the index to any registered taxonomy +
   term (beyond the legacy cat/tag args).
 * **Meta-key intra-bucket sorting** — set a post meta key + ASC / DESC to override
   post_title ordering within each letter bucket. Buckets still derive from post_title.
 * **Per-page override map** — `{ post_id => items_per_page }` so /glossary can 
   render 50 items per page while /products renders 20.
 * **DOM auto-injection** — for themes that don’t expose a hook: render the index
   in the footer and move it into a CSS selector via ~300 bytes of vanilla JS. No
   jQuery.

#### Backwards compatibility

 * The legacy `wp_snap()` template tag is preserved as a thin alias.
 * Legacy URL parameters `?snap=`, `?cp=`, and `?snap_paged=` continue to be honoured
   alongside the canonical `?alpha_order=` and `?alpha_paged=`.
 * Legacy `key_snap_*` option keys are migrated to `wp_snap_ext_*` automatically
   on activation.

### Usage

#### Gutenberg block

Add the **Alphabetical Pagination** block from the block inserter (Widgets category)
and configure attributes through the block sidebar:

 * `postType` — post type to index (default `post`).
 * `menu` — `1`, `2`, or `3` (see menu styles in the admin panel).
 * `firstload` — `all`, `none`, or `recent`.
 * `category` — category ID or `all`.
 * `includeChildren` — include category children.
 * `taxonomy` + `term` — restrict the index to a specific term of any registered
   taxonomy.
 * `display` — `true` (default) renders the post list under the letter nav; `false`
   renders only the letter nav.

The block is fully server-rendered — its HTML matches the shortcode and template
tag output byte for byte, and there is no JS build pipeline behind it.

#### Shortcode

Drop the shortcode into any post, page, widget, or Site Editor template part:

    ```
    [alphabetical_pagination]
    ```

All template-tag arguments are exposed as shortcode attributes:

    ```
    [alphabetical_pagination cat="15" child="true" menu="2" firstload="recent" post_type="post" display="true"]
    ```

Attribute reference:

 * `cat` — category ID, or `all`.
 * `child` — `true` to include category children (default `false`).
 * `menu` — 1, 2 or 3 (see menu styles in the admin panel).
 * `firstload` — `all`, `none` or `recent`.
 * `post_parent` — restrict to posts with a given parent ID.
 * `post_type` — defaults to `post`. Whitelisted against registered post types.
 * `display` — `true` (default) renders the post list under the letter nav; `false`
   renders only the letter nav.

The shortcode handler buffers its output through `ob_start()` / `ob_get_clean()`,
so the index renders exactly where you place the shortcode rather than breaking 
out of the surrounding layout.

#### Theme template tag

For deeper theme integration, call `alphabetical_pagination()` directly from a template
file. The legacy `wp_snap()` name is retained as a backwards-compatible alias.

    ```
    <?php
    if ( function_exists( 'alphabetical_pagination' ) ) {
        echo alphabetical_pagination();
    }
    ?>
    ```

Passing arguments works the same as the original `wp_snap()` API:

    ```
    <?php
    echo alphabetical_pagination( 'cat=15&child=true&firstload=recent' );
    ?>
    ```

Render an alphabetical index over a custom post type:

    ```
    <?php
    echo alphabetical_pagination( '', 'glossary_term' );
    ?>
    ```

Render only the letter navigation (without the post list):

    ```
    <?php
    echo alphabetical_pagination( '', 'post', false );
    ?>
    ```

#### URL query parameters

Once embedded, the plugin reads two query parameters on the front end:

 * `?alpha_order=A` — the active letter (or bucket, like `A-D`). `alpha_order=misc`
   selects the `#` bucket of non-alphanumeric titles.
 * `?alpha_paged=2` — the active pagination page.

These are isolated to the plugin (they do not collide with WordPress’s own `paged`/`
tag` / `cat` query vars). The legacy `?snap=` / `?cp=` parameters from earlier versions
are still accepted so existing bookmarks keep working.

#### Gutenberg block attributes

 Attribute
 Type Default Notes

 `postType`
 string `post` Any registered public post type.

 `menu`
 number `1` 1, 2, or 3.

 `firstload`
 string `recent` `all` / `none` / `recent`.

 `category`
 string “ Category ID or `all`.

 `includeChildren`
 boolean `false` Include category children.

 `taxonomy`
 string “ Any registered taxonomy slug.

 `term`
 number `0` Term ID for the taxonomy above.

 `display`
 boolean `true` Render the post list under the nav.

The block supports `wide` and `full` alignment via the `supports.align` declaration
in `block.json`.

#### REST API

Two read-only public routes under `/wp-json/wp-snap-ext/v1/`:

**`GET /letters`**

Query params: `post_type` (default `post`), `taxonomy`, `term`.

Response (200 OK):

    ```
    [ { "letter": "A", "count": 12, "href": "https://example.com/?alpha_order=A" }, … ]
    ```

**`GET /posts`**

Query params: `post_type`, `taxonomy`, `term`, `letter` (single character or `#`),`
page` (default 1), `per_page` (default 10, max 100).

Response (200 OK):

    ```
    { "posts": [ { "id": 42, "title": "...", "permalink": "...", "excerpt": "..." } ], "total": 75, "total_pages": 8, "page": 1, "per_page": 10 }
    ```

Toggle the endpoints on / off under **Settings  Alphabetical Pagination  REST API&
Cache**. Lockdown plugins that block public REST surface should leave the toggle
off.

#### WooCommerce auto-mount

Enable **Settings  Alphabetical Pagination  WooCommerce  Auto-mount on Shop**. The
index renders above the shop loop (or after the archive description / before main
content — pick the mount hook from the dropdown) on:

 * the WooCommerce shop archive,
 * product taxonomy archives (e.g. `/product-category/food`).

The mount uses native WooCommerce actions, never `posts_where`, so it does not collide
with caching plugins, SEO plugins, or multilingual plugins that also filter WP_Query.

#### Developer hooks

Customise behaviour without forking through the following hooks (added in 2.3.0):

    ```
    add_filter( 'wp_snap_ext/query_args', function( $args, $context ) {
        $args['meta_query'] = [ [ 'key' => 'featured', 'value' => '1' ] ];
        return $args;
    }, 10, 2 );

    add_filter( 'wp_snap_ext/letter_href', function( $href, $letter, $base ) {
        return str_replace( '?alpha_order=', '#letter/', $href );
    }, 10, 3 );

    add_filter( 'wp_snap_ext/excerpt', function( $excerpt, $post_id ) {
        return wp_trim_words( $excerpt, 25, '…' );
    }, 10, 2 );
    ```

Full list:

 * `do_action( 'wp_snap_ext/before_render', $context )` — fires before the index
   renders.
 * `apply_filters( 'wp_snap_ext/pre_render', $html, $post_type, $display, $args )`—
   short-circuit; return a string to replace the HTML.
 * `apply_filters( 'wp_snap_ext/query_args', $args, $context )` — mutate WP_Query
   arguments.
 * `apply_filters( 'wp_snap_ext/letter_href', $href, $letter, $base )` — rewrite
   letter link hrefs (router compatibility).
 * `apply_filters( 'wp_snap_ext/excerpt', $excerpt, $post_id )` — post-process the
   resolved excerpt.
 * `apply_filters( 'wp_snap_ext/render', $html, $post_type, $display, $args )` —
   final filter on rendered HTML.
 * `do_action( 'wp_snap_ext/after_render', $html, $context )` — fires after the 
   index has rendered.

#### Backend settings

Under **Settings  Alphabetical Pagination** you’ll find:

 * **Navigational Menu Options** — Local Alphabet, Menu Style, Group Posts, Recent
   Posts, CSS class names, Ignore When Alphabetizing.
 * **Presentational Options** — Fancy URLs, Fancy URL Name, Tabs.
 * **Pagination  Items Per Page** — integer, defaults to 10. Registered through 
   the WordPress Settings API and sanitised with `absint()`.
 * **Content Fallback  ACF Excerpt Fallback** — checkbox. When on, posts without
   a native WordPress excerpt fall back to the value of an ACF field instead of 
   the trimmed post content. ACF lookup chain: `get_field()`  `get_sub_field()`  
   recursive `get_fields()` walk for deeply nested flexible-content / repeater /
   group sub-fields.
 * **Content Fallback  ACF Field Name** — the field name (or key) read by `get_field()`
   when the toggle is enabled. The plugin gracefully no-ops if ACF (or ACF Pro) 
   is not installed.
 * **Appearance  Layout** — Horizontal or Vertical letter strip.
 * **Appearance  Letter Case** — Uppercase or Lowercase.
 * **Appearance  Disable Empty Letters** — renders empty buckets as muted + `aria-
   disabled`, with the anchor stripped.
 * **Appearance  Hide Pagination If One Page** — skips the Previous/Next strip when
   the filtered set fits on one page.
 * **Language  Alphabet Pack** — pick from 15 bundled scripts. Selecting a pack 
   overwrites the freeform Local Alphabet field on save.
 * **Sorting  Meta Key** — post meta key used for intra-bucket ordering instead 
   of post_title.
 * **Sorting  Meta Order** — ASC / DESC.
 * **Taxonomy Filter  Taxonomy + Term ID** — restrict the index to a single term
   of any registered taxonomy.
 * **WooCommerce  Auto-mount on Shop** + **Mount Hook** — see the WooCommerce section
   above.
 * **DOM Injection  Enable DOM Injection** + **Target Selector** — print the index
   in the footer and move it into a CSS selector via vanilla JS.
 * **REST API & Cache  Enable REST Endpoints** + **Cache TTL** — see the REST API
   section above.

## 屏幕截图

[[

## 安装

 1. Upload the `wp-snap-extended` directory to `/wp-content/plugins/`.
 2. Activate the plugin through the **Plugins** screen in WordPress.
 3. Visit **Settings  Alphabetical Pagination** to configure the menu style, alphabet
    pack, pagination limit, WooCommerce mount, content fallback, REST API, and other
    options.
 4. Embed the index in any post or page with the Gutenberg block, the shortcode, or
    the template tag from your theme.

## 常见问题

### Does the plugin still work if I’m calling `wp_snap()` from my theme?

Yes. `wp_snap()` is kept as a thin alias for `alphabetical_pagination()` with the
same parameter list, so existing themes continue to work unchanged.

### I need to embed the index inside a Gutenberg page.

Use the native **Alphabetical Pagination** block (added in 2.3.0) from the block
inserter under the Widgets category — it’s fully server-rendered and supports wide/
full alignment. The block sidebar exposes post type, menu style, firstload, category,
taxonomy + term, and display attributes. The legacy approach (Shortcode block with`[
alphabetical_pagination]`) still works.

### Does it integrate with WooCommerce?

Yes. Enable **Settings  Alphabetical Pagination  WooCommerce  Auto-mount on Shop**
and the index renders above the WooCommerce shop loop and product category archives
automatically. The mount uses native WooCommerce action hooks (`woocommerce_before_shop_loop`,`
woocommerce_archive_description`, or `woocommerce_before_main_content` — pick from
the dropdown) so it never collides with caching / SEO / multilingual plugins that
filter WP_Query.

### Is it WPML / Polylang compatible?

Yes. The transient letter-availability cache keys on the current language (via `
wpml_current_language` filter or `pll_current_language()` function), and `WP_Query`
runs with `suppress_filters => false`, so translated post sets are filtered and 
cached per-language automatically. Switching language busts the cache for that language
only.

### Can I get the data over REST for a headless front end?

Yes. Two read-only public endpoints under `/wp-json/wp-snap-ext/v1/`: `GET /letters`
returns `[{ letter, count, href }]`, `GET /posts` returns paginated post payloads
filtered by letter. Toggle on / off under **Settings  Alphabetical Pagination  REST
API & Cache**.

### How do I display the ACF field instead of the trimmed post content?

Go to **Settings  Alphabetical Pagination  Content Fallback**, enable **ACF Excerpt
Fallback**, and enter the ACF **Field Name** (e.g. `summary`). The plugin tries `
get_field()` first, then `get_sub_field()`, then walks the entire `get_fields()`
tree recursively to find the field even when it lives inside an ACF flexible-content
layout, repeater row, or group. Falls back to a trimmed extract of the post content
if ACF returns nothing.

### My theme has no obvious hook to drop the index into.

Enable **Settings  Alphabetical Pagination  DOM Injection  Enable DOM Injection**
and provide a CSS selector (e.g. `.entry-content`, `#primary > article:first-child`).
The plugin renders the index into a hidden `<template>` element in the footer and
a ~300-byte vanilla-JS snippet moves it into the matched element on `DOMContentLoaded`.
No jQuery, no dependencies.

### How do I sort posts by a custom field instead of the title?

Under **Settings  Alphabetical Pagination  Sorting**, set **Meta Key** to your post
meta key and **Meta Order** to ASC or DESC. The letter buckets still derive from`
post_title`, but the order of posts _within_ each bucket follows the meta value.
Useful for sorting glossary terms by importance, products by SKU, etc.

### Can I use a non-Latin alphabet (Arabic, Chinese pinyin, Cyrillic, Greek, Hebrew, Hindi, Korean, Thai, …)?

Yes. Pick the script from **Settings  Alphabetical Pagination  Language  Alphabet
Pack**. 15 packs are bundled: English, Arabic, Chinese (Pinyin A–Z), German (with
Umlauts), Spanish (with Ñ), French, Greek, Hebrew, Hindi (Devanagari), Hungarian,
Korean (Hangul Jamo), Russian (Cyrillic), Thai, Turkish, Urdu. Selecting a pack 
overwrites the freeform Local Alphabet field on save. You can also type a fully 
custom alphabet directly.

### Are the letter counts cached?

Yes. Letter availability is stored as a transient keyed by post_type / taxonomy /
term / current language / alphabet pack / menumisc setting. Default TTL is 1 hour(
configurable under **REST API & Cache  Cache TTL**). The cache is invalidated automatically
on `save_post`, `deleted_post`, `trashed_post`, `untrashed_post`, and `switch_blog`—
so editing a post immediately reflects in the index.

### Can I customise the output without editing the plugin?

Yes — every render path fires hooks (added in 2.3.0):

 * `wp_snap_ext/before_render`, `wp_snap_ext/after_render` — actions.
 * `wp_snap_ext/pre_render` — short-circuit filter (return a string to replace the
   HTML).
 * `wp_snap_ext/query_args` — mutate WP_Query args before the query runs.
 * `wp_snap_ext/letter_href` — rewrite letter link hrefs (useful for SPA routers).
 * `wp_snap_ext/excerpt` — post-process the resolved excerpt.
 * `wp_snap_ext/render` — final filter on the rendered HTML.

See the **Developer hooks** section above for code samples.

### Why are pagination URLs using `?alpha_paged=` instead of `?paged=`?

So they don’t collide with WordPress’s own paged query variable on category, tag,
or archive templates. You can paginate the alphabetical list independently of the
surrounding archive.

### Is the plugin accessible (WCAG)?

Yes — the markup targets WCAG 2.1 AA. The letter navigation is wrapped in a semantic`
<nav aria-label="Alphabetical Navigation">`, the active letter carries `aria-current
="page"`, empty letters carry `aria-disabled="true"`, every link has a descriptive`
aria-label`, and the stylesheet provides visible `:focus-visible` outlines. Explicit`
role="list"` / `role="listitem"` are emitted because Safari + VoiceOver strip the
implicit list role when `list-style:none` is applied.

## 评价

![](https://secure.gravatar.com/avatar/a06b4d7354859b942f05834c8b47c34e9d145122d315ac750e244551b93b4b31?
s=60&d=retro&r=g)

### 󠀁[……](https://wordpress.org/support/topic/7724069/)󠁿

 [KnightMan](https://profiles.wordpress.org/knightman/) 2017 年 2 月 7 日

![](https://secure.gravatar.com/avatar/a6d540b596998b116ff47f0aac83c6466f8757ead07f4e5294beab80679adf84?
s=60&d=retro&r=g)

### 󠀁[alphabetic order](https://wordpress.org/support/topic/alphabetic-order/)󠁿

 [dinwebb](https://profiles.wordpress.org/dinwebb/) 2017 年 2 月 7 日

 [ 阅读所有1条评价 ](https://wordpress.org/support/plugin/wp-snap-extended/reviews/)

## 贡献者及开发者

「Alphabetical Pagination」是开源软件。 以下人员对此插件做出了贡献。

贡献者

 *   [ mansoormunib ](https://profiles.wordpress.org/mansoormunib/)

[帮助将「Alphabetical Pagination」翻译成简体中文。](https://translate.wordpress.org/projects/wp-plugins/wp-snap-extended)

### 对开发感兴趣吗?

您可以[浏览代码](https://plugins.trac.wordpress.org/browser/wp-snap-extended/)，
查看[SVN仓库](https://plugins.svn.wordpress.org/wp-snap-extended/)，或通过[RSS](https://plugins.trac.wordpress.org/log/wp-snap-extended/?limit=100&mode=stop_on_copy&format=rss)
订阅[开发日志](https://plugins.trac.wordpress.org/log/wp-snap-extended/)。

## 更新日志

#### 2.4.2

 * Bumped “Tested up to” to WordPress 7.0. No functional changes.

#### 2.4.1

 * readme.txt metadata fix — limited Tags to wp.org’s maximum of 5 and trimmed the
   short description to the 150-character limit. No functional changes.

#### 2.4.0

 * **Tabbed settings page** — the admin panel is reorganised into four tabs using
   the standard WordPress `nav-tab` UI: **General**, **Styling**, **Integrations**,
   and **Developer**. After saving, you are returned to the tab you were editing(
   Post/Redirect/Get), not the first one.
 * **Styling mode** — new “Styling” choice on the Styling tab:
    - _Default CSS_ — loads the bundled `snap-style-default.css` skin (styled letter
      strip, post cards, pagination buttons) that mirrors the plugin’s preview.
    - _No CSS (theme consistent)_ — loads only the minimal structural `snap-style.
      css` so the output inherits your theme’s typography, colours, and button styles.
      This remains the default, so existing sites are unchanged on update.
    - Only the selected stylesheet is enqueued, and only on pages that actually 
      render the index.
 * **Developer tab** — copy-paste reference with `<pre><code>` snippets for the `[
   alphabetical_pagination]` shortcode, the `alphabetical_pagination()` template
   tag (with a `function_exists()` guard and the `wp_snap()` alias note), and the`
   wp_snap_ext/*` action/filter hooks.

#### 2.3.0

 * **Gutenberg block** — new server-rendered `wp-snap-ext/index` block. Drop the
   alphabetical index into any post, page, or Site Editor template with one click.
   No JS build pipeline required; block.json + render.php only.
 * **WooCommerce auto-mount** — toggle the new “Auto-mount on Shop” setting and 
   the index renders above the shop loop / product category archives automatically
   via the native `woocommerce_before_shop_loop` (or `woocommerce_archive_description`/`
   woocommerce_before_main_content`) action. No DOM hacks, no `posts_where` SQL 
   injection.
 * **REST API** — public endpoints under `/wp-json/wp-snap-ext/v1/`:
    - `GET /letters?post_type=…&taxonomy=…&term=…`  `[ { letter, count, href } ]`
    - `GET /posts?post_type=…&letter=A&page=1&per_page=10`  `{ posts, total, total_pages}`
    - Toggle on the settings page; uses the transient cache so repeated calls hit
      memory.
 * **Documented developer hook API** — every render path now fires:
    - `do_action( 'wp_snap_ext/before_render', $context )`
    - `apply_filters( 'wp_snap_ext/pre_render', $html, $post_type, $display, $args)`(
      short-circuit)
    - `apply_filters( 'wp_snap_ext/query_args', $args, $context )`
    - `apply_filters( 'wp_snap_ext/letter_href', $href, $letter, $base )`
    - `apply_filters( 'wp_snap_ext/excerpt', $excerpt, $post_id )`
    - `apply_filters( 'wp_snap_ext/render', $html, $post_type, $display, $args )`
    - `do_action( 'wp_snap_ext/after_render', $html, $context )`
 * **Transient letter-availability cache** — letter counts are cached as transients
   keyed by post_type / taxonomy / term / current language / alphabet pack. Invalidated
   on `save_post`, `deleted_post`, `trashed_post`, `untrashed_post`, `switch_blog`.
   Default TTL 1 hour (configurable).
 * **WPML + Polylang awareness** — the cache key includes the current language (
   via `wpml_current_language` or `pll_current_language()`) and WP_Query runs with`
   suppress_filters => false`, so translated post sets are filtered and cached per-
   language.
 * **Multi-language alphabet packs** — pick from 15 bundled scripts (English, Arabic,
   Chinese pinyin, German, Spanish, French, Greek, Hebrew, Hindi, Hungarian, Korean
   Jamo, Russian, Thai, Turkish, Urdu). Selecting a pack overwrites the freeform
   Local Alphabet field on save.
 * **Appearance toggles** — Horizontal/Vertical layout, Uppercase/Lowercase letter
   case, “Disable empty letters” (renders empty buckets as muted + `aria-disabled`),“
   Hide pagination if one page”.
 * **Generic taxonomy filter** — restrict the index to any registered taxonomy +
   term ID (beyond the legacy cat/tag args).
 * **Meta-key intra-bucket sorting** — set a post meta key + ASC/DESC to override
   post_title ordering within each letter bucket. Buckets themselves still derive
   from post_title.
 * **Per-page override map** — store a `{ post_id => items_per_page }` array so /
   glossary can render 50 items per page while /products renders 20.
 * **DOM auto-injection** — for themes that don’t expose a hook: render the index
   into a hidden `<template>` in the footer and move it into a CSS selector via 
   ~300 bytes of vanilla JS. No jQuery dependency.
 * **Accessibility preserved** — `<nav aria-label>`, `aria-current="page"`, explicit`
   role="list" / role="listitem"`, descriptive `aria-label` per letter link, `aria-
   disabled` on empty letters, visible focus outlines.

#### 2.2.0

 * URL parameters migrated to `?alpha_order=` and `?alpha_paged=` (legacy `?snap
   =` / `?cp=` / `?snap_paged=` still honoured).
 * Post titles are now rendered as links to each post’s permalink.
 * Accessibility (WCAG AA): letter navigation wrapped in a semantic `<nav aria-label
   ="Alphabetical Navigation">`, every letter link carries a descriptive `aria-label`,
   the active letter is exposed via `aria-current="page"`, and visible focus outlines
   are provided in the stylesheet.
 * New “Learn More” CTA below each post excerpt linking to the post permalink, with
   an `aria-label` that includes the post title.
 * New **Content Fallback** settings section: toggle “Use ACF field fallback if 
   post excerpt is missing” + text input “ACF Field Name”. When enabled and ACF 
   is active, the plugin reads the configured field via `get_field()` for posts 
   without a native excerpt.
 * Frontend post cards now show: linked title  excerpt (native  ACF fallback  trimmed
   content)  Learn More button.

#### 2.1.0

 * Rebranded as **Alphabetical Pagination**. Existing directory structure and option
   keys are preserved.
 * New template tag `alphabetical_pagination()` (the legacy `wp_snap()` is kept 
   as a backwards-compatible alias).
 * New `[alphabetical_pagination]` shortcode lets the index be embedded in any post
   or page. Attributes mirror the template tag arguments (`cat`, `child`, `menu`,`
   firstload`, `post_parent`, `post_type`, `display`).
 * New “Items Per Page” admin setting registered through the WordPress Settings 
   API (`register_setting`, `add_settings_section`, `add_settings_field`) and sanitised
   with `absint()`. Defaults to 10 if unset.
 * The post loop is now paginated; Previous / Next + numbered links are rendered
   through `paginate_links()` below the alphabetised post list.

#### 2.0.0

 * Requires PHP 8.1+. Plugin is now organised as typed classes under `includes/`.
 * Security: prepared statements on the legacy “ignore words” SQL path, full sanitisation
   of `$_GET` / `$_POST` / `$_SERVER` reads, escaped output, nonce + `manage_options`
   capability check on the settings page (was the deprecated numeric level “8”).
 * Settings now stored under the `wp_snap_ext_*` option prefix. Legacy `key_snap_*`
   values are migrated automatically on activation.
 * Stylesheet is registered through `wp_enqueue_scripts` and only enqueued on pages
   that actually call `wp_snap()`.
 * Standard navigation queries now use `WP_Query` instead of a hand-rolled SQL string.
 * Backwards-compatible `wp_snap()` template tag retained.

#### 1.0.0

 * Original Dinwebb fork of Nathan Olsen’s WP-SNAP! plugin.

## 额外信息

 *  版本 **2.4.2**
 *  最后更新：**2 天前**
 *  活跃安装数量 **30+**
 *  WordPress 版本 ** 5.0 或更高版本 **
 *  已测试的最高版本为 **7.0**
 *  PHP 版本 ** 8.1 或更高版本 **
 *  语言
 * [English (US)](https://wordpress.org/plugins/wp-snap-extended/)
 * 标签
 * [alphabetical](https://cn.wordpress.org/plugins/tags/alphabetical/)[glossary](https://cn.wordpress.org/plugins/tags/glossary/)
   [index](https://cn.wordpress.org/plugins/tags/index/)[navigation](https://cn.wordpress.org/plugins/tags/navigation/)
   [pagination](https://cn.wordpress.org/plugins/tags/pagination/)
 *  [高级视图](https://cn.wordpress.org/plugins/wp-snap-extended/advanced/)

## 评级

 2.3 星（最高 5 星）。

 *  [  1 条 5 星评价     ](https://wordpress.org/support/plugin/wp-snap-extended/reviews/?filter=5)
 *  [  0 条 4 星评价     ](https://wordpress.org/support/plugin/wp-snap-extended/reviews/?filter=4)
 *  [  0 条 3 星评价     ](https://wordpress.org/support/plugin/wp-snap-extended/reviews/?filter=3)
 *  [  0 条 2 星评价     ](https://wordpress.org/support/plugin/wp-snap-extended/reviews/?filter=2)
 *  [  2 条 1 星评价     ](https://wordpress.org/support/plugin/wp-snap-extended/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/wp-snap-extended/reviews/#new-post)

[查看全部评论](https://wordpress.org/support/plugin/wp-snap-extended/reviews/)

## 贡献者

 *   [ mansoormunib ](https://profiles.wordpress.org/mansoormunib/)

## 支持

有话要说吗？是否需要帮助？

 [查看支持论坛](https://wordpress.org/support/plugin/wp-snap-extended/)