Content Types - Source Excerpt 02
Summary
This source excerpt preserves a bounded section of 2IA.org/wp-content/themes/twoia-intelligence/inc/content-types.php so readers can inspect the evidence without opening the full source file.
**Source path:** 2IA.org/wp-content/themes/twoia-intelligence/inc/content-types.php
/**
* Register the organization directory content type.
*/
function twoia_register_organization_content_type() {
register_post_type(
'twoia_organization',
array(
'labels' => array(
'name' => __( 'Organizations', 'two-identities-anonymous' ),
'singular_name' => __( 'Organization', 'two-identities-anonymous' ),
'menu_name' => __( 'Organizations', 'two-identities-anonymous' ),
'name_admin_bar' => __( 'Organization', 'two-identities-anonymous' ),
'add_new' => __( 'Add New', 'two-identities-anonymous' ),
'add_new_item' => __( 'Add New Organization', 'two-identities-anonymous' ),
'edit_item' => __( 'Edit Organization', 'two-identities-anonymous' ),
'new_item' => __( 'New Organization', 'two-identities-anonymous' ),
'view_item' => __( 'View Organization', 'two-identities-anonymous' ),
'search_items' => __( 'Search Organizations', 'two-identities-anonymous' ),
'not_found' => __( 'No organizations found', 'two-identities-anonymous' ),
'not_found_in_trash' => __( 'No organizations found in Trash', 'two-identities-anonymous' ),
'all_items' => __( 'All Organizations', 'two-identities-anonymous' ),
'attributes' => __( 'Organization Attributes', 'two-identities-anonymous' ),
'featured_image' => __( 'Organization image', 'two-identities-anonymous' ),
'set_featured_image' => __( 'Set organization image', 'two-identities-anonymous' ),
'remove_featured_image' => __( 'Remove organization image', 'two-identities-anonymous' ),
'use_featured_image' => __( 'Use as organization image', 'two-identities-anonymous' ),
),
'description' => __( 'Verified or context-heavy directory profiles for civil-liberties, digital-rights, press-freedom, public-records, OSINT, privacy, AI-governance, and accountability organizations.', 'two-identities-anonymous' ),
'public' => true,
'show_in_rest' => true,
'menu_icon' => 'dashicons-groups',
'has_archive' => false,
'rewrite' => array(
'slug' => 'org',
'with_front' => false,
),
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'author', 'revisions', 'custom-fields' ),
'taxonomies' => array( 'organization_issue', 'organization_region', 'organization_type', 'organization_language' ),
'capability_type' => 'post',
'map_meta_cap' => true,
'delete_with_user' => false,
'exclude_from_search' => false,
)
);
}
add_action( 'init', 'twoia_register_organization_content_type' );
/**
* Register directory taxonomies.
*/
function twoia_register_organization_taxonomies() {
$taxonomies = array(
'organization_issue' => array(
'singular' => __( 'Organization Issue', 'two-identities-anonymous' ),
'plural' => __( 'Organization Issues', 'two-identities-anonymous' ),
'slug' => 'organization-issue',
),
'organization_region' => array(
'singular' => __( 'Organization Region', 'two-identities-anonymous' ),
'plural' => __( 'Organization Regions', 'two-identities-anonymous' ),
'slug' => 'organization-region',
),
'organization_type' => array(
'singular' => __( 'Organization Type', 'two-identities-anonymous' ),
'plural' => __( 'Organization Types', 'two-identities-anonymous' ),
'slug' => 'organization-type',
),
'organization_language' => array(
'singular' => __( 'Organization Language', 'two-identities-anonymous' ),
'plural' => __( 'Organization Languages', 'two-identities-anonymous' ),
'slug' => 'organization-language',
),
);
foreach ( $taxonomies as $taxonomy => $definition ) {
register_taxonomy(
$taxonomy,
array( 'twoia_organization' ),
array(
'labels' => array(
'name' => $definition['plural'],
'singular_name' => $definition['singular'],
'search_items' => sprintf(
/* translators: %s: taxonomy plural label. */
__( 'Search %s', 'two-identities-anonymous' ),
$definition['plural']
),
'all_items' => sprintf(
/* translators: %s: taxonomy plural label. */
__( 'All %s', 'two-identities-anonymous' ),
$definition['plural']
),
'edit_item' => sprintf(
/* translators: %s: taxonomy singular label. */
__( 'Edit %s', 'two-identities-anonymous' ),
$definition['singular']
),
'update_item' => sprintf(
/* translators: %s: taxonomy singular label. */
__( 'Update %s', 'two-identities-anonymous' ),
$definition['singular']
),
'add_new_item' => sprintf(
/* translators: %s: taxonomy singular label. */
__( 'Add New %s', 'two-identities-anonymous' ),
$definition['singular']
),
),
'public' => true,
'hierarchical' => true,
'show_admin_column' => true,
'show_in_rest' => true,
'rewrite' => array(
'slug' => $definition['slug'],
'with_front' => false,
),
)
);
}
}
add_action( 'init', 'twoia_register_organization_taxonomies' );
/**
* Include editorial content types in frontend search results.
*
* @param WP_Query $query Query object.
*/
function twoia_include_editorial_content_in_search( $query ) {
if ( is_admin() || ! $query->is_main_query() || ! $query->is_search() ) {
return;
}
$query->set( 'post_type', twoia_public_search_post_types() );
}
add_action( 'pre_get_posts', 'twoia_include_editorial_content_in_search' );
/**
* Return the best public URL for a publication lane card.
*
* Empty post-type archives do not help readers, so they route to a live
* source-controlled page until reviewed files exist in that lane.
*
* @param string $post_type Post type key.
* @param array $definition Post type definition.
* @param int $publish_count Number of published files for the post type.
* @return string
*/
function twoia_publication_lane_url( $post_type, $definition, $publish_count ) {
$archive_url = get_post_type_archive_link( $post_type );
if ( $publish_count > 0 && $archive_url ) {
return $archive_url;
}
if ( ! empty( $definition['landing'] ) ) {
return home_url( '/' . trim( $definition['landing'], '/' ) . '/' );
}
return $archive_url ? $archive_url : home_url( '/research/' );
}
/**
* Render publication lane cards for the research route.
*/
function twoia_render_publication_lanes() {
$content_types = twoia_editorial_content_types();
?>
<section class="section section--compact publication-lanes" aria-labelledby="twoia-publication-lanes-title">
<header class="section-header">
<p class="eyebrow"><?php esc_html_e( 'Publication lanes', 'two-identities-anonymous' ); ?></p>
<h2 id="twoia-publication-lanes-title"><?php esc_html_e( 'A real archive has jobs, not just posts.', 'two-identities-anonymous' ); ?></h2>
<p><?php esc_html_e( '2IA separates evergreen issue hubs, investigations, policy analysis, guides, toolkits, case studies, campaigns, and updates so readers know what kind of evidence and action each page is built for.', 'two-identities-anonymous' ); ?></p>
</header>
<div class="twoia-dossier-grid">
<?php foreach ( $content_types as $post_type => $definition ) : ?>
<?php
$count = wp_count_posts( $post_type );
$publish_count = $count && isset( $count->publish ) ? (int) $count->publish : 0;
$lane_url = twoia_publication_lane_url( $post_type, $definition, $publish_count );
$metadata = $publish_count > 0
? sprintf(
/* translators: %d: number of published items. */
esc_html( _n( '%d published file', '%d published files', $publish_count, 'two-identities-anonymous' ) ),
$publish_count
)
: esc_html__( 'Reader route', 'two-identities-anonymous' );
?>
<a class="briefing-panel briefing-panel--compact twoia-dossier-card twoia-dossier-card--link publication-lane-card" href="<?php echo esc_url( $lane_url ); ?>">
<span class="metadata-label"><?php echo esc_html( $metadata ); ?></span>
<h3><?php echo esc_html( $definition['plural'] ); ?></h3>
<p><?php echo esc_html( $definition['description'] ); ?></p>
</a>
<?php endforeach; ?>
</div>
</section>
<?php
}