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
| Block | Role |
|---|---|
| Roper Context Provider | Queries the Roper API and passes results to children |
| Roper Results | Paginated list of questions inside a provider |
| Roper Item | One 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 5–20). Passed to children as prc-roper/per-page context.
Filter recipe
Assemble filters from existing blocks (not built-in Roper block types):
| Control | Block | Key settings |
|---|---|---|
| Exclude keywords | Form Input Text | name qs_filter_exclude, namespace prc-roper/context-provider |
| After / Before years | Select Range Field (years) | min 1987, current year on; child selects anchors qs_filter_start_date / qs_filter_end_date |
| Filter / Clear | Buttons 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.
| Layout | Content |
|---|---|
| Default (Question + Chart) | Metadata + title above bar chart; optional Collapsible Question |
| Question | Metadata and title only |
| Chart | Bar 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
- Input Name:
- 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
- HTML Anchor:
- Before:
Form Input Select(automatic)- HTML Anchor:
qs_filter_end_date
- HTML Anchor:
- After:
- Select Range Type:
- Buttons:
- [Child Blocks]
- Text:
Filter- HTML Anchor:
filter-roper-results-button - HTML Element:
<button> - Target Namespace:
prc-roper/context-provider
- HTML Anchor:
- Text:
Clear Filter- Styles:
Outline - HTML Anchor:
clear-roper-filters - HTML Element:
<button> - Target Namespace:
prc-roper/context-provider
- Styles:
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.