WP Residence Help WP Residence Help

  • WPRESIDENCE
  • Video Tutorials
  • Client Support
  • API
Home / WPResidence Translate Plugin / Post List Table Enhancements — Developer Internals

Post List Table Enhancements — Developer Internals

52 views 0

The WPResidence Translate post list integration is split into focused files under includes/admin/post-list-*.php. This article maps each file to a UI responsibility so you can trace behavior, override it, or extend it from a child plugin. For product context, read the user article and our multi-language real estate website guide.

File Map

File Responsibility
post-list-hooks.php Registers all filters/actions for the post list screen.
post-list-columns.php Registers the Language column and renders its cells.
post-list-filters.php Language filter dropdown, views, and pre_get_posts filtering.
post-list-title.php Translation links below the post title + sortable language ordering.
post-list-badge.php Edit-screen language badge.
post-list-actions.php Add Translation handler and draft cloning.
post-list-meta.php Meta cloning with per-key rules.
post-list-helpers.php Translation group lookups and shared helpers.

Hook Registration

All post list hooks are registered from wpr_translation_register_post_list_hooks( $screen ), triggered on current_screen. The function only hooks when the screen is a translatable post type list.

add_filter( "manage_edit-{$post_type}_columns",          'wpr_translation_register_language_column', 0 );
add_filter( "manage_{$post_type}_posts_columns",         'wpr_translation_register_language_column', 0 );
add_filter( "manage_edit-{$post_type}_sortable_columns", 'wpr_translation_register_sortable_language_column', 10 );

add_action( 'manage_posts_custom_column',                 'wpr_translation_render_language_column', 0, 2 );
add_action( 'manage_pages_custom_column',                 'wpr_translation_render_language_column', 0, 2 );
add_action( "manage_{$post_type}_posts_custom_column",    'wpr_translation_render_language_column', 0, 2 );

add_filter( "views_edit-{$post_type}",                    'wpr_translation_register_language_views', 20 );

add_action( 'restrict_manage_posts', 'wpr_translation_render_language_filter_control' );
add_action( 'pre_get_posts',         'wpr_translation_filter_admin_query_by_language' );

Assets are enqueued by wpr_translation_enqueue_post_list_assets() on the admin_enqueue_scripts hook.

Column Registration & Rendering

wpr_translation_register_language_column( $columns ) inserts a language key into the columns array. The cell is rendered by wpr_translation_render_language_column( $column, $post_id ), which:

  1. Resolves the element type via wpr_translation_get_element_type( $post_type ).
  2. Loads the translation group via wpr_translation_get_translation_group( $post_id, $element_type ).
  3. Iterates active languages from wpr_translation_get_active_languages().
  4. For each language, prints either:
    • An edit link to the existing translation post ID.
    • A link to admin.php?action=wpr_add_translation&post_id={id}&language={code} with a nonce from wpr_translation_get_translation_nonce_action().
    • A needs update badge when the group flags that language.

An additional helper, wpr_translation_add_post_list_column_class_aliases(), runs on admin_head-edit.php to keep CSS aliases stable across column variants.

Language Filter & Views

The dropdown above the table comes from wpr_translation_render_language_filter_control( $post_type ), registered on restrict_manage_posts. It emits a <select name=”wpr_language”> with one option per active language plus an Untranslated entry.

Filtering is applied in wpr_translation_filter_admin_query_by_language( $query ) on pre_get_posts. It converts the selected language into a post__in list of element IDs pulled from {$wpdb->prefix}wpestate_translation_translations, or a post__not_in set for the untranslated view.

Quick links above the table are added via wpr_translation_register_language_views( $views ), which merges per-language counts into the WordPress views_edit-{post_type} filter.

Sortable Language Column

wpr_translation_register_sortable_language_column( $columns ) exposes the language column as sortable. The real work happens in wpr_translation_apply_language_orderby_clause( $clauses, $query ) (hooked to posts_clauses), which joins against the translations table and orders by language_code.

A separate hook, wpr_translation_set_default_language_ordering( $query ) on pre_get_posts priority 5, ensures default-language posts appear first when no explicit order is chosen.

Title Row Links

wpr_translation_build_post_title_translation_links_markup( $post_id ) builds the HTML; wpr_translation_render_post_title_links_payload( $post_id ) wraps it for the admin footer script; wpr_translation_move_title_translation_links_under_title() (on admin_footer-edit.php) injects the markup after the post title via JavaScript.

Edit-Screen Badge

wpr_translation_render_edit_screen_language_badge() is bound to both admin_head-post.php and admin_head-post-new.php. It prints a minimal inline badge above the title block so the post’s language is visible even before the block editor JS loads.

The block editor’s rich header badge is injected by wpr_translate_enqueue_post_editor_language_badge_assets() in editor-header-language.php via the localized wprTranslatePostLanguage object.

The Add Translation Action

wpr_translation_handle_add_translation_request() is wired to a custom admin.php?action=wpr_add_translation URL. It:

  1. Validates the nonce with wpr_translation_get_translation_nonce_action( $post_id, $language ).
  2. Calls wpr_translation_create_translation_draft( $post_id, $language ).
  3. Redirects via wp_safe_redirect( get_edit_post_link( $new_post_id, ‘raw’ ) ).

wpr_translation_create_translation_draft() inserts a cloned draft (wp_insert_post), then calls wpr_translation_clone_attachments(), wpr_translation_clone_taxonomies(), wpr_translation_clone_meta_fields(), and finally wpr_translation_insert_translation_record() which writes the translation group row.

Meta Cloning Rules

wpr_translation_clone_meta_fields( $source_post_id, $new_post_id ) loads preferences from wpr_translation_get_cached_custom_field_preferences() and for each meta key uses wpr_translation_resolve_custom_field_rule() to decide:

  • copy – value is duplicated verbatim into the translation.
  • translate – value is placed with a translate placeholder via wpr_translation_prepare_translate_placeholder().
  • copy-once – value is copied on first clone only; later clones skip it. Tracked by wpr_translation_get_copy_once_tracker() / wpr_translation_mark_copy_once_key().
  • ignore – skipped entirely.

Shared Helpers

Function Purpose
wpr_translation_get_active_languages() Returns the language array used by every post-list component.
wpr_translation_get_element_type( $post_type ) Maps a WordPress post type slug to the plugin’s element_type key.
wpr_translation_get_translation_group( $post_id, $element_type ) Reads {$wpdb->prefix}wpestate_translation_translations and returns trid, translations array, source language, and needs-update flags.
wpr_translation_is_translation_post_available( $post_id ) Guards against trashed or missing posts before rendering edit links.
wpr_translation_resolve_post_language_code( $post_id, $post_type ) Resolves a single post’s language code.
wpr_translation_format_language_version_label( $code ) Formats the display label used on badges and column cells.
wpr_translation_generate_trid() Allocates a new group ID with SELECT MAX(trid)+1.

Extension Points

  • Use manage_edit-{post_type}_columns with priority > 0 to insert your own column after Language.
  • Hook wpr_translation_created (fired in wpr_translation_insert_translation_record()) to run code every time a translation is first created.
  • Override wpr_translation_get_element_type() by registering your own filter before the plugin loads, or by defining a replacement in a must-use plugin.
  • Add your custom post type to the translatable set by registering it publicly and enabling it in the Taxonomy Translation / Custom Field Rules screens.

Gotchas

  • Column filters are registered at priority 0 so they run before third-party plugins that modify the same columns. Re-register at priority 10+ to land after.
  • wpr_translation_set_default_language_ordering() runs at priority 5 on pre_get_posts. If you add your own ordering hook, run it after priority 5 or your order will be overwritten.
  • The Untranslated filter uses post__not_in, which is expensive on large sites. Pre-filter by author/date first if you hit performance issues at 10K+ posts.
  • The nonce key ties a specific post_id to a specific target language. Reusing the same link across two different source posts will fail nonce verification.

Further Reading

  • Translating Posts & Pages – Developer Internals – the editor hooks that pair with these list-screen hooks.
  • Translation Linking (trid system) – the schema these columns query.
  • WP_Query Language Filtering – how the same translation data shapes frontend queries.

For product context, visit the multi-language real estate website page.

WPResidence Translate Plugin

Related Articles

  • String Scanner — Developer Guide
  • The String Scanner
  • Gettext Pipeline & MO Files — Developer Guide
  • Gettext & MO Files — Making Translations Appear on the Front End

Help Categories

  • 18Agent, Agency & Developers
  • 5Blog Posts & Blog Lists
  • 38Elementor Shortcodes Built-In
  • 56FAQ
  • 15Footer
  • 5Getting Started
  • 37Header
  • 2IDX & MLSImport
  • 6Installation & Setup
  • 22Installation FAQ
  • 23Maps & Location Settings
  • 21Multi-Language Third Party Plugins
  • 6Other Third party Plugins
  • 19Pages
  • 4Payments & Monetization
  • 20Property Lists, Categories & Archive
  • 36Property Pages & Layouts
  • 31Search & Filtering
  • 163Technical how to | Custom Code Required
  • 8Technical: Actions and filters
  • 6Technical: Child Theme
  • 86Theme Options & Global Settings
  • 6Translations & Languages
  • 16WPBakery Shortcodes
  • 51WPResidence / WPEstate CRM
  • 50WPResidence 5.0 Documentation
  • 8WPResidence Elementor Studio
  • 50WPResidence Translate Plugin

Join Us On

Powered by WP Estate - All Rights Reserved
  • WPRESIDENCE
  • Video Tutorials
  • Client Support
  • API