add_filter( 'the_content', $this, 'maybe_inject', 20 ); $loader->add_action( 'wp', $this, 'suppress_page_title' ); } public function maybe_inject( string $content ): string { // in_the_loop(): Avada's layout-builder header also runs the_content // filters; without this guard the layout was injected there, above the // site header, and consumed the once-only flag below. if ( ! is_singular() || ! in_the_loop() ) { return $content; } $page_id = get_queried_object_id(); if ( ! $page_id ) { return $content; } $collab_id = (int) get_post_meta( $page_id, '_academiccrew_collaboration_id', true ); // Fallback: CPT URL accessed directly — the queried object IS the collaboration. if ( ! $collab_id && is_singular( 'acc_collaboration' ) ) { $collab_id = $page_id; } if ( ! $collab_id ) { return $content; } static $injected = []; if ( isset( $injected[ $page_id ] ) ) { return $content; } $injected[ $page_id ] = true; return $this->render_crumb( $collab_id ) . $this->render_hero( $collab_id ) . '
' . '
' . $this->render_lede( $collab_id ) . $content . $this->render_partners( $collab_id ) . '
' . '' . '
' . $this->render_members( $collab_id ); } // --------------------------------------------------------------- // Title suppression (Avada + any theme that reads the_title in loop) // --------------------------------------------------------------- /** * Fired on every frontend request. Sets pyre_page_title (Avada) and * registers the_title filter (Gutenberg / any theme). * * Handles two cases: * • Auto-generated WP page linked to a acc_collaboration post * (identified by _academiccrew_collaboration_id meta on the page) * • CPT direct URL /projects/{slug} (is_singular('acc_collaboration')) */ public function suppress_page_title(): void { if ( ! is_singular() ) { return; } $page_id = get_queried_object_id(); if ( ! $page_id ) { return; } // Case 1: auto-generated WP page. $collab_id = (int) get_post_meta( $page_id, '_academiccrew_collaboration_id', true ); if ( $collab_id ) { update_post_meta( $page_id, 'pyre_page_title', 'no' ); add_filter( 'the_title', [ $this, 'blank_project_title' ], 10, 2 ); return; } // Case 2: CPT direct URL. if ( is_singular( 'acc_collaboration' ) ) { update_post_meta( $page_id, 'pyre_page_title', 'no' ); add_filter( 'the_title', [ $this, 'blank_project_title' ], 10, 2 ); } } /** Returns empty string for the queried object's title when rendered inside the loop. */ public function blank_project_title( string $title, int $id = 0 ): string { return ( (int) $id === get_queried_object_id() && in_the_loop() ) ? '' : esc_html( $title ); } // --------------------------------------------------------------- // Shared utilities // --------------------------------------------------------------- private function meta( int $id, string $key ): string { return (string) ( get_post_meta( $id, $key, true ) ?: '' ); } private function year_range( string $start, string $end ): string { $sy = $start ? (int) date_i18n( 'Y', strtotime( $start ) ) : 0; $ey = $end ? (int) date_i18n( 'Y', strtotime( $end ) ) : 0; if ( $sy && $ey ) { return $sy === $ey ? (string) $sy : $sy . "\u{2013}" . $ey; } if ( $sy ) { return $sy . "\u{2013}" . __( 'ongoing', 'academiccrew' ); } return $ey ? (string) $ey : ''; } private function project_status( string $end ): string { return ( $end && strtotime( $end ) < time() ) ? 'completed' : 'ongoing'; } // --------------------------------------------------------------- // 1. Breadcrumb // --------------------------------------------------------------- private function render_crumb( int $collab_id ): string { $archive_id = (int) get_option( 'academiccrew_collaborations_archive_page_id', 0 ); $archive_url = $archive_id ? get_permalink( $archive_id ) : null; if ( ! $archive_url ) { return ''; } $title = (string) get_the_title( $collab_id ); ob_start(); ?> post_title; $ptype = $this->meta( $collab_id, '_acc_project_type' ); $start = $this->meta( $collab_id, '_acc_start_date' ); $end = $this->meta( $collab_id, '_acc_end_date' ); $status = $this->project_status( $end ); $yr = $this->year_range( $start, $end ); $thumb = get_the_post_thumbnail_url( $collab_id, 'medium' ) ?: ''; $kw_raw = get_post_meta( $collab_id, '_acc_keywords', true ); $keywords = is_array( $kw_raw ) ? $kw_raw : []; $linked = (array) ( get_post_meta( $collab_id, '_acc_linked_members', true ) ?: [] ); $pi = CollaborationMeta::extract_pi_name( $linked ); $kicker_parts = array_filter( [ $ptype ? ucfirst( $ptype ) : '', $start ? date_i18n( 'Y', strtotime( $start ) ) : '', $pi ? 'PI ' . $pi : '', ] ); $status_label = $status === 'ongoing' ? __( 'Ongoing', 'academiccrew' ) : __( 'Completed', 'academiccrew' ); ob_start(); ?>
<?php echo esc_attr( $title ); ?>

meta( $collab_id, '_acc_short_desc' ); $h3 = '

' . esc_html__( 'Description', 'academiccrew' ) . '

'; if ( ! $lede ) { return $h3; } return '

' . esc_html( $lede ) . '

' . $h3; } // --------------------------------------------------------------- // 4. Partners box // --------------------------------------------------------------- private function render_partners( int $collab_id ): string { $raw = get_post_meta( $collab_id, '_acc_partners', true ); $partners = is_array( $raw ) ? array_filter( $raw ) : []; if ( empty( $partners ) ) { return ''; } ob_start(); ?>


< class="mcard">
<?php echo esc_attr( $mname ); ?>
>