Guide

Roper user guide

How to build Roper iPoll search and question displays with the Context Provider, Results, and Item blocks.

Built on Chart Builder with Interactivity API / Router navigation. Companion form and facet blocks wire to namespace prc-roper/context-provider.

Blocks at a glance

BlockRole
Roper Context ProviderQueries the Roper API and passes results to children
Roper ResultsPaginated list of questions inside a provider
Roper ItemOne question + Chart Builder bar chart (alone or in Results)

Context Provider modes

Fixed query (manual)

Enable Use a Fixed Query. Set keywords, exclusions, year range, and topic in the sidebar. The block removes the search header/bar when possible (remove leftovers manually if the template was edited). Frontend filtering is not supported in this mode.

Search mode

Leave Use a Fixed Query off. The block adds a search header and search bar. Users search by keyword on the frontend; advanced filters use companion form blocks targeting prc-roper/context-provider.

You may edit the search header text and button label. Do not break the search bar structure. The active term is appended on the frontend.

Items per page

Defaults to 10 (allowed 520). Passed to children as prc-roper/per-page context.

Filter recipe

Assemble filters from existing blocks (not built-in Roper block types):

ControlBlockKey settings
Exclude keywordsForm Input Textname qs_filter_exclude, namespace prc-roper/context-provider
After / Before yearsSelect Range Field (years)min 1987, current year on; child selects anchors qs_filter_start_date / qs_filter_end_date
Filter / ClearButtons as <button>anchors filter-roper-results-button / clear-roper-filters, namespace prc-roper/context-provider

Results text and tokens

Detach Facets Results Info and Selected Tokens, then set both blocks’ Target Namespace to prc-roper/context-provider (Results Info + Tokens List).

Roper Item layouts (manual mode)

When an Item sits outside Results, enter a Roper Question Id. Use Preview Item to toggle editor preview.

LayoutContent
Default (Question + Chart)Metadata + title above bar chart; optional Collapsible Question
QuestionMetadata and title only
ChartBar chart only

Collapsible charts lazy-load response data when expanded on the frontend.

Inside Results, the Item receives context data. Sidebar item controls stay hidden; a placeholder id roper-results-preview represents the list look in the editor.

Template markup

Copy-paste starting points from the Site Editor recipes. Prefer composing with the settings tables above when templates drift.

Filter card

Recipe:
  • Exclude Keywords: Form Input Text
    • Input Name: qs_filter_exclude
    • Target Namespace: prc-roper/context-provider
  • Before / After: Select Range Field
    • Select Range Type: Years
    • Minimum Value: 1987
    • Current Year: True
    • Target Namespace: prc-roper/context-provider
    • [Child Blocks]
      • After: Form Input Select (automatic)
        • HTML Anchor: qs_filter_start_date
      • Before: Form Input Select (automatic)
        • HTML Anchor: qs_filter_end_date
  • Buttons:
    • [Child Blocks]
    • Text: Filter
      • HTML Anchor: filter-roper-results-button
      • HTML Element: <button>
      • Target Namespace: prc-roper/context-provider
    • Text: Clear Filter
      • Styles: Outline
      • HTML Anchor: clear-roper-filters
      • HTML Element: <button>
      • Target Namespace: prc-roper/context-provider
Template
<!-- wp:prc-block/card {"className":"roper-filter-section","style":{"spacing":{"margin":{"left":"0"},"padding":{"left":"var:preset|spacing|30","right":"0","top":"var:preset|spacing|30"},"blockGap":"var:preset|spacing|40"}},"alignToGutter":true} -->
<div class="wp-block-prc-block-card roper-filter-section">
	<h2 class="prc-card__heading">REfine Your Selection</h2>
	<div
		class="prc-card__content"
		style="padding-left:var(--wp--preset--spacing--30);padding-right:0;padding-top:var(--wp--preset--spacing--30);--card-gap:var(--wp--preset--spacing--40)"
	>
		<!-- wp:prc-block/form-input-text {"style":{"spacing":{"padding":{"bottom":"var:preset|spacing|30"}},"border":{"bottom":{"color":"var:preset|color|ui-gray-light","width":"1px"},"top":[],"right":[],"left":[]}},"metadata":{"name":"qs_filter_exclude"},"blockVisibility":{"hideBlock":false},"interactiveNamespace":"prc-roper/context-provider"} -->
		<div
			class="wp-block-prc-block-form-input-text"
			style="padding-bottom:var(--wp--preset--spacing--30)"
		>
			<label><strong>EXCLUDE KEYWORDS</strong></label
			><input
				placeholder="Keyword(s)..."
				name="qs_filter_exclude"
				type="text"
				class=""
				style="border-bottom-color:var(--wp--preset--color--ui-gray-light);border-bottom-width:1px"
			/>
		</div>
		<!-- /wp:prc-block/form-input-text -->

		<!-- wp:prc-block/form-input-select-range {"type":"years","rangeStart":1987,"rangeEnd":2026,"interactiveNamespace":"prc-roper/context-provider"} -->
		<div class="wp-block-prc-block-form-input-select-range">
			<!-- wp:prc-block/form-input-select {"lock":{"move":true,"remove":true},"anchor":"qs_filter_start_date","style":{"spacing":{"padding":{"bottom":"var:preset|spacing|30"}},"border":{"bottom":{"color":"var:preset|color|ui-gray-light","width":"1px"},"top":[],"right":[],"left":[]}},"metadata":{"name":"aFTER"},"interactiveNamespace":"prc-block/form-input-select-range"} -->
			<div
				class="wp-block-prc-block-form-input-select"
				style="padding-bottom:var(--wp--preset--spacing--30)"
				id="qs_filter_start_date"
			>
				<label><strong>AFTER</strong></label>
				<div
					class="wp-block-prc-block-form-input-select__input"
					style="border-bottom-color:var(--wp--preset--color--ui-gray-light);border-bottom-width:1px"
				>
					<input
						placeholder="Select Year..."
						name="aFTER"
						type="text"
						role="combobox"
						required
					/>
					<div
						class="prc-block-form-input-select__list__placeholder"
					></div>
				</div>
			</div>
			<!-- /wp:prc-block/form-input-select -->

			<!-- wp:prc-block/form-input-select {"lock":{"move":true,"remove":true},"anchor":"qs_filter_end_date","style":{"spacing":{"padding":{"bottom":"var:preset|spacing|30"}},"border":{"bottom":{"color":"var:preset|color|ui-gray-light","width":"1px"},"top":[],"right":[],"left":[]}},"metadata":{"name":"bEFORE"},"interactiveNamespace":"prc-block/form-input-select-range"} -->
			<div
				class="wp-block-prc-block-form-input-select"
				style="padding-bottom:var(--wp--preset--spacing--30)"
				id="qs_filter_end_date"
			>
				<label><strong>BEFORE</strong></label>
				<div
					class="wp-block-prc-block-form-input-select__input"
					style="border-bottom-color:var(--wp--preset--color--ui-gray-light);border-bottom-width:1px"
				>
					<input
						placeholder="Select Year..."
						name="bEFORE"
						type="text"
						role="combobox"
						required
					/>
					<div
						class="prc-block-form-input-select__list__placeholder"
					></div>
				</div>
			</div>
			<!-- /wp:prc-block/form-input-select -->

			<!-- wp:paragraph {"className":"error-state-message"} -->
			<p class="error-state-message">Please select a valid range.</p>
			<!-- /wp:paragraph -->
		</div>
		<!-- /wp:prc-block/form-input-select-range -->

		<!-- wp:buttons -->
		<div class="wp-block-buttons">
			<!-- wp:button {"tagName":"button","interactiveNamespace":"prc-roper/context-provider","anchor":"filter-roper-results-button"} -->
			<div id="filter-roper-results-button" class="wp-block-button">
				<button
					type="button"
					class="wp-block-button__link wp-element-button"
				>
					Filter
				</button>
			</div>
			<!-- /wp:button -->

			<!-- wp:button {"tagName":"button","interactiveNamespace":"prc-roper/context-provider","className":"is-style-outline","anchor":"clear-roper-filters"} -->
			<div
				id="clear-roper-filters"
				class="wp-block-button is-style-outline"
			>
				<button
					type="button"
					class="wp-block-button__link wp-element-button"
				>
					Clear Filters
				</button>
			</div>
			<!-- /wp:button -->
		</div>
		<!-- /wp:buttons -->
	</div>
</div>
<!-- /wp:prc-block/card -->

Results info and tokens

Recipe
  • Detach the Facets Results Info and Selected Tokens.
  • [Child Blocks] – Tokens List – Target Namespace: prc-roper/context-provider – Facets Results Info – Target Namespace: prc-roper/context-provider
Template
<!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|20"}},"fontSize":"small-label","layout":{"type":"default"}} -->
<div class="wp-block-group has-small-label-font-size">
	<!-- wp:prc-ep/facets-results-info {"interactiveNamespace":"prc-roper/context-provider"} /-->

	<!-- wp:prc-block/tokens-list {"interactiveNamespace":"prc-roper/context-provider"} -->
	<div class="wp-block-prc-block-tokens-list">
		<label>Filtered by:</label
		><!-- wp:button {"tagName":"button","backgroundColor":"ui-gray-very-light","textColor":"ui-black","interactiveNamespace":"prc-block/tokens-list","interactiveSubsumption":true,"hasIcon":true,"iconLibrary":"light","iconName":"circle-x","style":{"elements":{"link":{"color":{"text":"var:preset|color|ui-black"}}},"typography":{"fontStyle":"normal","lineHeight":"1","fontWeight":"500"},"border":{"radius":"5px","width":"1px","color":"#818181"},"layout":{"selfStretch":"fit","flexSize":null},"spacing":{"padding":{"left":"var:preset|spacing|30","right":"var:preset|spacing|30","top":"var:preset|spacing|20","bottom":"var:preset|spacing|20"}}},"fontFamily":"sans-serif"} -->
		<div class="wp-block-button">
			<button
				type="button"
				class="wp-block-button__link has-ui-black-color has-ui-gray-very-light-background-color has-text-color has-background has-link-color has-border-color has-sans-serif-font-family wp-element-button"
				style="border-color:#818181;border-width:1px;border-radius:5px;padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--30);font-style:normal;font-weight:500;line-height:1"
			>
				Token Label
			</button>
		</div>
		<!-- /wp:button -->
	</div>
	<!-- /wp:prc-block/tokens-list -->

	<!-- wp:group {"layout":{"type":"default"},"blockVisibility":{"controlSets":[{"id":1,"enable":true,"controls":{"screenSize":{"hideOnScreenSize":{"large":true,"medium":true}}}}]}} -->
	<div class="wp-block-group">
		<!-- wp:paragraph {"style":{"elements":{"link":{"color":{"text":"var:preset|color|ui-link-color"}}}}} -->
		<p class="has-link-color">
			<a href="#refine-your-results">Refine Your Results</a>
		</p>
		<!-- /wp:paragraph -->
	</div>
	<!-- /wp:group -->
</div>
<!-- /wp:group -->

Full search results page

Template
<!-- wp:group {"layout":{"type":"constrained","contentSize":"1200px"}} -->
<div class="wp-block-group">
	<!-- wp:prc-roper/context-provider -->
	<!-- wp:heading {"level":1,"metadata":{"name":"roper-search-header"},"className":"roper-search-header"} -->
	<h1 class="wp-block-heading roper-search-header">Search results for:</h1>
	<!-- /wp:heading -->

	<!-- wp:group {"templateLock":"all","metadata":{"name":"roper-search-bar"},"className":"roper-search-bar","layout":{"type":"flex","flexWrap":"nowrap"}} -->
	<div class="wp-block-group roper-search-bar">
		<!-- wp:prc-block/form-input-text {"displayLabel":false,"className":"roper-search-bar-keyword","metadata":{"name":"qs_keyword"},"interactiveNamespace":"prc-roper/context-provider"} -->
		<div
			class="wp-block-prc-block-form-input-text roper-search-bar-keyword"
		>
			<input
				placeholder="Keyword(s)"
				name="qs_keyword"
				type="text"
				class=""
			/>
		</div>
		<!-- /wp:prc-block/form-input-text -->

		<!-- wp:button {"tagName":"button","className":"roper-search-bar-submit"} -->
		<div class="wp-block-button roper-search-bar-submit">
			<button
				type="button"
				class="wp-block-button__link wp-element-button"
			>
				Search
			</button>
		</div>
		<!-- /wp:button -->
	</div>
	<!-- /wp:group -->

	<!-- wp:prc-block/grid-controller {"verticalAlignment":"stretch","style":{"spacing":{"blockGap":{"left":"3rem"}},"border":{"top":{"color":"var:preset|color|ui-gray-light","width":"1px"},"right":[],"bottom":[],"left":[]}}} -->
	<!-- wp:prc-block/grid-column {"gridLayout":{"index":1,"desktopSpan":9,"tabletSpan":8,"mobileSpan":4,"tabletPosition":null,"mobilePosition":null,"desktopDivider":false,"tabletDivider":false,"mobileDivider":false},"verticalAlignment":"stretch","style":{"spacing":{"margin":{"top":"var:preset|spacing|30"}}}} -->
	<!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|20"}},"fontSize":"small-label","layout":{"type":"default"}} -->
	<div class="wp-block-group has-small-label-font-size">
		<!-- wp:prc-ep/facets-results-info {"interactiveNamespace":"prc-roper/context-provider"} /-->

		<!-- wp:prc-block/tokens-list {"interactiveNamespace":"prc-roper/context-provider"} -->
		<div class="wp-block-prc-block-tokens-list">
			<label>Filtered by:</label
			><!-- wp:button {"tagName":"button","backgroundColor":"ui-gray-very-light","textColor":"ui-black","interactiveNamespace":"prc-block/tokens-list","interactiveSubsumption":true,"hasIcon":true,"iconLibrary":"light","iconName":"circle-x","style":{"elements":{"link":{"color":{"text":"var:preset|color|ui-black"}}},"typography":{"fontStyle":"normal","lineHeight":"1","fontWeight":"500"},"border":{"radius":"5px","width":"1px","color":"#818181"},"layout":{"selfStretch":"fit","flexSize":null},"spacing":{"padding":{"left":"var:preset|spacing|30","right":"var:preset|spacing|30","top":"var:preset|spacing|20","bottom":"var:preset|spacing|20"}}},"fontFamily":"sans-serif"} -->
			<div class="wp-block-button">
				<button
					type="button"
					class="wp-block-button__link has-ui-black-color has-ui-gray-very-light-background-color has-text-color has-background has-link-color has-border-color has-sans-serif-font-family wp-element-button"
					style="border-color:#818181;border-width:1px;border-radius:5px;padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--30);font-style:normal;font-weight:500;line-height:1"
				>
					Token Label
				</button>
			</div>
			<!-- /wp:button -->
		</div>
		<!-- /wp:prc-block/tokens-list -->

		<!-- wp:group {"layout":{"type":"default"},"blockVisibility":{"controlSets":[{"id":1,"enable":true,"controls":{"screenSize":{"hideOnScreenSize":{"large":true,"medium":true}}}}]}} -->
		<div class="wp-block-group">
			<!-- wp:paragraph {"style":{"elements":{"link":{"color":{"text":"var:preset|color|ui-link-color"}}}}} -->
			<p class="has-link-color">
				<a href="#refine-your-results">Refine Your Results</a>
			</p>
			<!-- /wp:paragraph -->
		</div>
		<!-- /wp:group -->
	</div>
	<!-- /wp:group -->

	<!-- wp:prc-roper/results {"style":{"border":{"top":{"color":"var:preset|color|ui-gray-light","width":"1px"},"right":[],"bottom":[],"left":[]}}} -->
	<div
		class="wp-block-prc-roper-results"
		style="border-top-color:var(--wp--preset--color--ui-gray-light);border-top-width:1px"
	>
		<!-- wp:prc-roper/item {"roperQuestionId":"roper-results-preview","previewItem":true} -->
		<div class="wp-block-prc-roper-item"></div>
		<!-- /wp:prc-roper/item -->
	</div>
	<!-- /wp:prc-roper/results -->
	<!-- /wp:prc-block/grid-column -->

	<!-- wp:prc-block/grid-column {"gridLayout":{"index":2,"desktopSpan":3,"tabletSpan":4,"mobileSpan":4,"tabletPosition":null,"mobilePosition":null,"desktopDivider":true,"tabletDivider":true,"mobileDivider":true},"verticalAlignment":"stretch"} -->
	<!-- wp:prc-block/card {"className":"roper-filter-section","style":{"spacing":{"margin":{"left":"0"},"padding":{"left":"var:preset|spacing|30","right":"0","top":"var:preset|spacing|30"},"blockGap":"var:preset|spacing|40"}},"alignToGutter":true} -->
	<div class="wp-block-prc-block-card roper-filter-section">
		<h2 class="prc-card__heading">REfine Your Selection</h2>
		<div
			class="prc-card__content"
			style="padding-left:var(--wp--preset--spacing--30);padding-right:0;padding-top:var(--wp--preset--spacing--30);--card-gap:var(--wp--preset--spacing--40)"
		>
			<!-- wp:prc-block/form-input-text {"style":{"spacing":{"padding":{"bottom":"var:preset|spacing|30"}},"border":{"bottom":{"color":"var:preset|color|ui-gray-light","width":"1px"},"top":[],"right":[],"left":[]}},"metadata":{"name":"qs_filter_exclude"},"blockVisibility":{"hideBlock":false},"interactiveNamespace":"prc-roper/context-provider"} -->
			<div
				class="wp-block-prc-block-form-input-text"
				style="padding-bottom:var(--wp--preset--spacing--30)"
			>
				<label><strong>EXCLUDE KEYWORDS</strong></label
				><input
					placeholder="Keyword(s)..."
					name="qs_filter_exclude"
					type="text"
					class=""
					style="border-bottom-color:var(--wp--preset--color--ui-gray-light);border-bottom-width:1px"
				/>
			</div>
			<!-- /wp:prc-block/form-input-text -->

			<!-- wp:prc-block/form-input-select-range {"type":"years","rangeStart":1987,"rangeEnd":2026,"interactiveNamespace":"prc-roper/context-provider"} -->
			<div class="wp-block-prc-block-form-input-select-range">
				<!-- wp:prc-block/form-input-select {"lock":{"move":true,"remove":true},"anchor":"qs_filter_start_date","style":{"spacing":{"padding":{"bottom":"var:preset|spacing|30"}},"border":{"bottom":{"color":"var:preset|color|ui-gray-light","width":"1px"},"top":[],"right":[],"left":[]}},"metadata":{"name":"aFTER"},"interactiveNamespace":"prc-block/form-input-select-range"} -->
				<div
					class="wp-block-prc-block-form-input-select"
					style="padding-bottom:var(--wp--preset--spacing--30)"
					id="qs_filter_start_date"
				>
					<label><strong>AFTER</strong></label>
					<div
						class="wp-block-prc-block-form-input-select__input"
						style="border-bottom-color:var(--wp--preset--color--ui-gray-light);border-bottom-width:1px"
					>
						<input
							placeholder="Select Year..."
							name="aFTER"
							type="text"
							role="combobox"
							required
						/>
						<div
							class="prc-block-form-input-select__list__placeholder"
						></div>
					</div>
				</div>
				<!-- /wp:prc-block/form-input-select -->

				<!-- wp:prc-block/form-input-select {"lock":{"move":true,"remove":true},"anchor":"qs_filter_end_date","style":{"spacing":{"padding":{"bottom":"var:preset|spacing|30"}},"border":{"bottom":{"color":"var:preset|color|ui-gray-light","width":"1px"},"top":[],"right":[],"left":[]}},"metadata":{"name":"bEFORE"},"interactiveNamespace":"prc-block/form-input-select-range"} -->
				<div
					class="wp-block-prc-block-form-input-select"
					style="padding-bottom:var(--wp--preset--spacing--30)"
					id="qs_filter_end_date"
				>
					<label><strong>BEFORE</strong></label>
					<div
						class="wp-block-prc-block-form-input-select__input"
						style="border-bottom-color:var(--wp--preset--color--ui-gray-light);border-bottom-width:1px"
					>
						<input
							placeholder="Select Year..."
							name="bEFORE"
							type="text"
							role="combobox"
							required
						/>
						<div
							class="prc-block-form-input-select__list__placeholder"
						></div>
					</div>
				</div>
				<!-- /wp:prc-block/form-input-select -->

				<!-- wp:paragraph {"className":"error-state-message"} -->
				<p class="error-state-message">Please select a valid range.</p>
				<!-- /wp:paragraph -->
			</div>
			<!-- /wp:prc-block/form-input-select-range -->

			<!-- wp:buttons -->
			<div class="wp-block-buttons">
				<!-- wp:button {"tagName":"button","interactiveNamespace":"prc-roper/context-provider","anchor":"filter-roper-results-button"} -->
				<div id="filter-roper-results-button" class="wp-block-button">
					<button
						type="button"
						class="wp-block-button__link wp-element-button"
					>
						Filter
					</button>
				</div>
				<!-- /wp:button -->

				<!-- wp:button {"tagName":"button","interactiveNamespace":"prc-roper/context-provider","className":"is-style-outline","anchor":"clear-roper-filters"} -->
				<div
					id="clear-roper-filters"
					class="wp-block-button is-style-outline"
				>
					<button
						type="button"
						class="wp-block-button__link wp-element-button"
					>
						Clear Filters
					</button>
				</div>
				<!-- /wp:button -->
			</div>
			<!-- /wp:buttons -->
		</div>
	</div>
	<!-- /wp:prc-block/card -->
	<!-- /wp:prc-block/grid-column -->
	<!-- /wp:prc-block/grid-controller -->
	<!-- /wp:prc-roper/context-provider -->
</div>
<!-- /wp:group -->

Survey Questions in wp-admin

Users with manage_options can open Survey Questions. The All Survey Questions screen uses the shared Admin DataViews shell. The Expands column is the public Roper Item expand count. Completeness is stub or complete. Ingest owns creation, so the list has no Add New button.

The classic table is still available. Append ?classic=1 to edit.php?post_type=survey-question, or open the WordPress command palette (Ctrl/Cmd+K) and run Switch to classic survey-question table. Settings can disable DataViews per type.

The edit screen Roper data box shows the stored mapping (id, completeness, study, dates, archive id, source URL, dataset, responses) and the raw JSON. Those fields are read-only. Ingest writes the row. Custom Fields is off because the stored keys are protected (_roper_*). When ingest matches a Pew dataset, it also stores the Roper archive id on that dataset post as _roper_archive_id. The matching dataset’s Dataset Options sidebar lists associated survey questions and links to these edit screens.

Build

npx turbo build --filter=@prc/roper
npm run start -w @prc/roper

Requires @prc/chart-builder and form input blocks from @prc/block-library.

Was this helpful?