Skip to content
This repository has been archived by the owner on Oct 10, 2022. It is now read-only.

Add blocks-frontend.js for blocks frontend scripts #135

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

amjadr360
Copy link

Why we need blocks-frontend.js file and what problem it will solve?
To run scripts on front-end with src/blocks.js you can only run scripts in the admin area.

For example, I created testimonial carousel block to make carousel run in the admin area and on front-end I have to call the carousel js plugin both on front-end and backend.
image

That's why blocks-frontend.js file is necessary to be in the great toolkit.

Copy link
Contributor

@asharirfan asharirfan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @amjadr360

I just reviewed your pull request and a few issues need addressing.

Also, have you tested the changes in your local environment?

Cheers!

pluginDist: resolvePlugin( '.' ), // We are in ./dist folder already so the path '.' resolves to ./dist/.
yarnLockFile: resolvePlugin( 'yarn.lock' ),
appPath: resolvePlugin( '.' ),
// These properties only exist before ejecting:
ownPath: resolveOwn( '.' ),
};
// @remove-on-eject-end
// @remove-on-eject-end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that there is a blank line at the end of the file.

@@ -120,4 +121,4 @@ module.exports = {
// stats: 'errors-only',
// Add externals.
externals: externals,
};
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another blank line issue.

@@ -148,4 +149,4 @@ module.exports = {
// stats: 'errors-only',
// Add externals.
externals: externals,
};
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another blank line issue.

array(), // Dependencies, defined above.
// filemtime( plugin_dir_path( __DIR__ ) . 'dist/frontend.blocks.build.js' ), // Version: File modification time.
true // Enqueue the script in the footer.
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version parameter to this function is commented out, which makes the last one its version parameter which is a mistake. Please correct it.

For more information, check this link: https://developer.wordpress.org/reference/functions/wp_enqueue_script/

@ahmadawais
Copy link
Owner

Pretty sure adding a frontend je file will be a bad idea. Your code should look the same for both backend and frontend. Having separate code for both means you are doing it wrong just like we did in the classic editor.

I have not yet been convinced of why both frontend and backend code can't be the same.

@jedlikowski
Copy link

@ahmadawais that's true, but I wouldn't want to include the whole blocks.build.js file on the frontend just to make the block's dynamic functionality work on frontend. That's why a separate frontend file is needed to load only code required there.

@ahmadawais
Copy link
Owner

ahmadawais commented Mar 28, 2019 via email

@jedlikowski
Copy link

Let's use the example from the original comment:
On the backend you have the whole registerBlockType function with your block configuration, where in edit function you render the html and initialise the carousel's JS code.
However, the save method doesn't render components, it renders plain html. So on the frontend to make the carousel work you would need to enqueue a separate JS file which would initialize the carousel's dynamic functionality (switching slides).

I had a similar problem which is why I stumbled upon this pull request. I created a contact form block. It doesn't do anything on the backend, the edit method looks like this:

edit: () => <p>Contact form will appear here.</p>

And the save method renders an actual HTML form. On the frontend, I would like to load a JS file to handle form submit with AJAX. I could create a plain separate js file somewhere in the plugin and load this file. But what if I want this file to be built with webpack? This would require me to write a separate webpack config, install all dependencies, etc.

@amjadr360
Copy link
Author

Hi guys, I am agreed with @ahmadawais somehow.

blocks-frontend.js will work fine if the slider block has no options like autoplay: true; or nav: false; but what if each slider block has different options to initialize.
The solution to this problem is we can initialize javaScript to block with HTML like <div data-slider='{ "cellAlign": "left", "contain": true }'> or with inline javaScript.

And loading blocks-frontend.js on every page even that page does not have the block for that we are using blocks-frontend.js is waste of resources.

But we need a good method to fulfill our frontend needs. Like the dynamic block slider that renders in PHP.

Solution:
Import vendors javaScript (slider.js) file in dist/js/vendors directory then load slider.js using has_block() funcation to determine whether a $post contains a specific block.

@ahmadawais what is your opinion?

@ahmadawais
Copy link
Owner

@jedlikowski Exactly! That's where you are wrong. I don't want people to develop things like that. That's the wrong way. You must be thinking — what even am I talking about.

The thing is we moved away from the old editor because it was really hard to have "What You See is What You Get" in it. We built Gutenberg so that there will be no difference between the backend and the frontend. So, that in a couple of years there won't be a backend editor at all.

You'd build content at the frontend.

When you do something like this

edit: () => <p>Contact form will appear here.</p>

You are doing it wrong.

Your backend should be exactly like the frontend. That's why Gutenberg was built. That's why I chose not to add a frontend file in there — to inspire people in changing their mindset and to sort of enforcing "What You See is What You Get" probability.

It's why I have not merged this PR and haven't yet met a strong enough reason for separate frontend file.

@ahmadawais
Copy link
Owner

@amjadr360

Like the dynamic block slider that renders in PHP.

That's not what I would do. I would keep everything in JavaScript. I'll use PHP to create a new REST API endpoint and get data from that endpoint inside the JavaScript.

Stop thinking in PHP and start thinking wtih JavaScript otherwise adding JavaScript to WordPress is pretty much useless. You're basically trying to write another language in another language. That works for PHP → HTML and shouldn't work for PHP → JS.

Peace! ✌️

@jedlikowski
Copy link

@ahmadawais the edit function looks like this:

edit: () => <p>Contact form will appear here.</p>

only for simplicity. Of course I could render the whole contact form on the backend as well. This even would force me to extract the form rendering into an external module to not repeat the code.
But my main problem still exists, where would I place the JS code to handle form submit via AJAX? Add it inline to the rendered HTML?
I think it would be a better idea to load a separate JS file which would handle form submit. Now, where do I place this ajax code? I could create a JS file and load it alongside my block. But what if it's a more complex JS code which needs to be built by webpack. How do I go about it?
This problem could be generalised like this: what if given block requires JS code which needs to be built with webpack? How should such JS code be built and loaded?

@lkhedlund
Copy link

@ahmadawais Is there some misunderstanding about Gutenberg's functionality here?

You are doing it wrong.
Your backend should be exactly like the frontend. That's why Gutenberg was built. That's why I chose not to add a frontend file in there — to inspire people in changing their mindset and to sort of enforcing "What You See is What You Get" probability.
It's why I have not merged this PR and haven't yet met a strong enough reason for separate frontend file.

React doesn't load on the Wordpress frontend, so any functionality that uses React's capabilities wouldn't run by default. Gutenberg was built with the intention that your front-end functionality would follow older practices, it seems. I'm trying to get a handle on why we would load all of the backend Javascript (a great deal of which is unnecessary) rather than load in 'interaction JS' separately.

Thanks for considering my questions :). For what it's worth, we've just enqueued a separate, single JS file with some jQuery for the few blocks that need it.

@LyleBennett
Copy link

LyleBennett commented Jul 17, 2019

@ahmadawais I agree with you here and understand what you're trying to achieve. So I don't think it is necessary to push this.

But perhaps you could help us understand something that seems to boggle our minds based on what I'm thinking and reading?

If we want some sort of frontend .js functionality within our plugin (examples below) - what's the best way to implement this in the plugin? Is it possible to use the compiler to our advantage to achieve this? Or is it better to just

For what it's worth, we've just enqueued a separate, single JS file with some jQuery for the few blocks that need it.

?

Examples:
changing classes dynamically based on user interactions to create certain user experiences such as
accordions,
sliders,
carousels,
form validations and error messages

I know this solution has been suggested, which worked. Thoughts on this?

@doodirock
Copy link

Just following along but would really love to get some feed back on the last few questions posed here. I'm specifically having issues with:

If we want some sort of frontend .js functionality within our plugin (examples below) - what's the best way to implement this in the plugin? Is it possible to use the compiler to our advantage to achieve this?

Currently we have way to load js on the frontend that is required for client side interactions for blocks. The example of a form with AJAX is a great one.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants