drupal / pixienote
A private personal information hub for contacts, bookmarks, notes, schedules, and service links.
Package info
git.drupalcode.org/project/pixienote.git
Type:drupal-recipe
pkg:composer/drupal/pixienote
Requires
- drupal/accessible_menu: ^1
- drupal/aggregator: ^2
- drupal/bootstrap_cloud: ^7
- drupal/calendar_view: ^2
- drupal/copyright_footer: ^3
- drupal/core: ^11
- drupal/menu_link_config: ^1.0@alpha
- drupal/node_view_permissions: ^2
- drupal/printable: ^3
- drupal/recipe_config_translation: ^1
- twig/twig: >=3.29 <3.30
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-13 00:08:11 UTC
README
PixieNote is a Drupal Recipe for a private personal information hub. It adds contacts, bookmarks, notes, schedules, service links, RSS news, a note-photo grid, tags, list views, search, browser printing, and the Bootstrap Cloud Pixie Dark presentation.
Start with the Documentation for service walkthroughs, installation, and operations in English and Japanese. The same guides are available in this repository.
See release notes for the changes and limitations of
1.0.0-alpha2.
The Recipe contains configuration, a manifest of public RSS feed definitions,
and the footer layout settings. The guarded installer creates those feed
entities with site-generated IDs and initializes image effects after the
Recipe is applied. It does not include imported feed items, sample
content, user accounts, email addresses, credentials, private keys, uploaded
files, or identifiers copied from the production site.
The Recipe navigation omits Bootstrap Cloud's default logo. Add your own
branding after installation if desired. The front page is the i News Top view
at /top; the included public feeds appear after their first refresh.
English, Japanese, Simplified Chinese, and Thai are available as interface
languages with URL prefixes (/en, /ja, /zh-hans, /th). The Recipe
ships translations for selected configuration labels, including the Tags
navigation item, but does not ship translated personal content or guarantee
complete contributed-module interface translations.
The selected configuration-label translations use the contributed
recipe_config_translation module. This project is not covered by Drupal's
Security Advisory Policy; review its upstream releases and security status
before using it in a production site.
The host site's Composer lock controls the resolved module version; keep that
lockfile under version control for repeatable deployments. Reapply the Recipe
after installing a previously missing language or updating this module to
refresh the shipped label translations.
Requirements
- Drupal 11 (individual dependencies may require a later minor release)
- PHP supported by the installed Drupal release
- Composer
- Drush 13 for the required node-access rebuild
- A fresh site installed with the Minimal profile
- A private-file directory configured outside the public web root before uploading contact or note images
Dependency updates
The Recipe allows compatible releases within each dependency's major series.
Routine minor and patch releases do not require a Recipe change or a separate
PixieNote merge request. The installing site's composer.lock records the
resolved versions for repeatable deployments; review and test dependency
updates together in that site's normal update workflow before deployment.
The validation record identifies the versions actually tested, rather than
claiming that every older version allowed by a constraint has been tested.
Only raise a minimum version or add an upper bound for a demonstrated API, security, or compatibility requirement. The temporary Twig restriction below is one such documented compatibility exception. Menu Link Config retains its explicit alpha stability allowance without lowering the site's overall minimum stability.
Install
1.0.0-alpha1 is the initial release and lacks the guarded installer.
For 1.0.0-alpha2 and later releases that include
scripts/install-safe.sh, select the reviewed release explicitly in Composer:
the default stable-only constraint cannot install an alpha release. Keep the
project's minimum-stability at stable. Menu Link Config currently has only
an alpha release, so require it directly in the root project as shown below.
Use the alpha2 command only after that release is available on Drupal.org.
Run these commands from the root of an installed Drupal project. Drupal's
recommended project template from 11.2 onward already places Recipe packages
in recipes/. If your Composer project does not have that installer path,
configure it before requiring PixieNote:
composer config allow-plugins.drupal/core-recipe-unpack true
composer require drupal/core-recipe-unpack composer/installers:^2.3
composer config --merge --json extra.installer-paths '{"recipes/{$name}":["type:drupal-recipe"]}'
The Recipe application below assumes recipes/pixienote/recipe.yml exists
after Composer finishes. If it does not, check the installer path instead of
applying a different copy of the Recipe.
For the reviewed 1.0.0-alpha2 release, install the Recipe, its alpha-only
dependency, and Drush from the Drupal Composer repository:
composer require 'drupal/pixienote:1.0.0-alpha2' 'drupal/menu_link_config:^1.0@alpha' 'drush/drush:^13' --with-all-dependencies
For development of an unreleased 1.x checkout, register its absolute path
as a Composer path repository instead:
composer config repositories.pixienote path /absolute/path/to/pixienote
composer require 'drupal/pixienote:1.x-dev' 'drupal/menu_link_config:^1.0@alpha' 'drush/drush:^13' --with-all-dependencies
The checkout must be on 1.x. Composer does not apply the alpha stability
allowance from a transitive dependency to the root project. The direct
requirement keeps the root minimum-stability at stable. Do not use this
development-branch command for a published release; select its reviewed
version and keep the direct Menu Link Config requirement while it remains
alpha. The separate 1.0.0-alpha1 command below predates this dependency.
Before applying the Recipe, create a private-file directory in the Composer
project root, outside web/, and make it writable by the PHP web-server
user. In web/sites/default/settings.php, set the following path (adjust it
if your project uses a different web root):
$settings['file_private_path'] = dirname($app_root) . '/private';
On the standard recommended-project layout, create that directory with
mkdir -p private from the Composer project root. Do not put private files
in web/sites/default/files or commit them to version control.
Before running the commands below, replace any placeholder site email address
in Drupal's Basic site settings with a deliverable address that you control.
The setup-contact script uses that address as the recipient of the public
Contact form; it does not ship or print an email address. It refuses to create
the form if the address is invalid. If a feedback form already exists, the
script validates but does not replace its recipient. Changing the site's
email later does not update the form; edit its recipient separately in
Drupal's Contact forms administration screen.
The 1.0.0-alpha1 release predates the guarded installer below. For
1.0.0-alpha2 or a newer release containing scripts/install-safe.sh, use
this command after installing the Recipe package and Drush with Composer. It
is for an empty Minimal site in a standard recommended-project layout only. It
enables maintenance mode before applying configuration, checks the private-file
path and existing content, creates or verifies the public feed sources and
image effects, sets up Contact, rebuilds and verifies node access, and reopens
the site only if every step succeeds. Before reopening, it checks that
essential rendering plugins are discoverable and internally renders the front
page. A failed rendering check triggers one additional cache rebuild; a second
failure leaves maintenance mode enabled. This check does not replace testing
the public site through its actual web server after installation. The first
empty-site preflight runs before maintenance mode is enabled. If it rejects
the site, the original mode is unchanged; keep it private and use the update
procedure instead. After the preflight, a failed step leaves maintenance mode
enabled; correct the reported problem and rerun the same command. It does not
import personal content or change the site email. The inventory checks every
installed content entity type, not just nodes and files. Only Drupal's initial
accounts and unchanged packaged public RSS samples are allowed, including when
retrying an incomplete installation. Their stored public fields and defaults
must match: title, URL, language, refresh interval and empty cached metadata.
Drupal-generated runtime identity is not an expected content value. The
13 default sources are listed by stable descriptive keys in
assets/aggregator/feed/sources.yml. This is the only packaged feed list;
prior lists are preserved in Git history, not shipped as runtime profiles.
The manifest contains no entity IDs. Additional feed sources, dynamic menu
links, and other content are rejected. Unsupported
non-SQL content storage is rejected rather than silently skipped; Drupal core's
non-persistent Contact message storage is not a stored-content inventory.
Private storage must not contain the public web root either; filesystem roots and ancestor directories are not suitable private-file locations. The installer follows directory symlinks reachable from the web root and rejects links into the private-file directory. It also rejects dangling links, which could expose private data when their targets are created later. Remove or repair these links before retrying. It cannot inspect custom web-server or reverse-proxy aliases; ensure those do not expose the private directory before making the site public. The installer checks whether the Drush PHP process can read and write the private directory; separately verify that the PHP web-server user can read and write it before accepting image uploads.
bash recipes/pixienote/scripts/install-safe.sh
Run vendor/bin/drush cron after the successful command if you want to fetch
the public RSS feeds immediately. Feed availability is not a prerequisite for
reopening the site. To update an existing, populated PixieNote site, follow
the separate update procedure below rather than running the fresh installer.
Fetched feed descriptions, links, images and cache state are also existing
content for this fresh-install guard, even if no items were imported. After
refreshing feeds or customizing them, use the populated-site update procedure;
do not clear that data merely to make the fresh-install guard accept the site.
The published 1.0.0-alpha1 release has no guarded installer. Its manual
sequence below is for an isolated test site only, not a publicly reachable
site. Keep that site closed until the node-access rebuild has finished and
the privacy checks in Verification have passed. Do not treat these manual
commands as a safe production installation procedure.
For that published release, the manual sequence remains:
composer require 'drupal/pixienote:1.0.0-alpha1' 'drush/drush:^13' --with-all-dependencies
cd web
../vendor/bin/drush recipe ../recipes/pixienote
../vendor/bin/drush php:script setup-contact --script-path=../recipes/pixienote/scripts
../vendor/bin/drush php:eval '\Drupal\node_view_permissions\NodeAccessRebuildHelper::rebuild();'
../vendor/bin/drush cr
../vendor/bin/drush cron
Do not create private records or open the site to other users before the
node-access rebuild finishes successfully. The Node View Permissions
module marks access grants for rebuilding during installation, but Drupal's
original public default grant may still be present until that rebuild. A
cache rebuild alone is not sufficient. Then create an authenticated user.
PixieNote intentionally ships no accounts or personal content. Ordinary
authenticated users can create contacts, bookmarks, notes, and schedules.
The commands above install the legacy 1.0.0-alpha1 package. The Tags
behavior below applies to the 1.x source and 1.0.0-alpha2, not alpha1.
The current source allows Bootstrap Cloud 7.x;
7.1.8 includes the theme's Accessible Menu integration fixes. The published
alpha1 package retains its original dependencies and navigation configuration.
The main navigation ends with i Pics, Tags, and +. Accessible Menu's
Bootstrap 5 Disclosure Menu makes the entire Tags label a single toggle
that opens the service-specific /a/tags, /b/tags, and /n/tags links.
Tab focuses the toggle; Enter or Space opens the menu, and Escape closes it. The existing
/tags View remains available at its URL, but the parent is not a separate
navigation action. Bootstrap Cloud 7.1.8 renders the parent as a native button
without depending on the site's hostname. This release includes
Bootstrap Cloud MR!92
for navigation contrast, native disclosure controls, and avoiding duplicate
Bootstrap loading. The previous 7.1.7 release rendered the parent as a link
with button semantics.
The main navigation + link opens /node/add. The i Services link list remains
available at /m and follows the source site's administrator-managed
permissions; use an administrator account to add service links. The standard
administration-menu Add content link remains available separately.
Anonymous visitors see the six service labels in the same order as signed-in
users. Five private-service labels lead to the localized login form; i News
continues to link to its public feed. After login, Drupal's route access
checks hide those login-only links and expose the private service links in
their place. Direct requests to private service paths remain access-denied
until authentication. Do not grant anonymous access content to make private
menu links visible.
The five login links, the + link, and the Calendar links are Menu Link Config
configuration entities. They are distributed in config/ with machine names
such as anonymous_address_login and calendar_navigation_month; none has a
packaged UUID. Reapplying the Recipe does not duplicate them or overwrite
administrator changes to existing configuration entities. No custom module or
extra setup command is needed for these links.
The drupal/menu_link_config dependency currently uses an alpha release and is
not covered by Drupal's security advisory policy. Evaluate that dependency
before deploying this candidate. Sites that tested an earlier revision with
content-based login links must remove those five obsolete links through menu
administration before applying this revision. Sites that installed the earlier
seven content-based links must also remove the old +, Calendar, and five
Calendar navigation links through menu administration. Confirm each old link's
menu, title, and destination before deleting it, especially if the site has
customized its menus. The Recipe does not delete existing site content
automatically, so leaving an old link in place can display a duplicate.
The seven old links to replace are:
| Menu | Title | Destination |
|---|---|---|
| Main navigation | + | /node/add |
| Calendar | Calendar | /calendar/month |
| Calendar navigation | Month | /calendar |
| Calendar navigation | Week | /calendar/week |
| Calendar navigation | Day | /calendar/day |
| Calendar navigation | Year | /calendar/year |
| Calendar navigation | List | /calendar/list |
Record any customized titles, weights, and destinations before removing these old links, then restore those settings on the generated configuration links after applying the revised Recipe. Reapplying the Recipe subsequently preserves those configuration changes.
The Recipe includes a small set of public RSS feed definitions for English,
Japanese, Simplified Chinese, and Thai. Feed items are not included and are
fetched only when Drupal's Aggregator refreshes the feeds. Anonymous visitors
can read the i News lists; the other personal-service views remain protected.
The feed sources are created by scripts/install-safe.sh, not by a content
fixture in the Recipe. Applying drush recipe alone will not create them.
After the guarded alpha2 installer succeeds, run vendor/bin/drush cron from
the project root to request the first feed refresh. It requires outbound
access to the included public feed URLs; items are not guaranteed to appear
until the sources respond and Aggregator processes them. The legacy alpha1
manual sequence runs cron as its last step.
Re-applying the Recipe to an existing PixieNote installation is supported,
but existing configuration entities are not automatically overwritten.
Configuration actions do run again: they restore the Pixie Dark theme,
accessible-menu and print settings, clear anonymous permissions, and grant
the Recipe's authenticated permissions.
Configuration actions also move only the tag View's menu settings to the main
menu, expose its child links, restore Accessible Menu settings for the main
menu, and hide the lower Tools block. Tag filters, ownership arguments, fields,
and records are preserved. The Recipe's language overrides update the Tags menu
title and description to their shipped translations; other language-specific
configuration overrides are retained.
They also keep the i Services View at /m, remove its legacy main-menu entry,
restore the standard administration
Add content link, and keep the separate main-menu + entry pointed at
/node/add. Review those actions before re-applying to a customized site.
Apply later configuration changes through Drupal's normal configuration
management workflow. Re-application is not a content migration or a
replacement for a site backup.
Postal codes on existing installations
The home and office postal code fields are strings in fresh installations so leading zeroes, hyphens, spaces, and letters are preserved. Re-applying the Recipe does not change existing field storage definitions. On an existing installation, plan and test a separate migration on a staging copy after taking a database and files backup. Prefer creating replacement string fields, copying and verifying the existing values, updating form and display settings, and only then removing the old fields. Integer storage may already have lost leading zeroes, which cannot be inferred reliably during migration. Do not attempt an in-place field type change or run a data migration without a reviewed site-specific plan.
Updating
Back up the database, private files, and active configuration first. On a
standard Drupal 11 project, core-recipe-unpack moves the Recipe's package
dependencies into the site's composer.json and removes drupal/pixienote
as a direct requirement. Therefore composer update drupal/pixienote is not
an update path. Review the desired release and the site's root dependency
constraints, then fetch that Recipe release again. For the 1.x series, update
any older restrictive Bootstrap Cloud and Twig root constraints at the same
time. This is a one-time constraint migration, not a step for each dependency
release. The installer
may have unpacked the old exact theme constraint into the site's root
composer.json; updating PixieNote alone could select an older Recipe release.
Confirm that the existing feedback Contact form still has the intended
recipient; rerunning setup-contact preserves it rather than syncing it to
the current site email address.
Use the exact release being tested while only alpha releases are available.
The example below upgrades from the initial alpha to 1.0.0-alpha2 after it
is published. Change the Recipe version to the reviewed target release when
updating; ^1.0 alone excludes alpha releases. The broad root theme
constraint can remain unchanged for subsequent 7.x updates. The initial
alpha still imposes its own exact theme dependency; using the newer Recipe
is necessary to remove that package-level restriction. Keep Menu Link Config
as an explicit root requirement while it has only an alpha release.
composer require 'drupal/pixienote:1.0.0-alpha2' 'drupal/menu_link_config:^1.0@alpha' 'drupal/bootstrap_cloud:^7' 'twig/twig:>=3.29 <3.30' 'drush/drush:^13' --with-all-dependencies
Recipe releases have no automatic update path. Existing configuration entities, including Views and blocks, retain local edits when a Recipe is re-applied, while configuration actions run again and can replace theme or permission customizations. Compare local configuration with the updated Recipe and import reviewed changes through your site's configuration management. Do not blindly replace the active configuration on a site with private data.
For 1.0.0-alpha2 or a newer release containing scripts/upgrade-safe.sh,
use that guarded command after Composer resolves the reviewed release. First
test a complete database and private-files restore on a staging copy, review
site-specific configuration, and take a fresh verified backup. Then run from
the project root:
PIXIENOTE_BACKUP_VERIFIED=1 bash recipes/pixienote/scripts/upgrade-safe.sh
This guard closes the site and validates the private-file path. Before running it, confirm that the existing installation still has at least one Aggregator feed source. The upgrade refuses a site with zero feeds rather than treating it as a fresh installation; inspect and restore its configuration and content from a verified backup before retrying. Feed setup adds current public sources whose URLs are not already present. It preserves every existing feed and its imported items, including administrator edits and older alpha1 sources; it neither rewrites nor deletes feeds. Therefore an alpha1 installation can temporarily retain the six older CCTV sources while adding six VOA sources (13 to 19 feeds). Reapplying is idempotent and does not add another copy of a current URL. Review and remove any retired feed only after deciding how its imported items should be retained. Image effects are likewise created with Drupal-generated IDs on fresh sites and left unchanged when their settings match. A failure keeps maintenance mode enabled for inspection. A successful run restores its original value.
From the published 1.0.0-alpha1 release
A disposable Drupal 11 installation confirmed that applying the current
1.x Recipe after the published 1.0.0-alpha1 archive preserves a synthetic
private i Note. Its owner could still read it; another authenticated user and
an anonymous visitor could not. This is a focused test, not a migration of a
customized production site.
Reapplication does not remove content entities that were shipped by alpha1.
Its six CCTV sample feeds remain when the six VOA replacements are added, so
the sample feed count rises from 13 to 19. The alpha1 + link in Main
navigation and Calendar link in the Calendar menu also remain alongside their
new configuration-based counterparts. A site that used an intermediate
development revision may have five additional legacy Calendar navigation
links. Do not assume that a successful Recipe command produces the same menu
and feed set as a fresh installation.
Before updating, back up the database, files, and active configuration, then
record any edits to the old feeds and menu links. After reapplication, inspect
the old + link targeting /node/add in Main navigation and the old Calendar
link targeting /calendar/month in the Calendar menu. Remove only the
confirmed legacy content-based links through menu administration; keep the
new configuration-based links and any locally created links. Review the six
CCTV feed URLs and their imported items before deciding whether to remove
those feeds. Do not delete by a packaged UUID or blindly remove a feed with a
matching title. Finally, check the menus in all four languages and verify
that the owner, another authenticated user, and an anonymous visitor retain
the expected access to private content. The full old-link inventory appears
in the installation notes above.
Calendar navigation on existing installations
Fresh installations use a dedicated Calendar navigation menu and block for Month, Week, Day, Year, and List. Drupal generates these internal menu URLs with the active language prefix and installation base path. The block appears only on authenticated calendar pages, including empty calendars and the schedule list; the existing Calendar shortcut remains separate.
On an installation created before this change, re-application adds the new
menu and block without replacing existing Views or schedule records. After
backing up and reviewing local changes, edit the ischeduler_calendar View
and remove only its legacy Schedule list link custom-text header
(display.default.display_options.header.list_link) containing the five
literal /calendar links. Retain any other locally added headers and the
View's filters, arguments, displays, and schedule data. Export and review the
resulting configuration, then rebuild caches. Do not replace the entire View
to update navigation. Check all five menu links in each of the four languages.
What is installed
| Content type | Purpose | List path |
|---|---|---|
| i Address | Contacts | /a |
| i Bookmark | Bookmarks | /b |
| i Note | Notes | /n |
| i Scheduler | Month and week calendars | /calendar |
| i Services | Administrator-managed service links | /m |
The i News feed list is at /f, with its Top page at /top and a recent-news
block on /m. The i Pics grid at /n/p shows images attached to the current
user's i Note records. These are Views, not extra content types. RSS feeds
and imported items are shared site content; they are not user-isolated.
A new contact's birthday is empty until entered; the source site's "today"
default is intentionally not carried over to avoid a misleading age.
Included RSS sample sources
| Language | Sources |
|---|---|
| English | BBC News |
| Japanese | asahi.com, Yahoo! ニュース, 毎日新聞, 日本経済新聞 |
| Simplified Chinese | 法广中文新闻; 美国之音中文网: 新闻, 编辑推荐, 国会报道, 台湾, 港澳, 军事 |
| Thai | Sanook! |
The feed URLs are public examples and can be edited or removed after
installation. The Recipe does not copy or publish any fetched feed items.
The reference site's six CCTV feed URLs returned HTTP 403 and imported no
items in a fresh-install check on 2026-10-04. The six public VOA Chinese
replacement URLs are listed by the publisher at
https://www.voachinese.com/rssfeeds and each imported items through Drupal
Aggregator on that date. The existing RFI feed also imported items. Public
feed availability can change; verify the sources again after installation.
The guarded upgrade does not distinguish historical feed lists: it preserves
whatever sources and imported items already exist. To use a different default
list, review and make that change explicitly in Drupal after taking a backup.
The reference site's CNN Top Stories URL returned only April 2023 items in
the same check, so the Recipe uses BBC News for the English list instead.
The legacy CNN URL is http://rss.cnn.com/rss/cnn_topstories.rss; add it
manually only if its published items become current again.
The calendar opens at /calendar; /calendar/month is the reference site's
monthly alias, linked from a Calendar menu in the header only on calendar
pages. The weekly calendar is available at /calendar/week. Day and year
views at /calendar/day and /calendar/year are chronological lists rather than
calendar grids; both default to the current date or year and accept a date
argument in the URL. The schedule list remains at /calendar/list. The configuration
also installs an empty Tags vocabulary, tag lists,
search, a responsive Pixie Dark theme, an accessible menu, and a printable
browser view. Tags are optional at first because no example terms are
installed. The accessible menu loads its pinned JavaScript build from
jsDelivr; an offline installation needs a separately hosted copy. Bootstrap
Cloud accepts compatible 7.x updates; the site's lockfile controls the version
deployed. The selected HiraMaruPro-W4 font is
not bundled with Bootstrap Cloud or this Recipe. Browsers without that font
use the theme's fallback stack, so exact typography depends on fonts
installed on each visitor's device.
Twig is temporarily constrained to 3.29.x: 3.30.0 produces a template
TypeError and HTTP 500 responses in the fresh Drupal 11.4.7 Recipe test
environment. The constraint is unpacked into the site's root Composer
requirements. Remove it only after an upstream fix is verified against the
full Recipe suite.
The footer uses the stable 3.x series of the Copyright Footer module. Its
organization name, organization URL, origin year, version, and version URL
start empty. After applying the Recipe, set your own values in the Copyright
Footer block configuration; no publisher identity is installed as a site
default. Bootstrap Cloud 7.1.8 centers the copyright/Contact row, restores
the mobile navigation icon contrast, and fixes dark editor/form text colors.
The public Contact link appears beside the copyright text in a centered row.
The documented setup step creates the required Contact form from the
installing site's own mail setting.
Privacy defaults
PixieNote grants authenticated users permissions for their own personal
records and uses Node View Permissions for bundle-level view access. Review
role permissions before allowing multiple unrelated users onto one site.
Images use Drupal's private file scheme; configure file_private_path in
settings.php before enabling uploads.
Keep self-registration disabled, as in a fresh Minimal install. Taxonomy
terms are a shared vocabulary, so this Recipe is intended for a personal
site or a trusted group, not as a fully isolated multi-tenant service.
Aggregator feed sources and their items are public, including to anonymous
visitors. Add only sources suitable for that public audience. The news views
filter by language, not by owner or by membership in the packaged sample list;
newly added sources are not private. Do not add private feeds or feed URLs
containing credentials or access tokens.
Verification
On a fresh test site, run the guarded installer both with a valid private-file
path and with a path inside the web root. The invalid path must fail while
leaving maintenance mode enabled. An error after Recipe application must also
leave the site closed; a retry must clear the default grant before reopening.
Assert that the node-access rebuild flag is clear,
there is no nid = 0 default grant in node_access, and anonymous and
other authenticated users cannot read another owner's private record or
download its private image or thumbnail. The included functional and
privacy-audit tests exercise those conditions.
The license audit compares the complete GPL text after normalizing whitespace.
Drupal.org reformats LICENSE.txt in release downloads, so a byte-for-byte
source checksum is not suitable for the distributed package. Changes to the
license text still fail the audit; only whitespace formatting is ignored.
ReapplicationTest applies the Recipe to a populated, customized test site.
It verifies preservation of a note, its tag and private image (including the
file bytes), an edited RSS source, a Views title, a block weight, and the site
name. It checks that existing entity IDs are unchanged, documented theme and
permission actions run again, and the retained note and image remain readable
only by their owner. This tests reapplication of the same Recipe, not an
upgrade between different releases or a substitute for a backup/restore test.
To run this focused check in the Drupal test checkout, with its test server
running and the usual SIMPLETEST_* and browser-output variables configured:
vendor/bin/phpunit -c web/core/phpunit.xml.dist recipes/pixienote/tests/src/Functional/ReapplicationTest.php
If you use a PHP-enabled Drupal test checkout, run phpcs with the Drupal
and DrupalPractice standards and run the tests in tests/. Current
versions of several dependencies, including Calendar View and Printable,
emit Drupal 11 deprecation notices. PHP 8.4 additionally reports nullable
parameter deprecations in Calendar View. These are upstream compatibility
warnings, not passing evidence for future Drupal versions; do not suppress
test failures while reviewing them.
Scope
The Recipe reproduces the reusable structure and principal behavior of the source service. Production-only branding, analytics, advertising, mail settings, API credentials, content, and the site-specific print-link layout overlay are intentionally excluded. The production calendar uses a beta Calendar module with month, week, day, and year views. This Recipe recreates its month and week grids with the supported stable Calendar View module. Day and year views use Drupal core Views as chronological lists instead of grids, so the layout and navigation are not pixel-identical. PDF export relies on the browser's Print dialog; Printable's save-PDF feature is disabled.