Skip to content
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

Interactive code examples on php.net #3259

Open
pronskiy opened this issue Mar 11, 2024 · 4 comments · May be fixed by php/web-php#1097
Open

Interactive code examples on php.net #3259

pronskiy opened this issue Mar 11, 2024 · 4 comments · May be fixed by php/web-php#1097

Comments

@pronskiy
Copy link
Contributor

Regarding the 3v4l integration. How about having iframe-embeddings for code examples from 3v4l.org? We could, in theory, run a separate instance of it if needed, at 3v4l.php.net for example.

Another idea is to use WASM binary first, as it probably would cover 80% of cases.

So the user interaction might look like this:

  • User opens a manual page with one or several code blocks.
  • Each code block is static until the user executes it or starts editing.
  • When the user clicks "run" button, behind the scenes the page loads WASM-based PHP to run example in a browser.
  • This WASM-bin is at this moment cached in the browser, so that all further interactions go smoothly.

In theory, both approaches could be used together. As in, all logic is implemented on 3v4l side, and loaded via iframe. In this case, such code examples could be used not only on php.net, but also on other PHP websites, blog posts, etc.

@SjonHortensius, @kamil-tekiela, @Girgias, what do you think?

@SjonHortensius
Copy link

wasm first would be a good idea as it would reduce the load as the input & results don't need to be stored and it is resistant to abuse - I agree it would probably cover most cases. It also matches the current setup of 3v4l with the "real-time" option checked by default.

A separate endpoint on 3v4l would be needed that would accept the code and generate the correct output (via wasm) and include a "run on 3v4l" button. This would remove the needs to pre-store all examples on 3v4l and store the script-short code in the docs somewhere.
I'd prefer the layout of this to be less focused on the '3v4' button (than the current layout) as it would take users away from the docs and submit the script to the server for processing in all versions - which this integration doesn't focus on

@Jeckerson
Copy link

Jeckerson commented Apr 22, 2024

There is already OSS project, which uses WebAssembly:

Repository: https://github.com/seanmorris/php-wasm
Demo: https://seanmorris.github.io/php-wasm/

@pronskiy
Copy link
Contributor Author

Many projects are doing that, e.g. https://github.com/WordPress/wordpress-playground.

3v4l.org also already implements that capability. See the Live preview checkbox in the right-bottom corner.

Ideally, I envision being able to embed 3v4l.org snippets on the php.net page such that they initially appear static. Then, upon clicking, they load php-wasm behind the scenes, making the example editable.

@SjonHortensius
Copy link

I have a POC ready - I went with iframes for the initial version. I implemented window.postMessage and allowed php.net as frame-ancestors in the csp. This allows an external domain to embed 3v4l and supply the initial code for the editor.

example of integration:

<!-- straight from the PHP manual -->
<p><strong>Example #1 Using a negative <code class="parameter" style="cursor: pointer;">offset</code></strong></p>
<div class="example-contents">
    <div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br>$rest </span><span style="color: #007700">= </span><span style="color: #0000BB">substr</span><span style="color: #007700">(</span><span style="color: #DD0000">"abcdef"</span><span style="color: #007700">, -</span><span style="color: #0000BB">1</span><span style="color: #007700">);    </span><span style="color: #FF8000">// returns "f"<br></span><span style="color: #0000BB">$rest </span><span style="color: #007700">= </span><span style="color: #0000BB">substr</span><span style="color: #007700">(</span><span style="color: #DD0000">"abcdef"</span><span style="color: #007700">, -</span><span style="color: #0000BB">2</span><span style="color: #007700">);    </span><span style="color: #FF8000">// returns "ef"<br></span><span style="color: #0000BB">$rest </span><span style="color: #007700">= </span><span style="color: #0000BB">substr</span><span style="color: #007700">(</span><span style="color: #DD0000">"abcdef"</span><span style="color: #007700">, -</span><span style="color: #0000BB">3</span><span style="color: #007700">, </span><span style="color: #0000BB">1</span><span style="color: #007700">); </span><span style="color: #FF8000">// returns "d"<br></span><span style="color: #0000BB">?&gt;</span></span></code></div>
</div>

<button type="button" class="run-code-on-3v4l">try it</button>

<script>
    // receives updates on status of execution
    window.addEventListener('message', (event) => {
        if (event.origin !== 'https://3v4l.org') return;

        switch (event.data) {
            case 'busy':
            case 'done':
                alert('script code is '+ event.data);
            break;
        }
    }, false);

    document.querySelectorAll('.run-code-on-3v4l').forEach(function (el) {
        el.addEventListener('click', function() {
            var i;
            //FIXME detect if an iframe has already been opened for this el
            if (true) {
                i = document.createElement('iframe');
                i.classList.add('3v4l-live');

                i.src = 'https://3v4l.org/#live';
                el.after(i);
            }

            i.addEventListener('load', (e) => {
                //FIXME make me dynamic
                var code = document.querySelectorAll('.example-contents')[0].innerText;
                i.contentWindow.postMessage(document.querySelectorAll('.example-contents')[0].textContent, 'https://3v4l.org');
            });
        });
    });
</script>

proposed change on the server side (not in production yet): SjonHortensius/3v4l_org@4137692

Additionally, I wouldn't mind documenting how to integrate the WASM binary from 3v4l directly - but the inline editing capabilities will have to be added by someone else.

@soyuka soyuka linked a pull request Oct 16, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants