{"id":350529,"date":"2026-08-18T08:06:17","date_gmt":"2026-08-18T08:06:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/axismundi-media-library\/"},"modified":"2026-08-18T08:05:45","modified_gmt":"2026-08-18T08:05:45","slug":"axismundi-media-library","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/axismundi-media-library\/","author":21128503,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.0.42","stable_tag":"0.0.42","tested":"7.0.4","requires":"6.7","requires_php":"8.1","requires_plugins":null,"header_name":"Axismundi Media Library","header_author":"KIM JIWOON","header_description":"Promote WordPress attachments to independent media objects. Independent mode unbinds new uploads and adds visibility controls (public \/ unlisted \/ private) with per-surface access guards; Core mode leaves WordPress untouched.","assets_banners_color":"","last_updated":"2026-08-18 08:05:45","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/Jiwoon-Kim\/axismundi\/tree\/main\/products\/distributables\/plugins\/axismundi-media-library","header_author_uri":"https:\/\/designbusan.ai.kr","rating":0,"author_block_rating":0,"active_installs":0,"downloads":40,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"0.0.42":{"tag":"0.0.42","author":"kimjiwoon","date":"2026-08-18 08:05:45"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":{"axismundi\/media-rights":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-rights","version":"0.1.0","title":"Media Rights","category":"theme","icon":"privacy","description":"Displays license, creator, source, and a copyable attribution for an Attachment.","textdomain":"axismundi-media-library","usesContext":["postId","postType"],"supports":{"html":false,"multiple":false,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"editorScript":"file:.\/edit.js","editorStyle":"file:.\/style.css","style":"file:.\/style.css","viewScript":"file:.\/view.js","render":"file:.\/render.php"},"axismundi\/media-archive-title":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-archive-title","version":"0.1.0","title":"Media Archive Title","category":"theme","icon":"heading","description":"Displays the current media author or folder title.","textdomain":"axismundi-media-library","attributes":{"level":{"type":"number","default":1}},"supports":{"html":false,"align":true,"color":{"text":true},"spacing":{"margin":true,"padding":true},"typography":{"fontSize":true,"lineHeight":true}},"editorScript":"file:.\/edit.js","render":"file:.\/render.php"},"axismundi\/media-preview":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-preview","version":"0.1.1","title":"Media Preview","category":"theme","icon":"format-image","description":"Displays the current Attachment inside a Query Loop.","textdomain":"axismundi-media-library","usesContext":["postId","postType"],"attributes":{"sizeSlug":{"type":"string","default":"medium_large"},"linkToAttachment":{"type":"boolean","default":true}},"supports":{"html":false,"align":true,"spacing":{"margin":true}},"editorScript":"file:.\/edit.js","editorStyle":"file:.\/style.css","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/media-collection":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-collection","version":"0.2.1","title":"Media Collection","category":"theme","icon":"images-alt2","description":"Displays media folders and paginated attachments in separate collection regions.","textdomain":"axismundi-media-library","attributes":{"source":{"type":"string","default":"current"},"ownerId":{"type":"number","default":0},"folderId":{"type":"number","default":0},"columns":{"type":"number","default":4},"perPage":{"type":"number","default":12},"imageSize":{"type":"string","default":"medium_large"},"showDates":{"type":"boolean","default":true},"showCounts":{"type":"boolean","default":false},"showUp":{"type":"boolean","default":false}},"supports":{"html":false,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"editorScript":"file:.\/edit.js","editorStyle":"file:.\/style.css","style":"file:.\/style.css","render":"file:.\/render.php"},"axismundi\/media-post-template":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-post-template","version":"0.1.0","title":"Media Post Template","category":"theme","icon":"grid-view","description":"Repeats its inner blocks for every Attachment in a Media Collection.","textdomain":"axismundi-media-library","parent":["axismundi\/media-collection"],"supports":{"html":false},"editorScript":"file:.\/edit.js"},"axismundi\/media-pagination":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-pagination","version":"0.1.0","title":"Media Pagination","category":"theme","icon":"ellipsis","description":"Displays pagination for a Media Collection.","textdomain":"axismundi-media-library","parent":["axismundi\/media-collection"],"attributes":{"showPrevious":{"type":"boolean","default":true},"showNumbers":{"type":"boolean","default":true},"showNext":{"type":"boolean","default":true}},"supports":{"html":false},"editorScript":"file:.\/edit.js"},"axismundi\/media-no-results":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-no-results","version":"0.1.0","title":"Media No Results","category":"theme","icon":"warning","description":"Displays its inner blocks when a Media Collection has no Attachments.","textdomain":"axismundi-media-library","parent":["axismundi\/media-collection"],"supports":{"html":false},"editorScript":"file:.\/edit.js"},"axismundi\/media-folders":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/media-folders","version":"0.1.0","title":"Media Folders","category":"theme","icon":"portfolio","description":"Displays the child folders of a Media Collection.","textdomain":"axismundi-media-library","parent":["axismundi\/media-collection"],"attributes":{"heading":{"type":"string","default":"Folders"},"showCounts":{"type":"boolean","default":false},"showUp":{"type":"boolean","default":false}},"supports":{"html":false},"editorScript":"file:.\/edit.js"}},"tagged_versions":["0.0.42"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1346,84],"plugin_category":[50],"plugin_contributors":[270183],"plugin_business_model":[],"class_list":["post-350529","plugin","type-plugin","status-publish","hentry","plugin_tags-attachments","plugin_tags-media","plugin_category-media","plugin_contributors-kimjiwoon","plugin_committers-kimjiwoon"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/axismundi-media-library.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Axismundi Media Library promotes the WordPress attachment into an independent,\npublishable media object with its own owner and visibility, organised into virtual\nfolders, with structured rights (license, attribution, copyright, source) and a\nsensitive-content workflow. Saved references (collections) and federation are\nplanned for later phases.<\/p>\n\n<p>Activating the plugin changes no existing media. <strong>Core mode<\/strong> leaves WordPress\nattachments untouched. <strong>Independent mode<\/strong> detaches new uploads (post_parent 0)\nand enforces per-item visibility \u2014 public, unlisted, or private \u2014 across the\nattachment page, the REST API (single and collection), and the media picker.\nOwnership is the WordPress author (post_author); permission reuses core\ncapabilities.<\/p>\n\n<p>The full specification lives in the plugin's docs\/ directory (SPEC, SECURITY,\nROUTING, COMPATIBILITY, DATA-MODEL, PHASES). Independent mode provides media\narchives at \/media\/ and \/media\/author\/{nicename}\/. Attachment single pages continue to use\nthe active theme's normal attachment template hierarchy; Axismundi includes a\ndedicated attachment.html template.<\/p>\n\n<h3>Copyright<\/h3>\n\n<p>Axismundi Media Library, Copyright 2026 KIM JIWOON.\nDistributed under the terms of the GNU General Public License, version 3 or later.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload and activate Axismundi Media Library.<\/li>\n<li>Open Settings &gt; Media Library (Axismundi). Activation changes no existing media.<\/li>\n<li>Choose Independent mode to enable independent-attachment visibility.<\/li>\n<li>Optional: deactivate FileBird, then use Media &gt; Import Folders to analyze and\nimport a FileBird CSV export without overwriting existing Axismundi assignments.<\/li>\n<\/ol>\n\n<!--section=changelog-->\n<h4>0.0.42<\/h4>\n\n<ul>\n<li>Restrict federation rendition diagnostics to users who can edit the requested attachment.<\/li>\n<li>Require attachment visibility before Media Preview and Media Rights render, including editor-preview fallbacks.<\/li>\n<\/ul>\n\n<h4>0.0.41<\/h4>\n\n<ul>\n<li>Add nested media-folder management to the Media Library: direct counts,\ndrag-and-drop attachment moves, inline rename\/create, folder reparenting,\nkeyboard-accessible folder actions, and selected-folder uploads.<\/li>\n<li>Require explicit confirmation before moving a folder would weaken inherited\nprivate or password protection, and report partial attachment moves honestly.<\/li>\n<\/ul>\n\n<h4>0.0.39<\/h4>\n\n<ul>\n<li>Let an embedded-media policy select one bounded provider derivative up to 1024 pixels,\neven when the provider does not persist that larger virtual size in attachment metadata.\nThe candidate still passes HTTPS host, transform, dimension, pixel, and source-byte gates;\nthe original file remains excluded.<\/li>\n<\/ul>\n\n<h4>0.0.38<\/h4>\n\n<ul>\n<li>Keep trusted virtual rendition discovery available during Gutenberg REST saves. Jetpack\nsuppresses Photon image downsize when the editor request header is present; Axismundi now\nlifts that suppression only for its synchronous federation lookup and immediately restores\nthe editor policy.<\/li>\n<\/ul>\n\n<h4>0.0.37<\/h4>\n\n<ul>\n<li>Resolve virtual rendition URLs through WordPress image downsize when raw attachment\nmetadata contains the virtual marker but omits the provider URL. The computed URL still\npasses trusted-host, transform, dimension, pixel, and byte policy.<\/li>\n<\/ul>\n\n<h4>0.0.36<\/h4>\n\n<ul>\n<li>Allow rendition diagnostics for media already eligible for anonymous federation while\nkeeping private and locked attachments hidden behind the upload capability. Diagnostic\noutput contains public rendition metadata and policy decisions, never filesystem paths.<\/li>\n<\/ul>\n\n<h4>0.0.35<\/h4>\n\n<ul>\n<li>Treat a validated provider source URL as the virtual-rendition marker instead of\ndepending on a context-sensitive metadata boolean. Add an upload-capability-protected\nrendition diagnostic endpoint so administrators can inspect policy decisions without\nexposing server paths.<\/li>\n<\/ul>\n\n<h4>0.0.34<\/h4>\n\n<ul>\n<li>Treat provider metadata as the rendition inventory for policy-selected virtual sizes,\nwithout requiring those historical sizes to remain registered in the current request.\nAccept boolean-like virtual markers while retaining trusted-host, transform, dimension,\npixel, and source-byte gates.<\/li>\n<\/ul>\n\n<h4>0.0.33<\/h4>\n\n<ul>\n<li>Read an explicitly marked virtual rendition from its provider-owned metadata URL rather\nthan requiring the request-context image-downsize filter to select the same URL. This\nrestores PNG, JPEG, and WebP Note attachments on sites whose image sizes are all backed\nby Jetpack Photon.<\/li>\n<\/ul>\n\n<h4>0.0.32<\/h4>\n\n<ul>\n<li>Admit explicitly marked Jetpack Photon virtual image derivatives as federatable\nrenditions when WordPress selects the same trusted HTTPS URL and the source remains\nwithin policy bounds. Projection performs no CDN fetch, never falls back to the\noriginal, and omits an unknowable derivative byte size instead of guessing it.<\/li>\n<\/ul>\n\n<h4>0.0.31<\/h4>\n\n<ul>\n<li>Let domain plugins register readable relation subjects without making Media Library\ndepend on those domains, enabling ordered Note attachments to reuse the canonical\nmedia-relation store.<\/li>\n<\/ul>\n\n<h4>0.0.30<\/h4>\n\n<ul>\n<li>Add a folder listing API that returns a folder's visible child folders followed by its\ndirect media as one paginated sequence, so a federated folder can be navigated like the\ndirectory it is meant to be. Children are gated by the same rule that decides whether a\nfolder federates at all, rather than a second gate: an internal, private, or gated child\nis absent from the listing and from its count.<\/li>\n<li>Lock the sensitivity model for remote objects in docs: an origin's declaration is an\nobservation, never an authority state, so it stays out of the state machine that decides\nwho may clear a flag. A remote \"sensitive\" is never clearable locally; a remote false or\nunreported may be overridden locally through the normal authority record.<\/li>\n<li>Lock sensitivity scopes (site, user, folder, collection) as narrow-only, and record that\nblurring remote media is not privacy \u2014 the request itself must be withheld until reveal,\nor the origin already has the viewer's IP and the browser already has the image.<\/li>\n<\/ul>\n\n<h4>0.0.29<\/h4>\n\n<ul>\n<li>Install the media archive routes whenever they are found missing from the rewrite table,\ninstead of once per version counter. The counter was consumed even on the branch that\ndeliberately skipped the flush in Core mode, so the record claimed rules were installed\nthat had never been written; and because a flush cannot report success, a rule that\nfailed to persist stayed missing until someone saved permalinks by hand.<\/li>\n<li>A changed rule set no longer needs a manual counter bump to take effect. Retries are\nlimited to once an hour, Core-mode sites install nothing as before, and sites on plain\npermalinks are untouched.<\/li>\n<\/ul>\n\n<h4>0.0.28<\/h4>\n\n<ul>\n<li>Give every folder a permanent federation identity UUID, registered through the Axismundi\nActors identity registry, so a shared folder keeps one immutable URI across renames,\nmoves, and domain changes. The display permalink stays owner-scoped and mutable; the\nidentity URI is \/media\/folder\/{uuid}\/ and is not derived from it.<\/li>\n<li>Attribute a folder to its owner's Actor, resolved live from the user rather than copied\nonto the term.<\/li>\n<li>Publish and withdraw a folder identity as its visibility changes: public or unlisted,\nungated, and owned by a public Actor federates; anything else stays unpublished.\nWithdrawal returns the record to internal, and deleting a folder tombstones its\nidentity so a URI a peer already holds resolves to gone rather than to nothing.<\/li>\n<li>Axismundi Actors remains optional: without it a folder simply has no federation\nidentity, and local folder behaviour is unchanged.<\/li>\n<li>Show the folder's federation state and immutable Collection JSON-LD link in Media &gt;\nFolders. Opening this manager lazily backfills identities for pre-existing folders.<\/li>\n<li>Expose a bounded, anonymous folder-item query API for Object Projections. Direct members\nare ordered by folder-add time; private and gated media remain excluded even for an\nadministrator request.<\/li>\n<\/ul>\n\n<h4>0.0.27<\/h4>\n\n<ul>\n<li>Add the FEP-1311 federation rendition service: axismundi_media_federation_renditions()\nenumerates only the derivatives WordPress already generated, largest first, capped at four,\ndeduplicated by URL and dimensions, and returns url\/mediaType\/width\/height\/size. The Media\nLibrary owns this selection so consumers never read attachment metadata internals.<\/li>\n<li>Never advertise the original. Core's is-intermediate flag is the gate, so an image with no\ngenerated subsize returns nothing instead of falling back to the full-size file, and a\nsubsize whose byte size cannot be read is omitted rather than guessed.<\/li>\n<li>Gate the service on anonymous, cache-safe visibility only \u2014 public or unlisted, ungated,\nIndependent mode \u2014 with no owner\/editor bypass, and invent no versions for video, audio, or\ndocuments while there is no transcoding substrate.<\/li>\n<\/ul>\n\n<h4>0.0.26<\/h4>\n\n<ul>\n<li>Show the same parent\/child folder hierarchy in Attachment Details Location and\nMedia &gt; Add New by sharing one hierarchy-aware option service.<\/li>\n<\/ul>\n\n<h4>0.0.25<\/h4>\n\n<ul>\n<li>Save the grid Attachment Details Location field through a dedicated,\nnonce-protected request and show Saving\/Location saved status so a reload does\nnot silently race WordPress's compatibility-field autosave.<\/li>\n<\/ul>\n\n<h4>0.0.24<\/h4>\n\n<ul>\n<li>Scope Unfiled to the current user's uploads while keeping All media available\nas the complete capability-filtered library view.<\/li>\n<li>Add an Upload to folder selector to Media &gt; Add New for both Plupload and the\nbrowser uploader, using the same ownership checks as modal uploads and moves.<\/li>\n<li>Cover Attachment Details Location saves with a regression fixture.<\/li>\n<\/ul>\n\n<h4>0.0.23<\/h4>\n\n<ul>\n<li>Enforce that an Attachment can only be assigned to a virtual folder owned by\nits WordPress author, including administrator, upload, edit, and FileBird\nimport paths.<\/li>\n<li>Repair legacy cross-owner, hidden-root, and multi-folder relationships to\nUnfiled in bounded admin batches so affected media reappears in its author\narchive and Unfiled view.<\/li>\n<\/ul>\n\n<h4>0.0.22<\/h4>\n\n<ul>\n<li>Add a FileBird CSV compatibility importer at Media &gt; Import Folders for hosts\nwithout WP-CLI access. It recreates nested folders in the current user's\nnamespace and assigns media through the existing per-attachment permission\nservice.<\/li>\n<li>Parse the CSV once without retaining the uploaded file, then process folders and\nattachment assignments in resumable AJAX batches suitable for constrained\nhosting. Missing or unauthorized media is reported without stopping the job.<\/li>\n<li>Preserve existing Axismundi assignments, reject malformed\/cyclic hierarchies,\nreport cross-folder duplicates, and tag imported folders by FileBird source ID\nso rerunning the same export reuses folders instead of duplicating them.<\/li>\n<\/ul>\n\n<h4>0.0.21<\/h4>\n\n<ul>\n<li>Phase 4c (output integration) \u2014 sensitive media now gets a front-end\nclick-to-reveal blur overlay on the visual core blocks that render an\nattachment: core\/image, core\/video, and core\/post-featured-image. The overlay\nshows the content warning and a Show button. This is a viewer content warning,\nnot access control: the file is never altered or withheld and the blur applies\nto everyone including the owner. Assets load only on the front end in\nIndependent mode; the editor is untouched. Audio (no visual surface), Open\nGraph preview exclusion, and post-level flagging are intentionally out of scope.<\/li>\n<\/ul>\n\n<h4>0.0.20<\/h4>\n\n<ul>\n<li>Define Location visibility as an output policy for plugin-rendered metadata only.\nAxismundi never rewrites original or derivative files to remove EXIF\/GPS data.<\/li>\n<li>Drop the planned destructive GPS\/EXIF stripping phase and clarify the file-level\nprivacy boundary in the editor and specification.<\/li>\n<\/ul>\n\n<h4>0.0.19<\/h4>\n\n<ul>\n<li>Add the plugin-owned Media Rights dynamic block with license conditions, creator,\ncopyright holder, source, and rich-text\/Markdown attribution copying inspired by\nOpenverse and the WordPress Photo Directory.<\/li>\n<li>Append Media Rights once to the main Attachment content without adding a custom\nblock dependency to the active theme. Manual placement suppresses the automatic\ncopy.<\/li>\n<\/ul>\n\n<h4>0.0.18<\/h4>\n\n<ul>\n<li>Phase 4b (folder default license) \u2014 each folder can set a default license\n(Media &gt; Folders). A new upload into that folder is stamped with the default as\na one-time snapshot: it resolves the nearest ancestor folder that declares one,\nfalls back to all-rights-reserved, and NEVER overwrites a license the upload\nalready carries. This is not dynamic inheritance \u2014 moving an existing item\nbetween folders never changes its license. Every upload path (media modal, REST,\ndirect) shares the one stamp service on <code>add_attachment<\/code>.<\/li>\n<\/ul>\n\n<h4>0.0.17<\/h4>\n\n<ul>\n<li>Phase 4b (resolver) \u2014 a single license\/rights API. axismundi_media_license_record()\nreturns the code, display name, canonical CC\/PDM URL, and derived reuse conditions\n(attribution \/ commercial \/ derivatives \/ share-alike \/ known). The canonical URL\nwins for standard codes so the code and URL can never disagree; all-rights-reserved\nand unknown grant nothing. axismundi_media_attribution_text() prefers the authored\nattribution and otherwise composes a display-only title + creator + license string.<\/li>\n<li>Clean break: the plugin has no external installs yet, so there is no legacy license\nalias, no <code>custom<\/code> value, and no reuse\/download-policy migration \u2014 the resolver\ntreats any dropped\/legacy code as all-rights-reserved. This is the last point to\nfinalize the schema cleanly.<\/li>\n<\/ul>\n\n<h4>0.0.16<\/h4>\n\n<ul>\n<li>Drop the duplicate Reuse policy field. Creative Commons permissions and conditions\nderive from License, avoiding two mutable rights values that can drift apart.<\/li>\n<li>Clarify that Collection Save is a bookmark\/reference gated by visibility, not a\nlicensed reuse. License checks apply to later Import\/Copy, redistribution, and\ntransformation operations.<\/li>\n<li>Align the License field with the Openverse vocabulary \u2014 Public Domain Mark, CC0,\nCC BY, CC BY-SA, CC BY-ND, CC BY-NC, CC BY-NC-SA, CC BY-NC-ND, Unknown \u2014 plus an\nAll-rights-reserved default for a creator's own copyrighted work. The render field\nand its save whitelist now share one source (axismundi_media_license_options()).<\/li>\n<\/ul>\n\n<h4>0.0.15<\/h4>\n\n<ul>\n<li>Drop the never-enforced Download policy field. Core does not restrict downloads and\nthis plugin cannot either without Phase 6 controlled delivery, so a delivery-\naffordance hint that claimed to be a control has been removed rather than shipped.<\/li>\n<\/ul>\n\n<h4>0.0.14<\/h4>\n\n<ul>\n<li>Phase 4a \u2014 sensitive authority. <code>_ax_media_sensitive<\/code> becomes a derived, read-only\neffective boolean; the authority lives in <code>_ax_media_sensitive_state<\/code> (none \/\nself_marked \/ automated_flagged \/ moderator_marked \/ confirmed) with set-by, set-at,\nand a locked flag.<\/li>\n<li>An owner may self-mark and clear their own mark, but cannot clear a moderator or\nconfirmed lock, and can only appeal (not self-clear) an automated flag \u2014 closing the\nPhase 2c audit gap. Capabilities moderate_media_sensitivity \/ override_media_sensitivity\n(editors) and mark_own_media_sensitive (uploaders) map from existing roles.<\/li>\n<li>Attachment Details shows the state: moderators get a state selector, owners a\nself-mark checkbox while unlocked, and a read-only note when locked. Feeds and Media\nCollections keep reading the effective boolean, so nothing downstream changes.<\/li>\n<\/ul>\n\n<h4>0.0.13<\/h4>\n\n<ul>\n<li>Add the dual-key Used-in relation index (<code>wp_ax_media_relations<\/code>) with local-ID\nsource keys, optional canonical URIs, deduplication, occurrence counts, atomic\nper-provider replacement, schema upgrades, and read-filtered reverse lookup.<\/li>\n<li>Incrementally index featured images, core media blocks, galleries, and ID-based\ngallery\/playlist shortcodes while preserving prior data when an integration\nprovider reports an error. URL-string reverse matching remains intentionally out\nof scope.<\/li>\n<li>Add <code>wp axismundi media relations reindex<\/code> for exact dry-runs, single-post\nrebuilds, and confirmed full rebuilds.<\/li>\n<li>Rename the Attachment Details folder field to Location and add a role-labelled,\nread-filtered Used in list. Saved in remains reserved for Phase 5 collections.<\/li>\n<li>Add a guarded legacy-parent migration: immutable snapshot, read-only preview,\nexplicit detach, and ownership-safe rollback commands. Detach refuses missing or\nconflicting snapshots; rollback never overwrites a newer nonzero parent.<\/li>\n<li>Show an in-use deletion warning in Attachment Details without exposing source\ntitles or URLs the viewer cannot read.<\/li>\n<li>Add dev-only permission, relation-store, provider, and reindex regression fixtures;\nthe distributable ZIP excludes tests and build scripts.<\/li>\n<\/ul>\n\n<h4>0.0.12<\/h4>\n\n<ul>\n<li>Add Atom feeds for three scopes: Home (\/?ax_media_feed=home), Author\n(&amp;ax_media_owner=), and Folder (&amp;ax_media_folder=), plus pretty \/media\/\u2026\/feed\/atom\/\naliases. One shared, strict-public query service backs all three.<\/li>\n<li>Feeds emit only public + listed + ungated media; unlisted, private, and\npassword-gated items\/folders never appear, and a non-public folder feed 404s.<\/li>\n<li>Entry identity is the stable \/?attachment_id={id} across scopes; folder feeds order\nand date entries by when the item was added to the folder, Home\/Author by publish\ndate. Each archive advertises its feed via a  discovery link.<\/li>\n<li>Folder feeds are ON by default (like a category feed). A public folder can opt out\nvia a \"Feed\" checkbox on Media &gt; Folders (_ax_media_folder_feed_enabled = 0);\nnon-public or opted-out folders 404 and drop their discovery link.<\/li>\n<li>Add a Media RSS (media:content \/ media:thumbnail) sibling feed at the same scopes.\nFeeds serve an intermediate derivative (medium_large), never the original, and add\nthe item's folder as a category (Atom  \/ media:category). Sensitive items\nstay in the feed but are marked (Atom sensitivity category + content-warning\nsummary; media:rating + media:description) and are NOT given an auto-rendering\nenclosure or real thumbnail \u2014 an attachment-page link carries them instead.<\/li>\n<\/ul>\n\n<h4>0.0.11<\/h4>\n\n<ul>\n<li>Rebuild the Media Library folder sidebar on FileBird's proven layout: it is now a\nflex sibling of #wpbody-content (sticky) instead of an absolutely positioned\nelement inside the attachments browser. This removes the content-overlap bug and\nmakes the sidebar work in BOTH grid and list view \u2014 list mode had no folder tree\nbefore.<\/li>\n<li>List view filters via ?ax_media_folder= links + a server-side query filter; grid\nview drives the existing wp.media dropdown; the media modal keeps its dropdown.<\/li>\n<li>Add a folder-path breadcrumb above the Media Library content (both views), synced\nwith the sidebar selection; grid crumbs re-query in place, list crumbs are links.<\/li>\n<li>Show the folder tree inside the media-picker modal (Select or Upload Media) too,\nso choosing a folder narrows the picker when inserting images\/galleries in a post.<\/li>\n<li>Cache-bust the folder stylesheet\/script by filemtime so layout fixes reach\nbrowsers instead of serving a stale cached copy.<\/li>\n<\/ul>\n\n<h4>0.0.10<\/h4>\n\n<ul>\n<li>Add a FileBird-informed folder tree to the desktop Media Library and media\nmodal while retaining the existing folder dropdown on narrow screens.<\/li>\n<li>Keep the tree synchronized with the core attachment query so folder selection,\npermissions, and upload destination reuse the existing Axismundi services.<\/li>\n<li>Use the theme's folder, folder_open, and lock icon-font glyphs in public Media\nCollections; default desktop collections to four consistent columns.<\/li>\n<\/ul>\n\n<h4>0.0.9<\/h4>\n\n<ul>\n<li>Separate child folders from the paginated media grid and move optional parent\nnavigation into the folder-region header.<\/li>\n<li>Default folder counts and parent navigation to off, add sensitive-media\noverlays, and share the core Query Pagination styling contract.<\/li>\n<li>Add the core Breadcrumbs block to media home, author, and folder templates.<\/li>\n<li>Add Query Loop-style Media Folders, Media Post Template, Media No Results, and\nMedia Pagination inner blocks. Existing self-closing collections retain the\nsame default template as a server-rendered compatibility fallback.<\/li>\n<li>Save Attachment Details folder changes from partial media-modal payloads, and\nkeep password-protected child folders discoverable without exposing counts.<\/li>\n<\/ul>\n\n<h4>0.0.8<\/h4>\n\n<ul>\n<li>Add the Media Collection block with current archive, user root, and specific\nfolder sources; responsive columns; attachment pagination; and display controls.<\/li>\n<li>Render parent navigation, visible child folders, and direct Attachments in one\ncollection without leaking hidden descendant counts.<\/li>\n<li>Adopt Media Collection in media home, author, and folder templates.<\/li>\n<\/ul>\n\n<h4>0.0.7<\/h4>\n\n<ul>\n<li>Add folder password gates with WordPress password hashes, signed HttpOnly\nfolder cookies, nested gate inheritance, and owner\/editor bypass.<\/li>\n<li>Add protected-media challenges for folder and Attachment pages; gated media is\nexcluded from public collections and REST singles require authentication.<\/li>\n<li>Extend Media &gt; Folders and the folder REST API with open\/password access.<\/li>\n<\/ul>\n\n<h4>0.0.6<\/h4>\n\n<ul>\n<li>Add Media &gt; Folders for creating, nesting, renaming, deleting, and setting the\nvisibility policy of the current user's virtual folders.<\/li>\n<li>Add Media profile links to the Users screen.<\/li>\n<li>Add parent and child navigation to folder archives, and keep valid empty media\nprofiles and folders as 200 archives instead of generic 404 pages.<\/li>\n<\/ul>\n\n<h4>0.0.5<\/h4>\n\n<ul>\n<li>Phase 2a groundwork: the ax_media_folder virtual-folder taxonomy (hierarchical,\nper-user hidden root so two users can both have a \"Travel\" folder), single-folder\nenforcement (an attachment is in 0 or 1 folder), and direct\/recursive counts.<\/li>\n<li>Folder service + REST (axismundi-media\/v1): create, rename, delete (contents move\nto the root \u2014 never deleted), and move. Moving an attachment requires edit_post on\nTHAT attachment, not just upload_files.<\/li>\n<li>Attachment edit panel: assign the item's single folder.<\/li>\n<li>Folder-aware visibility resolver: explicit inherit support, narrow-only tier\nresolution across the parent chain, and derived effective-rank caches for\narchive, REST collection, and media-modal queries.<\/li>\n<li>Object\/Collection pretty routing: <code>\/media\/{type}\/{id}\/<\/code>,\n  \/media\/author\/{owner}\/, and owner-scoped folder archives; plain query\nendpoints remain the always-working base.<\/li>\n<li>Add the editable media-folder block template and dynamic archive-title block.<\/li>\n<li>Add the Media Library folder filter (All media, Unfiled, and the current\nuser's folder tree). New uploads inherit the folder selected in the picker.<\/li>\n<\/ul>\n\n<h4>0.0.4<\/h4>\n\n<ul>\n<li>Add public media archives with scoped visibility filtering. The base is a plain\nquery endpoint that works without pretty permalinks (?ax_media_archive=landing \/\nowner&amp;ax_media_owner={USER_ID}); \/media\/ and \/media\/{nicename}\/ are pretty\naliases. Owner is queried by user ID (nicename accepted on the alias; the\nPhase 2 pretty route is <code>\/media\/author\/{nicename}\/<\/code>).<\/li>\n<li>Add an optional Media page (Settings &gt; Reading) to use an editable Page as a\nstable media-hub landing.<\/li>\n<li>Editable plugin block templates: media-home (landing) and media-author (one\nuser's media; owner = post_author).<\/li>\n<li>Add a dynamic media-preview block for attachment Query Loops.<\/li>\n<li>Add stored-only creator, copyright, license, reuse, download, sensitivity,\ncontent-warning, and location-visibility metadata controls.<\/li>\n<li>Keep attachment single-page presentation in the active theme's standard\nattachment template hierarchy instead of duplicating it in the plugin.<\/li>\n<\/ul>\n\n<h4>0.0.3<\/h4>\n\n<ul>\n<li>Ownership is now the WordPress author (post_author) as the single source of\ntruth; removed the separate owner meta. Permission reuses core edit_post \/\nedit_others_posts.<\/li>\n<li>Fix: partial attachment saves no longer reset listed\/searchable (hidden field\nsentinel).<\/li>\n<li>Fix: reactivating while Independent mode is on re-acquires the attachment-pages\noption.<\/li>\n<li>New uploads set post_parent 0 before the INSERT (atomic), via\nwp_insert_attachment_data.<\/li>\n<li>Media modal now hides other users' unlisted media (matches SECURITY.md).<\/li>\n<li>Refresh admin and readme copy to reflect that Independent mode changes behaviour.<\/li>\n<\/ul>\n\n<h4>0.0.2<\/h4>\n\n<ul>\n<li>Phase 1a: Independent-mode media visibility (public \/ unlisted \/ private) with\nlegacy-public fallback, and per-surface access guards \u2014 HTML single, REST\nsingle (404), REST collection, and the media modal. New uploads become\nindependent (post_parent 0, owner, defaults). Canonical single page\n\/?attachment_id={id}. Attachment edit fields for visibility\/listed\/searchable.\nMedia archives (\/media\/) arrive in Phase 1b.<\/li>\n<\/ul>\n\n<h4>0.0.1<\/h4>\n\n<ul>\n<li>Phase 0 scaffold: non-destructive activation, a Core \/ Independent\nrelationship-mode setting (recorded, no effect until Phase 1), and a read-only\nattachment parent-relationship scan.<\/li>\n<\/ul>","raw_excerpt":"Promote WordPress attachments to independent, visibility-controlled media objects.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/350529","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=350529"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/kimjiwoon"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=350529"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=350529"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=350529"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=350529"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=350529"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=350529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}