scripts-to-footer icon indicating copy to clipboard operation
scripts-to-footer copied to clipboard

Question: Why not extract inline scripts to the footer too?

Open julkue opened this issue 9 years ago • 13 comments

When using plugins that require jQuery an exception (jQuery is not defined) will be thrown. This occurs because jQuery will be initialized after the inline scripts. The plugin offers the option to keep jQuery in the head. This solves the problem.

Actually this is against the sense of the plugin. I don't understand why the plugin doesn't extract inline scripts and places them after the other scripts?

julkue avatar Dec 13 '15 17:12 julkue

julmot,

Unfortunately, you can utilize any WP hook (usually wp_head) to insert scripts inline. Because any theme/plugin can do this at any hook, at any priority, and using a unique function name, it's impossible to unilaterally remove inline scripts. That's one of the reasons the enqueue system is in place. All scripts should utilize the enqueue system (and, honestly, in-line scripts should check that dependent scripts are already printed before inserting inline scripts). See this support post.

As such, this plugin can only deal with scripts that are properly enqueued. One of the reasons I added the jQuery in the header (and the corresponding filter) was due to these issues.

Hope that answers your question, let me know if I can help in any other way.

Cheers, Joshua

joshuadavidnelson avatar Dec 14 '15 04:12 joshuadavidnelson

@joshuadavidnelson I didn't digged into this topic, so apologize for my unsuspectingness. Isn't it possible to just build a content gateway class, where all content must go through? Example:

ob_start();
// Wordpress ....
$content = ob_get_contents();
ob_end_clean();
// Strip all <script>-tags from $content and insert them before </body>

I can understand that it's not possible to catch scripts that aren't added with the enqueue functionality, but maybe there's another way to get around this?

julkue avatar Dec 14 '15 17:12 julkue

@julmot I suppose you could do something like this, but what would be the goal? Would you filter out all the script tags and collect them (in order?) to be printed in the footer? I'm open to ideas, but I'm hesitant to dramatically expand the scope of the plugin like this.

Filtering the site content to force the removal of script tags would be a sweeping change that could break all sorts of other items on sites. It's nearly impossible to unilaterally fix issues with inline scripts without knowledge of every plugin/theme with the issue (hence the option/filter to place jQuery and others in the head, which offers a quicker fix).

There's nothing necessarily bad about inline scripts, but it's likely most won't work if they are removed and then placed at the end, even if they are placed in the correct order. Those specific plugins/themes could re-write their inline scripts to work from the footer or wait until after jQuery is loaded to fire. I think the onus on this one should be placed on the developer of the theme/plugin(s) that break when you move jQuery to the footer.

I think you're venturing outside the scope of this plugin. This plugin is great for the one thing it does, but ultimately at a certain point script management on a site needs to be managed by the site developer.

joshuadavidnelson avatar Dec 14 '15 18:12 joshuadavidnelson

I can understand your worries and I can also not understand why plugin developers aren't using the built in functionalities to resolve dependencies correctly. However, what do you think will break when having such behavior?

julkue avatar Dec 14 '15 20:12 julkue

I'm not 100% sure what you mean with that last question. In-line scripts server a purpose for lots of things, from share buttons to forms to animations. The enqueuing process handles all assets linked in the head/footer of the document, but it isn't setup to handle scripting elsewhere in a theme. Certainly a plugin developer could check if the required script is already printed, or write their JavaScript to work after jQuery is loaded, regardless of it's location in the document.

That said, filtering the content to remove scripts would remove all scripts, right? How would it be implemented to not remove scripts that the user wanted to remain in the content (like code being featured in the content as an example, or inline scripts that work and can remain)? That would be incredibly complicated to institute so broadly in a plugin like Scripts to Footer, when each implementation will be unique. The best method is for the site developer to manage the inline-scripts as pertains to their site. Coupled with this plugin, which manages where script files are loaded.

joshuadavidnelson avatar Dec 14 '15 22:12 joshuadavidnelson

In my example you would place all scripts to the footer, regardless if they would work without jQuery. But as you mentioned, let's say someone just prints something with vanilla JS like

<script>document.write(new Date().getFullYear())</script>

then this would appear also at the bottom which is not as intended. But, this plugin is for developers. No blogger will care about where scripts are placed. You you can assume that developers will check the site and the theme before launching the page with this plugin. So I think if the plugin would move to the way I showed, nothing would crash. An idea would be to add another option to allow such behavior with hint about the side effects.

julkue avatar Dec 15 '15 09:12 julkue

I appreciate your conviction to this idea, but this plugin is used by more than just developers - I know of many production sites that run it (8,000+ installs according to WP.org stats). I think if there is enough interest for this as an added optional feature, we could explore that. However, I don't have time at the moment to develop it. I'd welcome pull requests, though!

joshuadavidnelson avatar Dec 15 '15 16:12 joshuadavidnelson

Sure I am a developer but have production sites too. This is not an exclusion criterion. The target group are developers. No blogger without being a developer will care about such issues IMHO.

I appreciate your openness. Do you have any idea how to get started to hook into WordPress that way?

julkue avatar Dec 17 '15 18:12 julkue

Ah, see, there would be the bigger issue. You could filter the_content, but that wouldn't grab anything placed/hooked into theme-specific templates (like sidebars, header/footer, etc). I'm not 100% sure off the top of my head what the best method would be to comb the output from those other sources, since it can vary depending on the theme. You could perhaps hook into wp_head to start the process, and again into wp_footer to finish it.

joshuadavidnelson avatar Dec 17 '15 18:12 joshuadavidnelson

In new year I will have a research about realizing such an issue. It will be interesting in general. Things like a pretty code print could use the same way and it would not be necessary to have a workaround like mine.

julkue avatar Dec 17 '15 18:12 julkue

Sounds good, I'm interested to see what you come up with. For sure, this would need to be an "developer-only" option. Thanks!

joshuadavidnelson avatar Dec 17 '15 18:12 joshuadavidnelson

Josh, I did a research about this at this weekend. Found this related topic: http://stackoverflow.com/a/22818089/3894981 Seems that this is what we are searching for. However, implementing this would make a plugin refactoring necessary. What do you think is the correct way to integrate it?

julkue avatar Feb 07 '16 10:02 julkue

That certainly looks promising. If we're going to add this functionality to the plugin, my preference would be to include it as an option. Perhaps either a check box on the settings page or a filter/constant that a developer would have to set. I wouldn't want to have this method active by default, not every user will need/want it.

That should be easy enough to add without drastic changes to the plugin structure.

joshuadavidnelson avatar Feb 07 '16 13:02 joshuadavidnelson