Skip to content

Mount a directory from the browser #1482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 2, 2024
Merged

Conversation

bgrgicak
Copy link
Collaborator

@bgrgicak bgrgicak commented Jun 2, 2024

Motivation for the change, related issues

We would like to enable developers to mount local directories into their Playground-based projects by prompting users to select a directory. After the directory is selected the folder can be mounted into Playground and used by it.

For example, this could be used to load local plugins and themes into Playground.

Implementation details

This PR adds a window message listener that takes the provided directory handle and mounts it to the mountpoint.

window.showDirectoryPicker().then(function (directoryHandle) {
	window.parent.postMessage({
		type: 'mount-directory-handle',
		directoryHandle,
		mountpoint: '/wordpress/wp-content/uploads/markdown/',
	});
});

Testing Instructions (or ideally a Blueprint)

  • Add this code after line 280 in packages/playground/remote/src/lib/worker-thread.ts


	primaryPhp.writeFile(
		'/wordpress/mount.php',
		`<!DOCTYPE html>
		<html>
		<head>
			<title>Directory picker</title>
		</head>
		<body>
			<button id="pick">Pick directory</button>
			<script>
				document.getElementById('pick').addEventListener('click', function() {
					if (!('showDirectoryPicker' in window)) {
						alert('Your browser does not support the Directory Picker API');
						return;
					}
					window.showDirectoryPicker().then(function(directoryHandle) {
						window.parent.postMessage(
							{
								type: 'mount-directory-handle',
								directoryHandle,
								mountpoint: '/wordpress/wp-content/uploads/markdown/',
							}
						);
					});
				});
			</script>
		</body>
		</html>`
	);
  • open this blueprint http://localhost:5400/website-server/?url=/mount.php
  • Click the button and select a local folder that contains an HTML file
  • Change the URL in the Playground header to /wp-content/uploads/markdown/YOUR-HTML-FILE.html
  • Confirm that your file was loaded

@bgrgicak bgrgicak self-assigned this Jun 2, 2024
@bgrgicak bgrgicak marked this pull request as ready for review June 2, 2024 18:09
@bgrgicak bgrgicak requested a review from a team June 2, 2024 18:09
@bgrgicak
Copy link
Collaborator Author

bgrgicak commented Jun 2, 2024

@adamziel and I took a look at the code together. @brandonpayton this PR has instructions required for the markdown plugin button.

@bgrgicak bgrgicak merged commit 09c2d17 into trunk Jun 2, 2024
5 checks passed
@bgrgicak bgrgicak deleted the add/php-opfs-mount-trigger branch June 2, 2024 19:47
@johnstonphilip
Copy link

I am trying to mount a plugin to wp-content/plugins with this PR but it doesn't seem to be working.

If someone is able to take a look, I am playing with it at https://pluginade.com

My code is


    // Use unpkg for convenience
    import { startPlaygroundWeb } from 'https://playground.wordpress.net/client/index.js';

    const client = await startPlaygroundWeb({
        iframe: document.getElementById('wp'),
        remoteUrl: `https://playground.wordpress.net/remote.html?storage=device`,
        blueprint: {
            // preferredVersions: {
            //     wp: '6.3',
            //     php: '8.0',
            // },
            // Optional: downloads additional PHP extensions like DOMDocument, mbstring, etc.
            // extensionBundles: ['kitchen-sink'],
            features: { networking: true },
            steps: [
                { step: 'login' },
                // {
                //     step: 'installPlugin',
                //     pluginZipFile: {
                //         resource: 'wordpress.org/plugins',
                //         slug: 'gutenberg',
                //     },
                // },
            ],
        },
    });
    await client.isReady();
    document.getElementById('mount-directory-handle').addEventListener('click', async () => {
        const directoryHandle = await window.showDirectoryPicker({
            id: 'playground-directory',
            mode: 'readwrite',
        });
        window.parent.postMessage({
            type: 'mount-directory-handle',
            directoryHandle,
            mountpoint: '/wordpress/wp-content/plugins/',
        });
    });

@bgrgicak
Copy link
Collaborator Author

@johnstonphilip This code was designed to work within Playground and it can't be called from the outside.

For this to work we would need to add a method to the Playground client.

What are you trying to build? How is the directory mounting useful to you?

@johnstonphilip
Copy link

@bgrgicak I am trying to build a quick and easy way to test a plugin that you might have on your local computer. So essentially I am hoping people can click a button, browse to a plugin on their computer, and have it get mounted into wp-content/plugins. From there they could make code changes locally and test them immediately inside Playground.

@bgrgicak
Copy link
Collaborator Author

Adding support for triggering directory mounting makes sense to me.

It could also be useful for the Playground website to have this as a single function in the future.
@adamziel maybe we could even add folder mounting in the website redesign.

@johnstonphilip
Copy link

@bgrgicak I am a little confused about the developer documentation showing mounting information here:
https://wordpress.github.io/wordpress-playground/javascript-api/mount-data

I guess I am not sure where am I supposed to use that code. Is that supposed to be part of the documentation already?

@bgrgicak
Copy link
Collaborator Author

I guess I am not sure where am I supposed to use that code. Is that supposed to be part of the documentation already?

No, it shouldn't have been added to the documentation.

@adamziel I was thinking of adding a mountDirectory function to the Playground client.
Because this feature works only in Chromium browsers I wouldn't add it as a blueprint step, just a helper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants