Skip to content

Commit

Permalink
[Interactive code block] Add "theme mode" in the code editor (#353)
Browse files Browse the repository at this point in the history
<!-- Thanks for contributing to WordPress Playground Tools! -->

## What?

<!-- In a few words, what is the PR actually doing? Include screenshots
or screencasts if applicable -->

This PR attempts to add theme support to the code editor mode, so that
users can set up a plugin or theme in the code editor mode.

## Why?

<!-- Why is this PR necessary? What problem is it solving? Reference any
existing previous issue(s) or PR(s), but please add a short summary
here, too -->

I would like to be able to set up practical activities for learners on
Learn.WordPress.org around both plugin and theme development, using the
WordPress Playground block

## How?

<!-- How is your PR addressing the issue at hand? What are the
implementation details? -->

## Testing Instructions

<!-- Please include step by step instructions on how to test this PR.
-->
<!-- 1. Check out the branch. -->
<!-- 2. Run a command. -->
<!-- 3. etc. -->

1. Check out the
[jonathanbossenger:351-code-editor-theme-support](https://github.com/jonathanbossenger/playground-tools/tree/351-code-editor-theme-support)
branch
2. Load and instance of the playground in the Site Editor
3. Change the Code Editor Mode to "Theme"
4. Create a style.css and templates/index.html block theme files
5. Run the playground preview
6. The two theme files should activate as the active theme in the
preview

Fixes #351
  • Loading branch information
jonathanbossenger authored Sep 25, 2024
1 parent c183062 commit 2423859
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@ import {
// @ts-ignore
} from 'https://playground.wordpress.net/client/index.js';

export default async function downloadZippedPlugin(client: PlaygroundClient) {
export default async function downloadZippedPackage(
client: PlaygroundClient,
codeEditorMode
) {
const docroot = await client.documentRoot;
const pluginPath = docroot + '/wp-content/plugins/demo-plugin';

let pluginPath = docroot + '/wp-content/plugins/demo-plugin';
let fileName = 'wordpress-playground-plugin.zip';

if (codeEditorMode == 'theme') {
pluginPath = docroot + '/wp-content/themes/demo-theme';
fileName = 'wordpress-playground-theme.zip';
}

const zipFile = new File(
[await zipPlaygroundFiles(client, pluginPath)],
'wordpress-playground-plugin.zip',
fileName,
{
type: 'application/zip',
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import {
import useEditorFiles, { isErrorLogFile } from './use-editor-files';
import { LanguageSupport } from '@codemirror/language';
import { writePluginFiles } from './write-plugin-files';
import downloadZippedPlugin from './download-zipped-plugin';
import { writeThemeFiles } from './write-theme-files';
import downloadZippedPackage from './download-zipped-package';
import classnames from 'classnames';
import FileManagementModals, { FileManagerRef } from './file-management-modals';
import {
Expand Down Expand Up @@ -90,6 +91,7 @@ function PlaygroundPreview({
blueprintUrl,
configurationSource,
codeEditor,
codeEditorMode,
codeEditorSideBySide,
codeEditorReadOnly,
codeEditorTranspileJsx,
Expand Down Expand Up @@ -277,7 +279,7 @@ function PlaygroundPreview({
500
);

await reinstallEditedPlugin();
await reinstallEditedCode();

if (configurationSource === 'block-attributes') {
let postId = 0;
Expand Down Expand Up @@ -363,7 +365,7 @@ function PlaygroundPreview({
const [transpilationFailures, setTranspilationFailures] = useState<
TranspilationFailure[]
>([]);
async function reinstallEditedPlugin() {
async function reinstallEditedCode() {
if (!playgroundClientRef.current || !codeEditor) {
return;
}
Expand All @@ -372,6 +374,7 @@ function PlaygroundPreview({

const client = playgroundClientRef.current;
let finalFiles = files;

if (codeEditorTranspileJsx) {
const { failures, transpiledFiles } = await transpilePluginFiles(
finalFiles
Expand All @@ -388,12 +391,17 @@ function PlaygroundPreview({
}
finalFiles = transpiledFiles;
}
await writePluginFiles(client, finalFiles);

if (codeEditorMode === 'theme') {
await writeThemeFiles(client, finalFiles);
} else {
await writePluginFiles(client, finalFiles);
}
}

const handleReRunCode = useCallback(() => {
async function doHandleRun() {
await reinstallEditedPlugin();
await reinstallEditedCode();

// Refresh Playground iframe
const lastPath = await playgroundClientRef.current!.getCurrentURL();
Expand All @@ -406,7 +414,7 @@ function PlaygroundPreview({
} else {
doHandleRun();
}
}, [reinstallEditedPlugin]);
}, [reinstallEditedCode]);

const keymapExtension = useMemo(
() =>
Expand Down Expand Up @@ -552,8 +560,9 @@ function PlaygroundPreview({
className="file-tab file-tab-extra"
onClick={() => {
if (playgroundClientRef.current) {
downloadZippedPlugin(
playgroundClientRef.current
downloadZippedPackage(
playgroundClientRef.current,
codeEditorMode
);
}
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { EditorFile } from '../../index';
import {
PlaygroundClient,
activateTheme,
// @ts-ignore
} from 'https://playground.wordpress.net/client/index.js';

export const writeThemeFiles = async (
client: PlaygroundClient,
files: EditorFile[]
) => {
const docroot = await client.documentRoot;
const themeFolderName = 'demo-theme';
const themePath = docroot + '/wp-content/themes/' + themeFolderName;
if (await client.fileExists(themePath)) {
await client.rmdir(themePath, {
recursive: true,
});
}
await client.mkdir(themePath);

for (const file of files) {
const filePath = `${themePath}/${file.name}`;
const parentDir = filePath.split('/').slice(0, -1).join('/');
await client.mkdir(parentDir);
await client.writeFile(filePath, file.contents);
}

try {
await activateTheme(client, {
themeFolderName,
});
} catch (e) {
console.error(e);
}
};
51 changes: 38 additions & 13 deletions packages/wordpress-playground-block/src/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useState, useRef } from '@wordpress/element';
import {
ToggleControl,
SelectControl,
RadioControl,
TextareaControl,
Panel,
PanelBody,
Expand Down Expand Up @@ -143,6 +144,8 @@ export default withBase64Attrs(function Edit({
requireLivePreviewActivation,
} = attributes;

const showJSXTranspileOption = codeEditorMode === 'plugin';

return (
<div {...useBlockProps()}>
<PlaygroundPreview
Expand Down Expand Up @@ -222,21 +225,43 @@ export default withBase64Attrs(function Edit({
});
}}
/>
<ToggleControl
label={__('Transpile JSX to JS')}
help={__(
`Transpiles JSX syntax to JS using esbuild. Only the JSX tags are ` +
`transpiled. Imports and other advanced ES module syntax features are ` +
`preserved.`
)}
checked={codeEditorTranspileJsx}
onChange={() => {
setAttributes({
codeEditorTranspileJsx:
!codeEditorTranspileJsx,
});
<RadioControl
label="Code editor mode"
selected={codeEditorMode}
options={[
{ label: 'Plugin', value: 'plugin' },
{ label: 'Theme', value: 'theme' },
]}
onChange={(value) => {
if (value === 'theme') {
setAttributes({
codeEditorMode: value,
codeEditorTranspileJsx: false,
});
} else {
setAttributes({
codeEditorMode: value,
});
}
}}
/>
{showJSXTranspileOption && (
<ToggleControl
label={__('Transpile JSX to JS')}
help={__(
`Transpiles JSX syntax to JS using esbuild. Only the JSX tags are ` +
`transpiled. Imports and other advanced ES module syntax features are ` +
`preserved.`
)}
checked={codeEditorTranspileJsx}
onChange={() => {
setAttributes({
codeEditorTranspileJsx:
!codeEditorTranspileJsx,
});
}}
/>
)}
<ToggleControl
label={__('Multiple files')}
help={
Expand Down

0 comments on commit 2423859

Please sign in to comment.