Skip to content
wiki.fftac.org

Content Types - Source Excerpt 02

Back to Content Types

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
}