STR Content Management Debug Guide
STR Content Management is a new suite of plugins designed to create an integrated, highly scaleable content management, security, styling, tooling, analysis and private solution for non-block editor environments.
Initially, the intention is to launch it as a ClassicPress plugin, but it will also work in WordPress. However, there is no intention to support the block editor, or Full Site Editing.
STR Conetent Management includes a new access and security model, as well as a dynamic attack defense model that will allow for agile servers than move around the network. As such, the bloat of block-based WordPress makes it a less than ideal platform.
STR Debugger
The STR Debugger is a key part of our content management solution, debugging, just like the rest of the eco-system, is organic in design. This means that it is flexible, and offers a range of debugging styles for the user to configure for themselves, rather than the usual, “all or nothing” kind of debugging that is often available.
STR Levels
As you will see, our debugging system allows for developers to specify sifferent levels of debugging to be trigered, and focussed on specific components. debugging therefore becomes better targetted, and less overwhelming, in terms of the volume of error messages, and their appropriateness.
Goals
STR Content Management (STR Content Management) debug logging is designed to:
- make troubleshooting predictable across modules/sub-modules
- avoid noisy logs in production
- allow “risk-based” logging: newer/more complex areas log at lower debug levels (L1/L2) and stable/system areas log at higher levels (L3) or not at all
- prevent bootstrap “footguns” (calling debug before the debugger is loaded)
Debug Levels
STR Content Management uses four levels. Think of these as message detail levels:
- 0 (OFF): no debug output
- 1 (L1): high-level, risky/complex entry points (new code, file load boundaries, key orchestration functions)
- 2 (L2): helper outputs / intermediate results (your internal functions as they evolve)
- 3 (L3): deep detail / system calls (e.g.,
get_option, “included this file”, etc.). Optional to add.
Rule of thumb (risk-based):
- New + complex: emit L1 at start/end (and key checkpoints)
- Supporting helpers: emit L2 for important outputs
- WordPress/system calls: emit L3 only if you’re actively investigating something
Constants
Define constants early (bootstrap), with guards:
if (!defined('STRCM_DEBUG_OFF')) define('STRCM_DEBUG_OFF', 0);
if (!defined('STRCM_DEBUG_L1')) define('STRCM_DEBUG_L1', 1);
if (!defined('STRCM_DEBUG_L2')) define('STRCM_DEBUG_L2', 2);
if (!defined('STRCM_DEBUG_L3')) define('STRCM_DEBUG_L3', 3);
if (!defined('STRCM_DEBUG_DEFAULT_LEVEL')) define('STRCM_DEBUG_DEFAULT_LEVEL', STRCM_DEBUG_OFF);
if (!defined('STRCM_CORE_DEBUG_DEFAULT_LEVEL')) define('STRCM_CORE_DEBUG_DEFAULT_LEVEL', STRCM_DEBUG_OFF);
Scoping: module_id and sub_id
Every log entry should (where possible) be scoped with:
$module_id— identifies the module (or core)$sub_id— identifies the sub-module or the specific core component
Example for core bootstrap:
$module_id = 'content_management_core';
$sub_id = 'core_bootstrap';
This makes logs searchable and enables per-sub-module debug level control.
Bootstrap rule: don’t call debug before the debugger exists
Important: You cannot call strcm_debug_log() until the debugger file that defines it has been included.
Recommended pattern
- compute file paths
- include debugger file first
- only then call
strcm_debug_log()or wrappers likestrcm_core_include_once_with_debug()
Core file loading with debug boundaries
For “load file” style debugging, STR Content Management uses a helper that logs before/after includes.
strcm_core_include_once_with_debug()
Purpose: Load a file and optionally emit a “Loading…” and “Loaded…” log entry.
Recommended behaviour:
- the helper should not fatal if a file is missing
- it should emit an L1 “missing/unreadable” warning when the file can’t be loaded
Example usage:
strcm_core_include_once_with_debug($core_functions_file, STRCM_DEBUG_L1, $module_id, $sub_id);
Guidance for choosing log level on file loads
- L1: core admin + core functions (high impact, early in stack)
- L3: menus/help/debugger (often stable, or “deep detail”)
Standard log patterns
Pattern A: Function entry + exit (recommended for new/complex functions)
Use this for high-risk orchestration functions.
strcm_debug_log(STRCM_DEBUG_L1, __FUNCTION__ . ' fired', array(), $module_id, $sub_id);
// ... work ...
strcm_debug_log(STRCM_DEBUG_L1, __FUNCTION__ . ' completed', array(
'result_summary' => $summary,
), $module_id, $sub_id);
Pattern B: Helper output confirmation (recommended for evolving helper functions)
Use this for internal functions that produce data used by other functions.
strcm_debug_log(STRCM_DEBUG_L2, 'Built overrides array', array(
'count' => count($overrides),
), $module_id, $sub_id);
Pattern C: System call inspection (optional; L3)
Use this when you care about what WordPress returned.
$value = get_option('strcm_some_option', array());
strcm_debug_log(STRCM_DEBUG_L3, 'get_option(strcm_some_option)', array(
'is_empty' => empty($value),
), $module_id, $sub_id);
What NOT to log
Avoid logging:
- secrets (API keys, salts, passwords, nonces)
- full user objects / personal data
- full database rows unless explicitly redacted
Prefer summaries:
- counts, IDs, boolean flags, short strings, array keys
Recommended function naming
Since you’ve added _core_ to match conventions:
strcm_core_debug_log()(optional wrapper aroundstrcm_debug_log())strcm_core_get_active_debug_level()strcm_core_include_once_with_debug()
If you keep both core + module versions, keep names unambiguous:
- core-only helper:
strcm_core_* - module helpers:
strcm_*orstrcm_module_*
How this will work inside a sub-module function
Here’s the intended mental model:
- The sub-module stores an active debug level (0–3) in its settings (
sub_module_debug_modeor renamedsub_module_debug_level). - Each debug statement in the sub-module chooses its message level (1/2/3) based on risk/detail.
- A message prints only if:
active_debug_level >= message_level
Example skeleton (sub-module function)
function strcm_content_unique_headers_apply(array $post_ids): int {
$module_id = 'content_manager';
$sub_id = 'unique_headers';
strcm_debug_log(STRCM_DEBUG_L1, __FUNCTION__ . ' fired', array(
'post_count' => count($post_ids),
), $module_id, $sub_id);
// helper step (L2)
$headers = strcm_content_unique_headers_build_map($post_ids);
strcm_debug_log(STRCM_DEBUG_L2, 'Header map built', array(
'keys' => array_slice(array_keys($headers), 0, 10),
), $module_id, $sub_id);
// system call inspection (L3)
$opt = get_option('blogname');
strcm_debug_log(STRCM_DEBUG_L3, 'get_option(blogname)', array('value' => $opt), $module_id, $sub_id);
$updated = 0;
// ... do work, increment $updated ...
strcm_debug_log(STRCM_DEBUG_L1, __FUNCTION__ . ' completed', array(
'updated' => $updated,
), $module_id, $sub_id);
return $updated;
}
This is exactly the same pattern you’re using in bootstrap — just scoped to the sub-module.
Next step
To make this guide perfectly consistent with your current code, paste the updated core section with the new _core_ helper names (e.g. strcm_core_debug_log vs strcm_debug_log, strcm_core_include_once_with_debug vs strcm_include_once_with_debug) and I’ll:
align the guide to the exact function names you’re shipping
include a “copy/paste” template for sub-module functions that includes:
- recommended
$module_id/$sub_idconventions - entry/exit L1 pattern
- L2 helper output pattern
- optional L3 system call pattern









0 Comments