# Index Table – Indexing ACF repeater field titles and contents

Using this custom code, you can enable indexing of [Advanced Custom Fields](https://wordpress.org/plugins/advanced-custom-fields/) repeater field post titles and/or contents for the current post. Change the following parameters in the **$arguments** variable in the first part of the code as you need them:

* **'field\_names'** -> one or more repeater field names, separated by comma
* **'index\_title'** -> true or false, to index the post titles found in the repeater field
* **'index\_content'** -> true or false, to index the post contents found in the repeater field
* **'run\_shortcodes'** -> true or false, to run the shortcodes in the content fields

[What is this, and where do I put this custom code?](/safe-coding-guideline.md)

```php
add_filter(
	'asp_index_cf_contents_before_tokenize', // do not change this
	function ( $content, $post ) {

		// Change these arguments to your needs
		$arguments = array(
			'field_names'    => 'field1, field2', // Comma separated list of field names to index
			'index_title'    => true,     // To index the related post title
			'index_content'  => true, // To index the related post content
			'run_shortcodes' => true, // To run shortcodes within Flex element contents
		);

		// --------------------- WARNING: DO NOT CHANGE ANYTHING BELOW -------------------------
		$o = new class($arguments, $content, $post) {
			/**
			 * @var string
			 */
			private string $field_names = 'field1, field2';
			/**
			 * @var bool
			 */
			private bool $index_title = true;
			/**
			 * @var bool
			 */
			private bool $index_content = true;
			/**
			 * @var bool
			 */
			private bool $run_shortcodes = true;

			/**
			 * @var string
			 */
			private string $content;

			/**
			 * @var WP_Post
			 */
			private WP_Post $post;

			/**
			 * @param array<string, mixed> $args
			 */
			public function __construct( array $args, $content, $post ) {
				$this->field_names    = $args['field_names'] ?? $this->field_names;
				$this->index_title    = $args['index_title'] ?? $this->index_title;
				$this->index_content  = $args['index_content'] ?? $this->index_content;
				$this->run_shortcodes = $args['run_shortcodes'] ?? $this->run_shortcodes;
				$this->content        = $content;
				$this->post           = $post;
			}

			/**
			 * @param mixed $any
			 * @param int   $level
			 * @return string
			 */
			private function anyToString( $any, int $level = 0 ): string {
				$str = '';
				if ( is_array( $any ) ) {
					foreach ( $any as $sub_arr ) {
						$str .= ' ' . $this->anyToString( $sub_arr, $level + 1 );
					}
				} elseif ( !is_object($any) ) {
					$str = (string) $any;
				}

				return $str;
			}

			public function fetchRepeater(): string {
				$content = $this->content;
				$post    = $this->post;
				if ( function_exists('get_field') ) {

					$fn_arr = explode(',', $this->field_names);
					foreach ( $fn_arr as $field_name ) {
						$field_name = trim($field_name);
						if ( empty($field_name) ) {
							continue;
						}

						$args     = array(
							'p'         => $post->ID, // ID of a page, post, or custom type
							'post_type' => 'any',
						);
						$my_query = new WP_Query( $args );
						while ( $my_query->have_posts() ) :
							$my_query->the_post();
							$items = get_field($field_name);
							if ( empty($items) ) {
								continue;
							}
							if ( is_array($items) ) {
								foreach ( $items as $item ) {
									if ( isset($item->ID) ) {
										if ( $this->index_title ) {
											$content .= ' ' . get_the_title($item->ID);
										}
										if ( $this->index_content ) {
											$content .= ' ' . apply_filters('the_content', get_post_field('post_content', $item->ID));
										}
									} elseif ( is_array($item) || is_string($item) ) {
										if ( $this->run_shortcodes ) {
											$content .= ' ' . do_shortcode( $this->anyToString($item));
										} else {
											$content .= ' ' . $this->anyToString($item);
										}
									}
								}
							} elseif ( is_string($items) ) {
								$content .= ' ' . $items;
							}

						endwhile;
					}
				}
				return $content;
			}
		};

		return $o->fetchRepeater();
	},
	10,
	2
);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://knowledgebase.ajaxsearchpro.com/miscellaneous/tutorials/index-table-indexing-acf-repeater-field-titles-and-contents.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
