During website production, saying that material is missing can mean several things. The feature may be unnecessary, or someone may not have supplied the file yet. Treating both situations as the same blank can leave an unwanted menu in place or silently remove something that still needs a decision.

The replaceable template I prepared distinguishes confirmed, absent and pending material. Its current build source blocks unresolved material before release and excludes sections marked absent. It also rejects a confirmed menu whose item list is empty. I rewrote that distinction as a small module so the person supplying material and the AI implementing the page can share the same meaning.

Explore a small example

This isolated example explains the structure. The article records what has actually been verified.

I record why the material is missing

Confirmed means the content and material have been checked for use. Absent means a decision has been made not to use that material. Pending means the need or the actual material has not yet been resolved. Absent and pending may both produce an empty screen, but they represent different decisions.

If a gallery is deliberately unnecessary, its menu and connected opening-screen teaser should be removed together. If photographs are still expected, they should remain in the work list as pending. Filling the gap with invented images or another project’s material removes the blank without establishing a truthful page. I do not let the status automatically become confirmed without an explanation.

I separate preview readiness from release readiness

The overall flow may need review before every file arrives. The original preview mode permits some unresolved material while the release mode blocks it. That establishes different conditions for internal review and public release; it does not mean unfinished content has been approved for visitors.

The new module returns previewReady and releaseReady separately. Pending material can allow an internal review plan while still preventing a ready-for-release result. The preview itself needs genuine private access. Naming a variable preview does not automatically provide authentication or prevent indexing.

I check the content behind a confirmed label

Changing a status does not create the material. An original template test rejects a confirmed menu with an empty item list. I retain checks for the actual entries and their connections even when someone has marked the status confirmed.

The new example verifies nonempty material-reference strings. It does not establish that a file exists, that its publication rights are appropriate, or that an image contains no old identity. A real production program should add path, file, material-type and disclosure checks. A data-shape check should not be described as verification of the truth of the material.

Connected introductions must be ready or removed together

Removing a detail menu while leaving its opening-screen button sends visitors toward a missing page. Confirming a teaser while its detail material remains unresolved can also present an unfinished subject as available. The original build checks whether a confirmed home section has a confirmed destination menu.

The small module expresses that relationship with requires. A section that introduces documents needs the document section to be confirmed. In a real project, menu links, cards, related posts, downloads and sitemap entries should follow the same publication state. This example checks a simple dependency plan rather than replacing a complete route generator.

I gather the status decision in one function

The following code is a newly written explanatory implementation. It checks whether each section is required and distinguishes visible, pending, omitted and invalid entries. A missing record remains pending. Unknown statuses and sections created by a typo do not disappear silently.

An optional section can be omitted as absent. Required material cannot become release-ready simply by being marked absent. Not having received needed information and deciding not to use information essential to the page require different discussions. Which sections are required is an input rule; the example does not impose the same fields on every website.

Explore the implementation

JavaScript · Material states for preview and release planning

export function planPublication(rules, records) {
  if (!rules || !records || typeof rules !== 'object' || typeof records !== 'object' ||
      Array.isArray(rules) || Array.isArray(records)) {
    throw new TypeError('Rules and records must be objects');
  }
  const ids = Object.keys(rules);
  if (!ids.length) throw new TypeError('At least one section rule is required');
  const visible = [], pending = [], omitted = [], errors = [];
  for (const id of Object.keys(records)) {
    if (!Object.hasOwn(rules, id)) errors.push(`${id}: unknown section`);
  }
  for (const id of ids) {
    const rule = rules[id];
    if (!rule || typeof rule.required !== 'boolean' ||
        (rule.requires !== undefined && !Array.isArray(rule.requires))) {
      throw new TypeError(`${id}: invalid section rule`);
    }
    const record = Object.hasOwn(records, id) ? records[id] : { status: 'pending' };
    if (!record || !['confirmed', 'absent', 'pending'].includes(record.status)) {
      errors.push(`${id}: invalid material status`);
      continue;
    }
    if (record.status === 'pending') { pending.push(id); continue; }
    if (record.status === 'absent') {
      omitted.push(id);
      if (rule.required) errors.push(`${id}: required material is absent`);
      continue;
    }
    if (!Array.isArray(record.items) || !record.items.length ||
        record.items.some(item => typeof item !== 'string' || !item.trim())) {
      errors.push(`${id}: confirmed material needs nonempty item references`);
      continue;
    }
    visible.push(id);
  }
  for (const id of ids) {
    for (const dependency of rules[id].requires || []) {
      if (!Object.hasOwn(rules, dependency)) {
        errors.push(`${id}: unknown dependency`);
      } else if (visible.includes(id) && !visible.includes(dependency)) {
        errors.push(`${id}: confirmed section lacks its confirmed dependency`);
      }
    }
  }
  return {
    visible, pending, omitted, errors,
    previewReady: errors.length === 0,
    releaseReady: errors.length === 0 && pending.length === 0
  };
}

export function assertRelease(plan) {
  if (!plan.releaseReady) throw new Error('Resolve material states before release');
  return [...plan.visible];
}

An example retains unresolved material

In the synthetic data below, introduction material is confirmed and documents remain pending. An internal review plan can exist, but assertRelease throws. A build system can connect this check before generating and uploading public files.

The function does not decide whether real material deserves confirmation. The review evidence and time should be recorded internally before changing the status. The references here are neutral identifiers rather than customer files or names. Connecting the status change to its reason also makes it possible to understand later why a menu was removed.

Explore the implementation

JavaScript · Internal review allowed while release remains blocked

const rules = {
  introduction: { required: true },
  documents: { required: false },
  documentTeaser: { required: false, requires: ['documents'] }
};
const records = {
  introduction: { status: 'confirmed', items: ['approved-introduction'] },
  documents: { status: 'pending' },
  documentTeaser: { status: 'absent' }
};

const plan = planPublication(rules, records);
// plan.previewReady === true
// plan.releaseReady === false
// plan.pending contains 'documents'
// Render only confirmed sections in an INTERNAL preview.
// Display plan.pending as review notes; do not treat it as public approval.
assertRelease(plan); // throws: unresolved material blocks release

I check the stopping conditions as well as successful release

The new module has nine synthetic-data check groups. They cover optional omission, pending release blocking, missing records remaining pending, required absence, empty confirmed lists, unresolved dependencies, complete dependencies, invalid statuses and sections, and input preservation. All passed. These are not file-existence, rendered-screen, API-permission or cloud-deployment checks.

The historical template review and inspected current source support broader build conditions. Even so, copying this function does not complete file review or public-access configuration. I preserve the distinction between conditions automatically blocked by code and conditions that require a person or AI to inspect the material.

  1. Does absent represent an actual decision distinct from pending?
  2. Do missing required material and empty confirmed lists stop release?
  3. Do connected teasers and links follow a removed menu’s state?
  4. Are file existence, rights and content reviewed separately?
  5. Is preview private and clearly distinct from release readiness?
  6. Can the reason and evidence for the last status change be found?

I manage unfinished decisions, not only empty screens

It is easy to fill an empty section with something attractive. When a website must explain real content, the choices to wait, omit or verify should come first. A blank can be a design issue, but it can also reveal that a decision has not been completed.

I consider these small material-state rules part of the quality of repeated production. Recording what can be removed, what must wait and what evidence permits release helps retain the basis for a decision when working with AI on the next website.