Using WordPress? Every integration here is also available as a plugin. Browse the plugin store →

Knowledge base WordPress plugins Data and documents

Embedding OneDrive files in WordPress with OneDrive Display

The five shortcodes the Office 365 OneDrive Display plugin registers, the order it wants you to connect things in, and what each failure message on the page actually means.

Published 12 August 2026

  • onedrive
  • wordpress
  • shortcode
  • embedding
  • microsoft graph

Office 365 OneDrive Display (version 2.7, text domain o365) puts files from one connected OneDrive for Business account onto WordPress pages. It is an add-on: it will not stay activated without the o365 base plugin, and it reads its Azure credentials from the base plugin’s settings rather than holding its own.

Everything below is drawn from the plugin source.

Connect it in this order

The plugin fails closed at three separate points, each with its own message, and they fire in this sequence.

1. Configure the base plugin first. OneDrive Display’s activation hook checks o365_base_plugin_is_verify. If it is 0 the plugin deactivates itself and stops with “ERROR: This plugin needs to be configured on the settings page >> General tab, before proceeding.” If the base plugin (o365/o365.php) is not active at all, it deactivates itself with “This plugin requires o365 base plugin.”

The General tab stores client_id, client_secret and tenant_name in the o365_settings option. tenant_name is the label in front of .onmicrosoft.com, not the full domain and not the GUID — the plugin builds https://login.windows.net/<tenant_name>.onmicrosoft.com/.well-known/openid-configuration from it to look your tenant ID up, and caches the result in onedrive_search_tenant_id.

2. Enter the licence key. The licence field for this plugin is added to the base plugin’s licence tab and writes onedrive_search_lcode; verification sets onedrive_search_verify_auth. Until that flag is truthy, every one of the display shortcodes renders the single line “Please enter the Office365 OneDrive Display Plugin activation key.” and the admin carries the notice “Please enter the Office 365 Onedrive Display plugin activation key.”

3. Get the access token. The tokens tab shows a Get Access Token button while onedrive_search_access_token is empty. It sends the browser to:

https://login.microsoftonline.com/common/oauth2/authorize
  ?response_type=code
  &client_id=<client_id>
  &redirect_uri=<your wp-admin URL>
  &state=o365_onedrive_view_identifier

The redirect URI is admin_url() — the wp-admin root of this site, trailing slash and all. It has to be registered on the Azure app registration character for character, and it changes if the site moves or switches scheme.

Coming back, WordPress sees ?code=…&state=o365_onedrive_view_identifier and exchanges the code at https://login.microsoftonline.com/common/oauth2/token, then redirects to the settings page with either “Successfully get OneDrive access token” or “Error while getting access token”. On success it stores onedrive_search_access_token, onedrive_search_refresh_token and onedrive_search_token_expires.

Once a token exists the button becomes Revoke Token.

About Azure permissions

The plugin uses the Azure AD v1 endpoints and asks for a resource, not scopes: the token request sends resource=https://graph.microsoft.com and no scope parameter at all. So there is no scope list in the plugin to match against — the permissions in play are whatever delegated permissions the app registration itself carries. It is an authorization-code flow signed in as a person, and the calls it makes are /me/drive/… and /users/<user id>/drive/…, so the registration needs delegated read access to OneDrive files for that account.

Tokens refresh themselves: on any request where time() + 300 has passed onedrive_search_token_expires, the plugin posts grant_type=refresh_token to https://login.microsoftonline.com/<tenant id>/oauth2/token and rewrites all three options. A failed refresh is silent — the symptom is that pages stop listing files, not an error.

The shortcodes

Five, registered from the filenames in shortcode/.

[o365_onedrive_file]

Embeds one or more specific items.

AttributeDefaultNotes
file(empty)Graph drive item IDs, comma-separated. Nothing renders without it.
height700pxApplied to the <embed> for document types.
width500pxSame.

For each ID it calls GET /v1.0/me/drive/items/<id>?expand=thumbnails(...). What comes out depends on the extension: pdf, xls, xlsx, csv, doc, docx, ppt and pptx are sent through POST /v1.0/me/drive/items/<id>/preview and rendered as an <embed> pointing at the returned getUrl. Anything else with a thumbnail renders as the 256×256 thumbnail followed by the filename. Anything without one falls back to a bundled generic icon — exe, zip, jpg, jpeg, png, gif, bmp, tif and txt have icons; other extensions with no thumbnail produce nothing at all.

[o365_onedrive_folder]

A browsable folder listing with breadcrumbs.

AttributeDefaultNotes
dir(empty)Drive item ID of the folder to open at.
maxresults(empty)Appended as Graph’s $top.
width(empty)Accepted by the shortcode but not used in the output.

It calls GET /v1.0/me/drive/items/<dir>/children. Clicking a folder or a breadcrumb re-fetches through admin-ajax.php; when Graph returns an @odata.nextLink a Load More button appears and pages through it, ending on “No more result found!!!”.

[o365_onedrive_view] and [o365_onedrive_proof]

These two render through a PHP template instead of building markup inline, and they read a different drive: /v1.0/users/<o365_display_user_id>/drive/…, where the user ID comes from the base plugin’s o365_display_user_id setting. Both accept folderid, template, includefile, title, subfolders (no), sort, maxresults (10), cache, viewer, id (o365), columns, userbinding (no) and password. o365_onedrive_proof adds show_like (yes).

sort becomes &orderby=<value>%20desc, columns becomes &select=, maxresults becomes &top=. id is used to build element IDs, so give each shortcode on a page a distinct id if you place more than one. subfolders="yes" makes folder rows clickable rather than hiding them.

Watch the template attribute. Templates are looked up first in your theme at <theme>/o365-display/onedrive/views/<file>, then in the plugin’s own templates/views/. The plugin directory ships grid_tpl.php, listv1_tpl.php, listv3_tpl.php and mgt_list.php — but with no template attribute, [o365_onedrive_view] looks for list_tpl.php and [o365_onedrive_proof] looks for masonry_tpl.php, neither of which is in that set. When the file is missing the include is simply skipped, so the shortcode outputs an empty space and no error. Name a template you actually have:

[o365_onedrive_view folderid="01ABCDEF..." template="listv1_tpl.php" maxresults="25"]

[mgt_onedrive]

The odd one out. Instead of rendering server-side from the stored token, it loads Microsoft’s Graph Toolkit from https://unpkg.com/@microsoft/mgt/dist/bundle/mgt-loader.js and emits <mgt-msal2-provider>, <mgt-proxy-provider> and <mgt-file-list>. The provider uses the base plugin’s client_id, login-type="redirect" and authority https://login.microsoftonline.com/common — meaning the visitor signs in to Microsoft in their own browser and sees their own files. Attributes: driveid, itemid, userid, proxy (fed to graph-proxy-url), plus the shared template/maxresults/ userbinding set.

Getting item IDs without hunting for them

Every shortcode above is keyed on Graph drive item IDs, which are not something you can read off the OneDrive web UI comfortably. The plugin adds two buttons to the classic editor toolbar (registered via mce_buttons / mce_external_plugins) — a File button and a Folder button. Each opens a browser over the connected drive, and Insert Shortcode writes the finished tag into the editor: [o365_onedrive_file file="…"] or [o365_onedrive_folder dir="…"]. This plugin registers no Gutenberg block, so in the block editor the practical route is to pick the file in a classic-editor context, or paste the shortcode into a shortcode block.

Locking a listing down

Two independent gates, both on o365_onedrive_view and o365_onedrive_proof:

  • userbinding="yes" requires a logged-in WordPress user. Logged-out visitors get “First need to login user in wordpress for see the OneDrive files search result.”
  • password="…" puts an Unlock Project form in front of the listing. A post meta value of wpcf-password-for-this-folder on the containing post takes precedence over the attribute. A wrong entry shows “Incorrect Password” in red; ticking Remember Me records the unlock in the PHP session the plugin starts on plugins_loaded, so it survives until the session ends, not permanently. Super admins skip the form entirely.

Worth being clear-eyed about the model: apart from [mgt_onedrive], no visitor ever authenticates to Microsoft. The listing and download endpoints are registered for logged-out visitors too (wp_ajax_nopriv_o365_onedrive_view_records, …_folder_records, …_get_file_download_link, …_auto_search), and they run with the one stored token from whoever connected the plugin. Anything that account can see is reachable to anyone who can call admin-ajax.php with the right item ID. Connect an account whose drive contents you are comfortable exposing, and treat password= as a speed bump on the page rather than access control on the files.

When it goes wrong

A red admin notice: “…doesn’t have an access token.” onedrive_search_access_token is empty. The notice links to the token manager; re-run Get Access Token.

“Tenant name or Sharepoint token data not defined.Please check O365 base plugin setting tab.” — or the same sentence with “OneDrive” in place of “Sharepoint”, from [o365_onedrive_proof]. Either o365_settings['tenant_name'] is blank or the access token is gone. Both live in the base plugin.

“Please enter the Office365 OneDrive Display Plugin activation key.”onedrive_search_verify_auth is empty or false. Licence step, not token step.

Blank output, no message. Almost always the missing default template described above. Add an explicit template= naming a file that exists.

“cURL Error #:” printed into the page. [o365_onedrive_file] and [o365_onedrive_folder] print transport-level cURL errors inline rather than logging them — DNS, TLS or timeout (the calls use a 30-second timeout) between your host and graph.microsoft.com.

“No Result Found” in a list template. The bundled templates print this both for an empty folder and for a failed request. The AJAX handler does relay Graph’s own error message in the JSON response, so if the folder is definitely not empty, check the admin-ajax.php response in the browser’s network tab for the real reason — an expired token and a bad folderid look identical on the page.

An alert saying “ERROR: Unable to load folder data, Please Try Again.” The admin-ajax.php POST behind [o365_onedrive_folder] failed outright — a 403 from a security plugin or a PHP fatal, not a Graph problem.

A page called “Onedrive Single Page” you did not create. The plugin creates one on admin_init, remembers it in onedrive_single_gallery_page_id, and registers a rewrite rule for ^onedrive-single-page/<folder name>. Delete it and it comes back on the next admin request; it backs the single-folder gallery view. Its template can be overridden at <theme>/o365-display/onedrive/pages/o365-onedrive-gallery-page.php.

Uninstalling

Uninstall deletes the plugin’s own options — onedrive_search_tenant_id, onedrive_search_access_token, onedrive_search_refresh_token, onedrive_search_token_expires, onedrive_search_verify_auth, onedrive_search_lcode, onedrive_search_auth_code, onedrive_search_resource_url and onedrive_search_id_token. The base plugin’s o365_settings, including your Azure credentials, is not touched. Nothing revokes the refresh token on the Microsoft side, so remove the grant from Azure AD as well if you are decommissioning the site.

Read next

  • WordPress plugins · Data and documents

    Configuring SharePoint Search and Document Display

    This plugin is being retired. How to rebuild each shortcode in the Documents component, exactly which attributes have no equivalent — and, for reference, the original setup: base plugin, licence key, access token, the seven shortcodes and what each failure message means.

  • WordPress plugins · Getting started

    Setting up the Office 365 Microsoft Booking plugin

    Base plugin, Azure token, licence, then a shortcode — the order the plugin actually enforces, with every [msb_booking] attribute and its default.

  • WordPress plugins · Getting started

    SharePoint Calendar Display: setup, shortcodes and room booking

    Installing Office 365 SharePoint Calendar Display, the order the plugin requires, every attribute of [o365_sp_events] and [o365_sp_booking], and what each failure message means.

Back to the knowledge base