PHPackages                             alleyinteractive/wp-widget-control - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. alleyinteractive/wp-widget-control

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

alleyinteractive/wp-widget-control
==================================

Setup and curate WordPress widgets with code.

v0.1.0(9mo ago)10[2 PRs](https://github.com/alleyinteractive/wp-widget-control/pulls)GPL-2.0-or-laterPHPPHP ^8.2CI passing

Since Aug 12Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/alleyinteractive/wp-widget-control)[ Packagist](https://packagist.org/packages/alleyinteractive/wp-widget-control)[ Docs](https://github.com/alleyinteractive/wp-widget-control)[ RSS](/packages/alleyinteractive-wp-widget-control/feed)WikiDiscussions develop Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (4)Used By (0)

WP Widget Control
=================

[](#wp-widget-control)

[![Testing Suite](https://github.com/alleyinteractive/wp-widget-control/actions/workflows/all-pr-tests.yml/badge.svg)](https://github.com/alleyinteractive/wp-widget-control/actions/workflows/all-pr-tests.yml)

Setup and curate WordPress widgets with code.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require alleyinteractive/wp-widget-control
```

Usage
-----

[](#usage)

WP Widget Control lets you programmatically manage WordPress sidebars and widgets. This can be useful for setting up default widget configurations, managing widget curation with code for end to end testing, or simply maintaining widget state in a more structured way.

When you have to manage widgets with code, WordPress doesn't provide a great way to do that. WP Widget Control fills this gap by providing a simple API for managing widgets programmatically.

Here are some common usage patterns:

### Retrieve a Sidebar

[](#retrieve-a-sidebar)

```
use Alley\WP\Widget_Control\Sidebar;

$sidebar = Sidebar::from( 'sidebar-1' );
```

### Append a Widget to a Sidebar

[](#append-a-widget-to-a-sidebar)

```
use Alley\WP\Widget_Control\Sidebar;
use Alley\WP\Widget_Control\Widget;

$sidebar = Sidebar::from( 'sidebar-1' );

// Append a widget by its ID:
$sidebar->append( 'example_widget-4' );

// You can create a new widget instance from the base ID and append it to the sidebar:
$sidebar->append(
  Widget::from( 'example_widget' )->append( [ 'content' => 'Hello, World!' ] ),
);

// Or by referencing the widget's class:
$sidebar->append(
  Widget::from( \My\Custom\ExampleWidget::class )->append( [ 'content' => 'Hello, World!' ] ),
);

// Save the sidebar to persist changes.
$sidebar->save();
```

### Insert Widgets Before or After Another Widget

[](#insert-widgets-before-or-after-another-widget)

```
use Alley\WP\Widget_Control\Sidebar;
use Alley\WP\Widget_Control\Widget;

$sidebar = Sidebar::from( 'sidebar-1' );

// Insert a widget "block-99" before "block-2":
$sidebar->insert_before( widget: 'block-99', before_widget_id: 'block-2' );

// Insert a widget "example_widget-6" after "example_widget-2":
$sidebar->insert_after( widget: 'example_widget-6', after_widget_id: 'example_widget-2' );

// Also supports inserting a widget instance directly.
// Inside a new widget instance before "example_widget-2":
$sidebar->insert_before(
	widget: Widget::from( 'example_widget' )->append( [ 'content' => 'Hello, World!' ] ),
	before_widget_id: 'example_widget-2',
);

// Save the sidebar to persist changes.
$sidebar->save();
```

### Remove a Widget by ID or Index

[](#remove-a-widget-by-id-or-index)

```
use Alley\WP\Widget_Control\Sidebar;
use Alley\WP\Widget_Control\Widget_Instance;

$sidebar = Sidebar::from( 'sidebar-1' );

// Remove a widget by its ID:
$sidebar->remove( 'block-2' );

// Remove a widget by its index:
$sidebar->remove_index( 2 );

// Save the sidebar to persist changes.
$sidebar->save();
```

### Set All Widgets in a Sidebar

[](#set-all-widgets-in-a-sidebar)

```
use Alley\WP\Widget_Control\Sidebar;
use Alley\WP\Widget_Control\Widget;

$sidebar = Sidebar::from( 'sidebar-1' );

$sidebar->set( [
	// Use existing widget instances (they follow a widget_base-ID pattern).
	'nav_menu-1',
	'block-2',
	'example_widget-2',

	// You can also create a new widget instance and append it to the sidebar.
	Widget::from( 'example_widget' )->append( [ 'content' => 'Hello, World!' ] ),
	Widget::from( \My\Custom\ExampleWidget::class )->append( [ 'content' => 'Hello, World!' ] ),
] );

// Save the sidebar to persist changes.
$sidebar->save();
```

### Filter Widgets in a Sidebar

[](#filter-widgets-in-a-sidebar)

Remove a specific widget from a sidebar while keeping others:

```
use Alley\WP\Widget_Control\Sidebar;
use Alley\WP\Widget_Control\Widget;
use Alley\WP\Widget_Control\Widget_Instance;

$sidebar = Sidebar::from( 'sidebar-1' );

// Remove all widgets whose ID contains 'example_widget'.
$sidebar->filter_by_id( function( string $widget_id ) {
	return ! str_contains( $widget_id, 'example_widget' );
} );

// Keep only widgets of a certain type (using Widget_Instance).
$sidebar->filter( function( Widget_Instance $widget ) {
	return $widget->id_base === 'example_widget';
} );

// Save the sidebar to persist changes.
$sidebar->save();
```

### Clear All Widgets from a Sidebar

[](#clear-all-widgets-from-a-sidebar)

```
use Alley\WP\Widget_Control\Sidebar;

$sidebar = Sidebar::from( 'sidebar-1' );

$sidebar->clear();

// Save the sidebar to persist changes.
$sidebar->save();
```

### Full Sidebar Curation Example

[](#full-sidebar-curation-example)

In this example, we will set the sidebar to contain an instance of `ExampleWidget` and another instance of the `block` widget:

```
use Alley\WP\Widget_Control\Sidebar;
use Alley\WP\Widget_Control\Widget;
use Alley\WP\Widget_Control\Tests\ExampleWidget;

$sidebar->set( [
	Widget::from( ExampleWidget::class )->append( [ 'content' => 'Hello, World! 1' ] ),
	Widget::from( 'block' )->append( [ 'content' => 'Hello, World! 2' ] ),
] );

// Save the sidebar to persist changes.
$sidebar->save();
```

These will be the only two widgets in the sidebar.

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Credits
-------

[](#credits)

This project is actively maintained by [Alley Interactive](https://github.com/alleyinteractive). Like what you see? [Come work with us](https://alley.co/careers/).

- [Sean Fisher](https://github.com/srtfisher)
- [All Contributors](../../contributors)

License
-------

[](#license)

The GNU General Public License (GPL) license. Please see [License File](LICENSE) for more information.

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance64

Regular maintenance activity

Popularity2

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

279d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/338d27065b1074f2d66d049d742f22996dd137eef6f91bc8f75350ceee1e8ef2?d=identicon)[srtfisher](/maintainers/srtfisher)

---

Top Contributors

[![srtfisher](https://avatars.githubusercontent.com/u/346399?v=4)](https://github.com/srtfisher "srtfisher (3 commits)")

---

Tags

wordpresswordpress-packagealleyinteractivewp-widget-control

### Embed Badge

![Health badge](/badges/alleyinteractive-wp-widget-control/health.svg)

```
[![Health](https://phpackages.com/badges/alleyinteractive-wp-widget-control/health.svg)](https://phpackages.com/packages/alleyinteractive-wp-widget-control)
```

###  Alternatives

[alleyinteractive/wp-block-converter

Convert HTML into Gutenberg Blocks with PHP

62321.0k1](/packages/alleyinteractive-wp-block-converter)[alleyinteractive/wp-curate

Plugin to curate homepages and other landing pages

10154.3k](/packages/alleyinteractive-wp-curate)[alleyinteractive/feed-consumer

Ingest external feeds and other data sources into WordPress

114.8k](/packages/alleyinteractive-feed-consumer)[alleyinteractive/wp-bulk-task

A library to assist with running performant bulk tasks against WordPress objects.

21326.8k4](/packages/alleyinteractive-wp-bulk-task)[alleyinteractive/wp-alleyvate

Defaults for WordPress sites by Alley.

3434.2k](/packages/alleyinteractive-wp-alleyvate)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
