Mojolicious, Layouts and Positioning of Javascript

2019-05-26 21:37发布

问题:

I want to load most of my scripts in my main layout ( i.e jquery). Now from my understanding it is best practice to position scripts at the bottom of my html page.

However if we put the script at the bottom of the layout page like so.

layout/default.html.ep

<!doctype html>

<html>
<head><title><%= title %></title></head>
<body><%=content %></body>
</html>
<script src="js/jquery.min.js" type="text/javascript"></script>    

And then use this layout in a page that has its own javascript that relies on jquery like so.

testscript.html.ep
%layout 'default';
%title 'Script Test';

<p>Main Page</p>

<script type="text/javascript">
$(document).ready(function(){
alert('fails if jquery is not loaded');  
});
</script>

You end up with a page like this. Notice that the reference to jquery is BELOW my code that relies on it.

<!doctype html>

<html>
<head><title>Script Test</title></head>
<body>
<p>Main Page</p>

<script type="text/javascript">
$(document).ready(function(){
alert('fails if jquery is not loaded');
});
</script>
<script src="js/jquery.min.js" type="text/javascript"></script>
</body>
</html>

What is the best way to deal with this situation?

Put my javascript references at the top of my layouts? I assume it's not best practice to add the script reference for jquery in every page that uses this layout?

Any help is much appreciated. I'm very much a new comer to all of this.

cheers.

回答1:

Sorry we missed this one, most of the people who use Mojolicious follow the Perl tag.

To answer your question, use the content_for helper to be able to place things where you want them. Note that this also lets you put the imports at the top of your dependent template, or the bottom if you prefer! I have an example below. I would also recommend a separate template for standard JS imports that all pages need, though this is just for clarity.

#!/usr/bin/env perl

use Mojolicious::Lite;

any '/' => 'testscript';

app->start;

__DATA__

@@ layouts/default.html.ep

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
  </head>
  <body>
    %= content
    %= include 'common_js'
    %= content_for 'js_imports'
  </body>
</html>

@@ common_js.html.ep
<script src="js/jquery.min.js" type="text/javascript"></script>

@@ testscript.html.ep
%layout 'default';
%title 'Script Test';

% content_for 'js_imports' => begin
  %= javascript begin
    $(document).ready(function(){
      alert('fails if jquery is not loaded');  
    });
  % end
% end

<p>Main Page</p>

When you visit the '/' route, this produces

<!DOCTYPE html>
<html>
  <head>
    <title>Script Test</title>
  </head>
  <body>


<p>Main Page</p>

    <script src="js/jquery.min.js" type="text/javascript"></script>

      <script>//<![CDATA[

    $(document).ready(function(){
      alert('fails if jquery is not loaded');  
    });

//]]></script>
  </body>
</html>