Neutrope Quiz Engine

Plugin Banner

Neutrope Quiz Engine

by Neutrope Inc.

Download
Description

Neutrope Quiz Engine is a flexible quiz engine for WordPress, designed for
certification study sites, e-learning, and media sites that want to embed
interactive quizzes. Build a library of questions and one or more test sets in
the WordPress admin, then drop a shortcode anywhere — on pages, posts, or
custom content — to render the quiz. Scoring happens entirely on the client,
so quizzes work on cached / static pages and do not write to the database.

Core features

  • Questions and test sets managed as WordPress custom post types
  • Practice mode (per-question feedback) and mock mode (graded at the end)
  • Step-by-step or full-list display
  • Question shuffling, choice shuffling, configurable choice labels (A/B/C/D,
    カナ, numeric, custom)
  • Pass thresholds (percentage or number of correct answers) and per-set time limit with countdown
  • Question banks (practice / mock / 過去問 etc.) for grouped delivery
  • Per-field accuracy breakdown on the results screen
  • CSV import with dry-run, upsert and automatic term creation
  • Optional question and explanation images with alternative text
  • Optional per-choice images, including choices made of a picture alone
  • Optional image credits, shown under the image, with the explanation, or
    nowhere in the quiz, as the site chooses
  • Images held as media library attachments, at a size the test set picks
  • Unscored essay prompts with browser-only responses and self-review rubrics
  • Optional choice-question group minimums by field or canonical position
  • Configurable call-to-action link per test set on the result screen

Shortcodes

  • [ntqengine_quiz set="<ID>"] — renders the test set with the given ID.

Example: [ntqengine_quiz set="123"]

No external services

All processing happens inside your WordPress install. The plugin makes no
outbound HTTP requests, loads no remote scripts or styles, and stores no
quiz-result records in the database.

  1. Upload the plugin folder to /wp-content/plugins/, or install through the
    WordPress Plugins screen.
  2. Activate Neutrope Quiz Engine through the Plugins menu in WordPress.
  3. Under the 問題 menu, add some questions. Under the テストセット menu,
    create a test set and link it to the relevant 資格種別 taxonomy term.
  4. Embed the test set anywhere with [ntqengine_quiz set="<ID>"].

CSV import is available under 問題 CSVインポート (dry-run + upsert).

  1. Quiz display on the front end (practice mode, step-by-step).

    Quiz display on the front end (practice mode, step-by-step).

  2. Result screen with score, accuracy, pass / fail verdict and per-field
breakdown.

    Result screen with score, accuracy, pass / fail verdict and per-field breakdown.

  3. Question admin: choices, correct answer, explanation and difficulty.

    Question admin: choices, correct answer, explanation and difficulty.

  4. Test set admin: mode, question count, time limit, pass mode, CTA and
display options.

    Test set admin: mode, question count, time limit, pass mode, CTA and display options.

  5. CSV import: dry-run report with per-row create / update / skip / error
counts.

    CSV import: dry-run report with per-row create / update / skip / error counts.

In what order are questions shown when shuffling is off?

By the external ID (ql_external_id), compared without regard to case. Where
two IDs are identical apart from their digits, the digits are compared as
numbers, so item-2 comes before item-10 even without zero padding. IDs
that differ in their text are compared character by character, as before.
Questions whose IDs compare equal are ordered by post ID, and questions
without an external ID come last. Canonical question positions — which group
minimums can be keyed to — follow the same order.

Does the plugin store quiz results in the database?

No. Scoring is computed entirely on the client and is not persisted. Pages
can be safely cached because no per-user state is written on the server.

What is removed on uninstall?

Only the CSV-import temporary transients and the
wp-content/uploads/ntqengine-imports/ working directory. Questions, test
sets, taxonomy terms and post meta are deliberately preserved so production
data is never lost on uninstall.

Is the plugin translation-ready?

Yes. All user-facing strings (PHP and JS) are routed through the
neutrope-quiz-engine text domain. A languages/neutrope-quiz-engine.pot template is
included. JS strings are delivered via wp_localize_script, with Japanese
fallbacks compiled into the script so display never breaks when translations
are missing.

Does it work with cache plugins?

Yes. Output is purely HTML plus a JSON-in-<script> payload; nothing depends
on per-request server state. Page caches (WP Super Cache, W3 Total Cache,
LiteSpeed, etc.) are safe.

Which shortcode should I use?

Use [ntqengine_quiz set="<ID>"]. It is the only shortcode the plugin
registers. You can place several instances on the same page; each one renders
and scores independently.

How do I add question or explanation images?

Use the question editor’s image URL and alternative-text fields, or the
optional CSV columns question_image_url, question_image_alt,
explanation_image_url, and explanation_image_alt. Existing CSV files do
not need these columns. Sites can enforce media policies before JSON output
with the ntqengine_question_data filter.

How do I put a picture on a choice?

Each choice in the question editor has its own image URL and
alternative-text fields, or you can use the optional CSV columns
choice_1_image_url / choice_1_image_alt through
choice_4_image_url / choice_4_image_alt. A choice may hold a
picture, text, or both; leave its text empty for a picture-only choice,
and give that picture alternative text, because the alternative text is
what the result screen and the review sheet record as the chosen answer.
Existing CSV files do not need these columns, and a question with no
choice image produces exactly the quiz data it produced before.

Can an image come from the media library?

Yes. Every image field — question, explanation and each choice — has an
attachment ID field beside its URL field, or the matching optional CSV
columns (question_image_id, explanation_image_id,
choice_1_image_id … choice_4_image_id). An attachment ID is used in
place of that field’s URL, at the size the test set picks, so moving or
renaming the file does not break the question. A question with no
attachment ID keeps using its URL exactly as before.

An attachment that cannot be shown does not fall back to the URL.
When the attachment is missing, is not an image, or is not publicly
viewable — WordPress decides that, so an image attached to a draft is
not public while an unattached one is — the slot is left empty and named
in the question’s images_unavailable, so the site can drop the whole
question with ntqengine_skip_question rather than ask it without the
picture it depends on. Falling back would quietly serve an image the
site has taken down.

Alternative text and credits are never read from the attachment. A line
written for the media library usually names the subject, which in a quiz
can be the answer, so the question’s own fields are the only source and
nothing is generated. The editor shows the attachment’s alternative text
and caption as a hint to copy from deliberately.

A multilingual site can return the translated attachment from the
ntqengine_attachment_id filter; the plugin does no translation of its
own. ntqengine_attachment_image_size overrides the size per image.

Can a site keep a question out of a quiz?

Yes. Return true from the ntqengine_skip_question filter and that
question is left out of the attempt: out of the question count, the
scoring, the per-field accuracy, the group minimums and the canonical
positions. It is meant for a site that refuses an image on rights
grounds and does not want the question asked without the picture it
depends on. The questions that remain are numbered from one, the way an
unpublished question already renumbers them, and a set whose questions
are all dropped shows a notice instead of an empty quiz. When a set asks
for more questions than are left, it asks the ones that remain; the
settings’ question_count_target and question_count_actual show the
difference, and skipped_questions says how many the site dropped.

ntqengine_question_data is separate and unchanged: it keeps the

question whenever it is handed anything that is not an array, so a
filter that forgets to return cannot start dropping questions.

How do I credit an image?

Each image field — question, explanation and each choice — has a credit
text field and a credit link field, or the matching optional CSV columns
(question_image_credit, question_image_credit_url,
explanation_image_credit, explanation_image_credit_url,
choice_1_image_credit … choice_4_image_credit_url). Put the text you
want displayed in the credit field; the plugin builds the link itself and
escapes both, and the link opens in a new tab so an answer in progress is
not lost. A link with no text shows nothing, because the text is what gets
displayed.

Each test set chooses where its credits appear: under the image, with the
explanation after the question is answered (for when a photographer name
or a source page would give the answer away), or nowhere in the quiz, so
the site can list them in a standing section of its own. The plugin never
invents a credit from a file name, a domain or the alternative text, and a
question with no credit renders exactly as it did before.

Whether a licence requires a credit, and what it has to say, is for the
site to decide. Neutrope\QuizEngine\Credits::for_set( $set_id ) returns
every credit a set would show, for building that standing section, and the
ntqengine_set_credits filter can adjust the list.

What does the score pass mode mean?

The stored score mode compares the threshold with the number of correct
answers; every question counts as one. It does not calculate weighted points
or convert the result to a 100-point scale. Updating does not change any saved
threshold or verdict. Administrators can audit affected sets without writing
to the database with wp ntqengine doctor pass-modes --format=json. Each
row says which shape its saved threshold has: ok, perfect_required
(the threshold equals the question count, so only a perfect result
passes — the shape a threshold meant as “60 points out of 100” ends up
with), unreachable (the threshold is above the question count, so the
set cannot be passed), no_threshold (zero, so everyone passes) or
count_dynamic (the set asks every question in its bank, so the two
cannot be compared here). These are advisories about intent, not errors;
the settings screen shows the same warning while you edit a set.

0.9.0

  • Let a question point at an image by media library attachment ID,
    beside the existing URL fields, in the editor and in six optional CSV
    columns. Each test set picks the size its attachment-backed images are
    served at.
  • Leave a question without an attachment ID exactly as it was.
  • Never fall back to the stored URL when an attachment cannot be
    shown.
    The slot is left empty and named in images_unavailable, so
    the site can drop the question with ntqengine_skip_question.
  • Judge whether an attachment may be shown the way WordPress does, so an
    image attached to a draft is not public while an unattached one is.
  • Never read alternative text or credits from the attachment; show them
    in the editor as a hint instead.
  • Add ntqengine_attachment_id and ntqengine_attachment_image_size.

0.8.2

  • Add the ntqengine_skip_question filter, so a site can keep one
    question out of an attempt — for a picture refused on rights grounds,
    rather than asking the question without it and marking it wrong.
  • Leave ntqengine_question_data as it was: anything that is not an
    array still keeps the question, so an existing filter cannot start
    dropping questions on upgrade.
  • Report the number of dropped questions in the quiz data, only when a
    site dropped one.

0.8.1

  • Say which saved correct-count thresholds look like a points total that
    was entered by mistake. wp ntqengine doctor pass-modes now labels
    each set, and the test set screen warns while the set is being edited
    when the threshold equals or exceeds the question count.
  • No change to how any verdict is decided, and no setting is rewritten.

0.8.0

  • Add an optional credit to every image — question, explanation and each
    choice — as a text field and a separate link field, so the anchor is
    built by the plugin and both are escaped on output.
  • Let each test set choose where its credits appear: under the image, with
    the explanation after answering, or nowhere in the quiz.
  • Add twelve optional CSV columns for the credits. Columns that are absent
    from an uploaded CSV are left untouched on update.
  • Keep credits out of the recorded answers: they describe the image, not
    the attempt.
  • Add Credits::for_set() and the ntqengine_set_credits filter for
    building a standing credits section outside the quiz.
  • Keep the quiz data and the rendered markup identical when no credit is
    entered.

0.7.0

  • Allow a picture on each choice, kept in its own meta fields rather
    than inside the choice text, so the recorded answer and the review
    sheet stay free of markup. A choice may be a picture alone.
  • Add the per-choice image URL and alternative-text fields to the
    question editor and eight optional CSV columns
    (choice_1_image_url … choice_4_image_alt). Columns that are
    absent from an uploaded CSV are left untouched on update.
  • Fall back to a picture-only choice’s alternative text wherever a
    choice is named as text: the result screen, the review sheet, the
    completion event, and the button’s accessible name.
  • Keep the quiz data identical when no choice carries a picture, so
    sites that do not use the feature see no change.

0.6.0

  • Compare external IDs so that digits are read as numbers when that is the
    only difference between two IDs, so item-2 is shown before item-10
    without zero padding. IDs that differ in their text keep the order they had,
    and IDs that differ only in case or in padding still fall back to the
    previous comparison and the post-ID tiebreak.
  • Document the unshuffled question order, which was not described anywhere.

Order change. Sites whose external IDs end in unpadded numbers will see
those questions in a different order: by value instead of character by
character. This is the intended fix. If a test set keys group minimums to
canonical question positions, the questions at those positions change with the
order, so review those sets after updating. Zero-padded IDs are unaffected.
Positions recorded in earlier attempts refer to the earlier order. No schema
or content migration is required.

0.5.0

  • Add unscored essay prompts with browser-only responses and optional
    self-review rubrics. Essay responses are not included in automatic scoring,
    pass/fail verdicts, completion events, local history or Pro persistence.
  • Add optional choice-question group minimums by field or canonical question
    position, using either correct-count or correct-percentage thresholds in
    addition to the existing overall condition.
  • Sign the exact server-rendered choice-question selection so Pro can validate
    question IDs and canonical positions without trusting submitted positions.
  • Exclude essays from signed scoring selections, including questions converted
    from choice format while legacy choice metadata remains.

0.4.9

  • Keep hand-created questions without ql_external_id eligible when question
    shuffling is disabled, with deterministic ordering for missing or duplicate IDs.
  • Add official question/explanation image URL and alt-text fields to the editor,
    CSV importer and public payload, plus a pre-JSON site-policy filter.
  • Keep legacy CSV imports compatible when image columns are absent; all four
    image columns are optional, and empty-value overwrites apply only to columns
    actually present in the uploaded CSV.
  • Render explanation images after explanation text in step, list and review views.
  • Clarify that legacy score pass mode means number of correct answers and add
    a read-only WP-CLI audit; saved values and verdict logic remain unchanged.
  • Keep deterministic release builds compatible with both LF and CRLF source
    checkouts while validating version metadata.
  • Accept legacy ql_choices arrays with numeric 0-based or 1-based keys when
    canonical choice_N keys are absent, while keeping canonical keys preferred.
  • Normalize and reject invalid questions before applying each test set’s
    question-count limit, preventing random quizzes from returning too few
    questions when the valid pool is large enough.
  • Include the plugin version in frontend CSS and JavaScript cache keys while
    retaining file-change cache busting during development.

0.4.8

  • Improve timed quiz bar positioning when a site uses a sticky or fixed header.
  • Add automatic sticky header offset detection while preserving manual CSS
    override support.
  • Keep the quiz timer sticky within the quiz container without covering the
    site header.

0.4.7

  • Hardens the quiz shortcode set attribute to accept only positive integer
    IDs, including values wrapped in paired straight or smart quotes.
  • Rejects missing, malformed and out-of-range set values with a safe notice,
    without querying quiz posts or emitting a quiz JSON payload.
  • Adds a read-only WP-CLI identifier doctor for detecting legacy residue after
    schema 2 migrations.
  • Adds HTTP, DOM, JSON and real-browser release gates for migrated quizzes,
    including question integrity, asset loading and browser/PHP error checks.
  • Keeps timed-quiz controls visible while scrolling on desktop and mobile,
    including the correct offset below the WordPress admin bar and isolation
    between multiple quizzes on one page.

0.4.6

  • Automatically migrates pre-0.4.5 question and test-set post types,
    taxonomies and executable legacy shortcodes to the ntqengine identifiers.
  • Preserves post IDs, term IDs, relationships and every ql_* / ql_set_*
    post-meta value.
  • Stores an immutable pre-migration snapshot, runs database changes in one
    transaction and verifies that no executable legacy identifiers remain.
  • Uses a database lock to prevent concurrent migrations and stops module
    startup with an administrator notice if a conflict or database error is found.

0.4.5

  • Prefix compliance update for WordPress.org: renamed the shortcode, custom
    post types, taxonomies, script/style handle, JavaScript object, plugin
    constants and the CSV-import transient/admin identifiers to the unique
    ntqengine prefix.
  • The shortcode is now [ntqengine_quiz set="<ID>"]. The previous
    [nqe_quiz], [ql_quiz] and [wpqe_quiz] aliases have been removed.
  • Existing content created with earlier versions needs to be migrated to the
    new post types and taxonomies before upgrading.

0.4.4

  • Add browser-local anonymous quiz summary support for future Study Desk integrations when Pro integration data is available.
  • Keep quiz summary storage client-side and scoped to the visitor’s browser.

0.4.3

  • Pass completed quiz result payloads to the Pro integration bridge when available.
  • Preserve existing quiz scoring, retry, and scroll behavior.

0.4.2

  • Fix scroll position after viewing quiz results and retrying a quiz.
  • Preserve the quiz completed JavaScript event hook for Pro integrations.

0.4.1

  • Added a nqe:quiz:completed JavaScript event, dispatched on the quiz root
    element (.skl-quiz, with bubbles: true) when scoring completes. This is a
    purely additive extension point for add-ons such as Neutrope Quiz Engine Pro;
    it does not change existing shortcodes, markup, CSS, scoring logic, the result
    display, or any backward-compatibility identifiers. Scoring still happens
    entirely on the client and no data is written to the database by the free
    plugin.

0.4.0

  • Initial public release.
  • Question and test-set custom post types with practice and mock modes,
    step / list display, question and choice shuffling, configurable choice
    labels, pass thresholds, countdown timer, question banks, per-field
    accuracy breakdown, and a configurable per-set CTA on the result screen.
  • CSV importer with dry-run, upsert, automatic term creation and
    CSRF-hardened upload handling.
  • Shortcode for embedding a test set on any page or post.
  • Frontend strings routed through wp_localize_script with Japanese
    fallbacks (translation-ready via the neutrope-quiz-engine text domain).
  • No outbound HTTP, no external assets, no per-user database writes.
Back to top