views:

47

answers:

1

I've got master.kid (simplified):

<html>
<head py:match="item.tag == 'head'">
  <title>My Site</title>
</head>
<body py:match="item.tag == 'body'">
  <h1>My Site</h1>
  <div py:replace="item[:]"></div>
  <p id="footer">Copyright Blixt 2010</p>
</body>
</html>

And mypage.kid:

<html>
<head></head>
<body>
  <p>Hello World!</p>
</body>
</html>

Now I want it to be possible to add more content before the </body> tag in the resulting HTML, specific to mypage.kid.

Basically the result should be something this:

<html>
<head>
  <title>My Site</title>
</head>
<body>
  <h1>My Site</h1>
  <p>Hello World!</p>
  <p id="footer">Copyright Blixt 2010</p>
  <script type="text/javascript">alert('Hello World!');</script>
</body>
</html>

The <script> tag should be specified in mypage.kid. It's okay if I have to modify master.kid to optionally support additional content before the </body> tag, but what the content is has to be specified in mypage.kid.

At first I figured adding an element before the </body> tag in master.kid with py:match="item.tag == 'bodyend'" would work. The problem is that it uses the position of the element in mypage.kid, and not the position of the element doing py:match. So if I put the <bodyend> tag before </body> in mypage.kid, it is imported before <p id="footer">, and if I put it below </body> it will stay there.

How do I set up master.kid and mypage.kid to support adding content immediately before the </body> tag?

+1  A: 

The best solution I've found is the following:

master.kid:

<html>
<head py:match="item.tag == 'head'">
  <title>My Site</title>
</head>
<body py:match="item.tag == 'body'">
  <h1>My Site</h1>
  <div py:replace="item[:]"></div>
  <p id="footer">Copyright Blixt 2010</p>
  <div py:if="defined('body_end')" py:replace="body_end()"></div>
</body>
</html>

mypage.kid:

<html>
<head></head>
<body>
  <p>Hello World!</p>
  <div py:def="body_end()" py:strip="True">
    <script type="text/javascript">alert('Hello World!');</script>
  </div>
</body>
</html>

The master.kid page checks for a variable defined as body_end, and if there is such a variable, it will call it, replacing the contents of the element before </body> (otherwise it will output nothing).

Any page that needs to output content before </body> will define the body_end function using py:def="body_end()". The py:strip="True" is there to remove the wrapping <div>.

Blixt