Add functionality to a CMS
Outcome
Section titled “Outcome”You will evaluate and add a table-of-contents plugin to a WordPress practice site, test its visitor behavior and dependency boundary, and prove that the configured site can be restored.
Why this matters
Section titled “Why this matters”A CMS plugin adds or changes behavior beyond the CMS core and active theme. That capability also adds code, maintenance, security, privacy, compatibility, and removal responsibilities. The correct extension is the smallest maintained option that solves a defined visitor or editor need and has a tested recovery path.
What you will practice
- Define a visitor need before selecting a CMS extension.
- Compare core, theme, manual, plugin, and custom-code routes by fit and risk.
- Evaluate current plugin identity, maintenance, compatibility, data, requests, and removal behavior.
- Install and configure one plugin in a restored practice copy without changing the baseline.
- Test generated in-page navigation with headings, URL fragments, keyboard use, narrow viewports, zoom, and browser tools.
- Deactivate the plugin in a separate copy and document the site's dependency on it.
- Export and restore a complete final checkpoint with the required plugin active.
What is new and what is reused
Section titled “What is new and what is reused”- New: Capability definition, plugin evaluation, WordPress Plugin Directory metadata, plugin installation and activation, generated blocks, dependency testing, deactivation behavior, frontend request inspection, privacy questions, and extension lifecycle evidence.
- Reused: WordPress Playground, complete-site ZIPs, block editing, headings, anchor links, semantic lists, global theme styles, visitor testing, browser developer tools, documentation,
.gitignore, and the solo Git workflow for text evidence.
Starting point
Before you start
- The unchanged theme-customized-final.zip from the CMS theme lesson, or a teacher-provided equivalent ZIP.
- A current version of Edge, Chrome, or Firefox with internet access.
- VS Code and permission to create a local cms-functionality-practice folder.
- Permission to install a teacher-approved plugin in a local practice site. Do not install it on a production site for this lesson.
- Current state
- You have a tested CMS theme result, but no separate functionality practice copy, plugin decision record, dependency test, or plugin-enabled final ZIP.
- First action
- Create cms-functionality-practice, copy theme-customized-final.zip into it without changing the original file, and rename the copy functionality-source.zip.
- First checkpoint
- cms-functionality-practice contains functionality-source.zip, and the unchanged theme-customized-final.zip still exists in its original folder.
- Help trigger
- Use the recovery note or ask for help if the source ZIP does not restore, plugin identity is ambiguous, installation requests an external account, the generated links do not reach their headings, deactivation makes content unreadable, or the final ZIP does not restore the active plugin and configured block.
Reference capability and plugin
Section titled “Reference capability and plugin”The reference need is:
A visitor reading a long process guide must be able to scan its section structure and move directly to one section.
This lesson uses SimpleTOC – Table of Contents Block from the official WordPress Plugin Directory. It adds a block that generates a nested list of links from page headings.
Plugin metadata can change after this lesson is published. Read the current directory page before installation. Confirm the exact plugin name, author, directory URL, current version, last update, required WordPress and PHP versions, tested WordPress version, installation count, reviews, support activity, and changelog.
The directory description is evidence from the plugin publisher and WordPress.org records. It is not proof that the plugin works with this site, theme, browser, content, or assistive technology. The required tests provide that project-specific evidence.
If your teacher selects another plugin, keep the same capability and evidence contract. The alternative must create in-page navigation from headings, work in the native block editor, require no external account for the core feature, and have a reversible deactivation path.
Required result
Section titled “Required result”You have completed the lesson when:
cms-functionality-practicecontainsfunctionality-source.zip,functionality-baseline.zip,functionality-configured.zip,functionality-final.zip,.gitignore, andcms-functionality-notes.md;- the source restores with the tested theme, routes, navigation, and media;
- the notes define the visitor need and compare manual, core or theme, plugin, and custom-code routes;
- the current official plugin metadata and identity are recorded before installation;
- the reference plugin is installed and active only in the practice site;
- a published
Process Guidepage contains an introduction, a table of contents, fourH2sections, and at least oneH3subsection; - every generated link reaches the matching heading and produces a useful URL fragment;
- the table of contents uses list-and-link semantics, works with a keyboard, and remains usable at about
320pxand200%zoom; - browser tools show the plugin’s actual frontend requests and generated markup, including any unexpected external request or asset;
- a separate copy remains readable after deactivation, and the notes identify exactly which capability disappears;
- the configured plugin and page return after restoring
functionality-final.zip; and - the notes are committed while all CMS ZIPs remain ignored and local.
Create the evidence files
Section titled “Create the evidence files”Use this local structure:
cms-functionality-practice/├── .gitignore├── functionality-source.zip└── cms-functionality-notes.mdAdd this rule to .gitignore:
*.zipAdd this starting record to cms-functionality-notes.md:
# CMS extended functionality
## Capability
- Visitor:- Need:- Observable success:- Out of scope:
## Alternatives
| Route | Fit | Added risk or work | Decision || --- | --- | --- | --- || Manual anchor list | | | || CMS core or active theme | | | || Plugin | | | || Custom plugin code | | | |
## Plugin evaluation
- Exact name:- Author:- Official directory URL:- Version and last update checked on:- Required and tested environments:- Active installations, reviews, and support evidence:- Data stored:- Personal data handled:- External services or requests:- Frontend assets:- Permissions or administration access:- Deactivation and uninstall expectation:- Update owner for a production site:
## Test evidence
| Condition | Expected result | Observed evidence | Pass or fix || --- | --- | --- | --- |
## Dependency test
- Result with plugin active:- Result after deactivation:- Content that remains:- Capability that disappears:- Recovery action:
## Restore verification
- Final ZIP:- Plugin status after restore:- Page and links compared:- First mismatch, or none:
## Known limits
- Playground is a local practice environment, not a public production deployment.Do not copy a plugin description into every field. Use the directory, administration screens, browser tools, and your own test results to distinguish claims from observed evidence.
Restore and verify the source
Section titled “Restore and verify the source”Open a new WordPress Playground. Use New → Import zip in the Dock and select functionality-source.zip.
Before you install anything:
- Open the site root and every required visitor route.
- Test the primary navigation with the keyboard.
- Confirm the active block theme and saved global Styles.
- Confirm that required images and page headings remain present.
- Open Plugins → Installed Plugins and record the existing plugin list.
- Open the browser Network panel, reload one content page, and record the baseline request domains and relevant frontend assets.
Export the verified state as functionality-baseline.zip. Restore that ZIP in another new Playground and compare the site root, one child route, active theme, plugin list, navigation, and one image.
Checkpoint: The plugin test has a restorable baseline
- What now works
- functionality-source.zip remains unchanged, functionality-baseline.zip restores the verified site and plugin inventory, and the notes record the baseline routes and requests.
- Files changed
cms-functionality-practice/functionality-source.zip, cms-functionality-practice/functionality-baseline.zip, cms-functionality-practice/cms-functionality-notes.md- What remains
- Evaluate the extension against alternatives, then install it in the working practice site.
- Next action
- Open the official SimpleTOC directory page and complete every known evaluation field before selecting Install.
- If it does not work
- Compare the first failed baseline route with functionality-source.zip. Repair or replace the source before adding a plugin.
Compare the implementation routes
Section titled “Compare the implementation routes”Do not begin with the plugin name. Begin with the visitor need.
Manual anchor list
Section titled “Manual anchor list”A page author can add HTML anchors to headings and maintain a normal list of links. This route adds no plugin dependency, but each heading and list entry must stay synchronized through manual editing and review.
CMS core or theme
Section titled “CMS core or theme”Inspect the current block inserter and theme features for a table-of-contents block or equivalent navigation. Use a core or already-approved theme capability when it meets the complete need. Do not add a duplicate plugin.
Existing plugin
Section titled “Existing plugin”A focused plugin can generate the list from headings and update it as content changes. It adds a third-party code and maintenance dependency.
Custom plugin code
Section titled “Custom plugin code”Custom code gives more control but creates ownership for secure implementation, validation, escaping, accessibility, compatibility, tests, updates, and removal. It is outside this lesson because the current goal is extension selection and integration, not PHP plugin development.
Complete the alternatives table. Select the reference plugin only if the site does not already provide an equivalent approved feature.
Evaluate the current plugin record
Section titled “Evaluate the current plugin record”Open the official directory page and record the current values. Use these questions:
Identity and maintenance
Section titled “Identity and maintenance”- Does the administration search result match the exact name, author, and official directory page?
- When was the plugin last updated?
- Which WordPress and PHP versions does it require?
- Which WordPress version does the publisher report as tested?
- Does the changelog show current maintenance rather than only a recent version number?
- Do support topics reveal a conflict relevant to this site or editor?
Scope and dependency
Section titled “Scope and dependency”- Does the plugin add only the required block, or several unrelated features?
- Which content stores the plugin block?
- What visitor output remains after deactivation?
- Does uninstall remove settings, content markers, or data?
- Can a manual anchor list replace the capability if maintenance stops?
Privacy, requests, and permissions
Section titled “Privacy, requests, and permissions”- Does the plugin collect or store personal data?
- Does it contact an external service, load a remote asset, add telemetry, use cookies, or add browser storage?
- Does the core feature require an account, license key, consent, or data transfer?
- Which WordPress capability is required to install, configure, and use the block?
Mark an unanswered question as unknown. Do not convert missing documentation into a claim that no risk exists.
Install the plugin in the practice site
Section titled “Install the plugin in the practice site”In the working restored Playground:
- Open Plugins → Add New Plugin.
- Search for the exact plugin name
SimpleTOC – Table of Contents Block. - Compare the author and details with the official directory record.
- Select Install Now only on the matching result.
- When installation completes, select Activate.
- Open Plugins → Installed Plugins and confirm that the plugin status is active.
If administration search or networking is unavailable, download the plugin ZIP from the official WordPress.org directory and use the administration upload route approved by your teacher. Do not use a third-party download mirror.
Stop if installation requests an external account, unrelated plugin, or broader feature bundle that was not part of the recorded evaluation.
Inspect the activation boundary
Section titled “Inspect the activation boundary”Before you create content:
- reload the existing visitor routes;
- confirm that page content, theme presentation, and navigation still work;
- compare the Network panel with the baseline; and
- record any new request, script, stylesheet, cookie, storage entry, or external domain.
An absent difference in one route is limited evidence. The plugin’s block has not been placed yet.
Build the Process Guide page
Section titled “Build the Process Guide page”Create a page named Process Guide. Use the page title as the only H1.
Add these blocks in order:
- A short introduction:
Use this guide to move from a defined requirement to verified project evidence. - The SimpleTOC table-of-contents block.
- An
H2namedPlan the required resultand one explanatory paragraph. - An
H2namedBuild the smallest complete pathand one explanatory paragraph. - An
H3namedRecord a working checkpointand one explanatory paragraph. - An
H2namedTest observable behaviorand one explanatory paragraph. - An
H2namedDocument evidence and limitsand one explanatory paragraph.
Configure the table of contents to include headings through level H3. Use an ordered or unordered list. Keep the generated heading label visible unless you add an equivalent visible heading immediately before the block.
Publish the page. Open the visitor result in a new tab.
Test generated navigation
Section titled “Test generated navigation”For each generated link:
- Read its text and identify the matching heading.
- Activate it with the keyboard.
- Confirm that the browser moves to the correct heading.
- Confirm that the address contains a fragment after
#. - Reload that fragment URL and confirm that the same heading remains the target.
- Confirm that focus and reading order remain understandable after the move.
Use the Elements or Inspector panel to confirm that the table of contents contains a semantic list of links. Record the observed wrapper, list, links, heading IDs, and URL fragments. Do not record the plugin directory’s accessibility statement as your test result.
Test content updates
Section titled “Test content updates”Add one more H2 named Share the result, followed by a paragraph. Update and reload the visitor page. Confirm that one new table-of-contents link appears and reaches the new heading without manually editing the list.
Remove the added section again. Confirm that its generated link also disappears.
Checkpoint: The extension solves the defined visitor need
- What now works
- Process Guide renders a generated list from H2 and H3 headings, every keyboard-operated link reaches its matching fragment target, and heading additions and removals update the list.
- What remains
- Inspect the frontend cost, test deactivation in a separate copy, then export and restore the active final state.
- Next action
- Run the complete visitor and Network test matrix, then export the active configured site as functionality-configured.zip.
- If it does not work
- Check the heading levels, block depth setting, saved page state, and first incorrect fragment before reinstalling or replacing the plugin.
Test accessibility, layout, and frontend cost
Section titled “Test accessibility, layout, and frontend cost”Add these conditions to the notes:
| Condition | Expected result |
|---|---|
| Process Guide at a wide viewport | Table of contents shows the correct nested section structure |
Process Guide at about 320px |
Link text wraps without horizontal overflow or clipped targets |
Process Guide at 200% zoom |
Content reflows and every generated link remains operable |
| Keyboard from page start | Every table-of-contents link receives visible focus in a logical order |
| Fragment URL loaded directly | The matching heading is present and not hidden by the shared header |
| Screen-reader or accessibility-tree inspection | The result exposes useful navigation, list, link, and heading semantics |
| Network panel with cache disabled | Requests and transferred assets are recorded and compared with baseline |
| Console after interaction | No new JavaScript error appears |
The plugin directory can describe default asset behavior. Record what this configured page actually requests. If the page contacts an unexpected third-party domain or loads an unexplained asset, stop and investigate before approval.
Test the dependency through deactivation
Section titled “Test the dependency through deactivation”Export the active configured working site as functionality-configured.zip.
Restore functionality-configured.zip in a separate Playground. In that separate copy:
- Open Process Guide and record the active result.
- Open Plugins → Installed Plugins and deactivate the reference plugin. Do not delete it.
- Reload Process Guide in the visitor view.
- Record which page content remains, which table-of-contents capability disappears or changes, and whether an unsupported-block message appears in the editor.
- Confirm that other routes, theme presentation, navigation, headings, and paragraphs remain readable.
- Reactivate the plugin and confirm that the configured table of contents returns after a page reload.
Do not perform this test in the only configured working copy. Deactivation is reversible, but it changes the site state and can affect saved editor behavior.
Document the exact dependency. A statement such as “the plugin is required” is incomplete. Name the block, visitor output, saved content, fallback behavior, and recovery action.
Export and restore the final active site
Section titled “Export and restore the final active site”Return to the working site where the plugin remains active and every test passes.
- Confirm the plugin is active and Process Guide is published.
- Export the complete Playground as a ZIP.
- Store it as
functionality-final.zip. - Open a new Playground and restore
functionality-final.zip. - Confirm the active plugin identity and status.
- Open Process Guide and test the generated links, fragments, hierarchy, narrow layout, and keyboard path.
- Check another route to confirm that the theme and navigation remain correct.
- Record the first mismatch, or
none, in the notes.
Commit only .gitignore and cms-functionality-notes.md in the private practice repository. Use git status --ignored to confirm that all four ZIP files remain local and ignored.
Self-check
Complete these checks against the required result.
- Confirm that functionality-source.zip, functionality-baseline.zip, functionality-configured.zip, and functionality-final.zip are separate local files greater than 0 bytes.
- State the visitor need without naming the plugin, then explain why the selected route fits better than the recorded alternatives.
- Compare the installed plugin name and author with the current official directory record.
- Show the current maintenance, compatibility, support, data, request, permission, and removal evidence in the notes, including every unknown.
- Open Process Guide and confirm one H1 page title, four H2 sections, at least one H3 subsection, and the generated table of contents.
- Use the keyboard to activate every generated link and confirm the matching heading and URL fragment.
- Test the page at about 320px and 200% zoom and confirm readable wrapping, visible focus, and no horizontal overflow.
- Compare the Network and Console evidence with the baseline and explain every plugin-related difference you observed.
- Show the separate deactivation result and name the exact content that remains, capability that disappears, and recovery action.
- Restore functionality-final.zip and confirm that the active plugin and configured page return without a mismatch.
- Run git status and git status --ignored and confirm that the notes are committed while every ZIP remains ignored and local.
Common extension failures
Section titled “Common extension failures”| Symptom | Likely cause | Focused check |
|---|---|---|
| The plugin cannot be found | Search, networking, or plugin identity is wrong | Compare the official name, author, slug, and directory URL |
| The block is absent after activation | The page uses another editor or activation did not complete | Confirm the native block editor and Installed Plugins status |
| The table is empty | The page has no included heading levels or changes are unsaved | Inspect H2 and H3 blocks, depth settings, and publication state |
| A generated link reaches the wrong place | Heading anchors are repeated or stale | Inspect heading IDs and the exact fragment in the rendered link |
| A heading is hidden after a link | The shared header overlays the fragment target | Test direct fragment loading and inspect header positioning |
| Deactivation makes the editor warn about a block | Saved content depends on a plugin-provided block | Record the dependency and reactivate in the test copy before editing |
| The final restore lacks the plugin | The wrong ZIP was exported or export occurred before activation | Compare filenames, plugin status, and export order |
| Requests reach an unexplained domain | The plugin, another extension, or page content adds an external resource | Match the request initiator and stop until the data flow is understood |
Optional references
Section titled “Optional references”- SimpleTOC in the WordPress Plugin Directory provides the current publisher description, metadata, installation notes, changelog, reviews, and support links.
- WordPress Plugin Handbook privacy guidance lists questions about personal data, third parties, telemetry, browser storage, and removal.
- WordPress Plugin Directory guidelines describe directory requirements for licensing, external services, tracking, and disclosure.
- WordPress Playground web instance guide explains plugin-capable practice sites, Dock tools, ZIP export, and restoration.
Next step or safe stopping point
Section titled “Next step or safe stopping point”The required lesson is complete when the extension solves the defined need, the visitor and request evidence passes, the separate deactivation test documents the dependency, and functionality-final.zip restores the active configured result.
Continue to Practice: Extend a CMS site to select and integrate a CMS capability for an independent site brief with the same evaluation and recovery contract.
If you stop here, leave yourself this resume note beside the final ZIP: The table-of-contents capability is evaluated, tested, deactivation-aware, and restorable. Next, open the CMS extension assignment and define the visitor or editor need before selecting a solution.