tags:

views:

81

answers:

4

Hi, I'm using SHPAML (HAML for python) for Django, however, I'm facing problems converting SHPAML -> HTML because of whitespace issues when overriding some blocks, heres an example:

In skeleton.shpaml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
        <title>{{ title }}</title>

        {% comment %}
        <link rel="shortcut icon" href="/static/images/favicon.ico" type="image/x-icon"/>
        {% endcomment %}

        {% if css_list %}
            {% for css in css_list %}
            <link type="text/css" rel="stylesheet" href="{{css_relative}}{{ css }}">
            {% endfor %}
        {% endif %}

        {% if js_list %}
            {% for js in js_list %}
            <script type="text/javascript" src="{{js_relative}}{{ js }}">
            </script>
            {% endfor %}
        {% endif %}

        {% if no_cache %}
        <meta http-equiv="Pragma" content="no-cache" />
        <meta http-equiv="Cache-Control" content="no-cache" />
        {% endif %}

    </head>

    body
        #nonFooter
            #content
                {% block header %}&nbsp;{% endblock %}
            #maincontent
                {% block content %}&nbsp;{% endblock %}
        #footer
            &nbsp;

</html>

In index.shpaml:

{% extends "includes/skeleton.shpaml" %}
{% block content %}
asd
.test
    .test2 | meh
{% endblock %}

In the end, my output is this:

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
        <title>Home | Zineified</title>





            <link type="text/css" rel="stylesheet" href="/media/css/base.css">





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

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

            <script type="text/javascript" src="/media/js/base.js">
            </script>





    </head>

    body
        #nonFooter
            #content
                &nbsp;
            #maincontent

asd
.test
    .test2 | meh

        #footer
            &nbsp;

</html>

As you can see, whitespace is not preserved in the blocks. The next line in index.shpaml goes straight down into the next line in skeleton.shpaml. How can I prevent this and retain whitespace through template extending?

+1  A: 

from docs:

spaceless

Removes whitespace between HTML tags. This includes tab characters and newlines.

Example usage:

{% spaceless %}
    <p>
        <a href="foo/">Foo</a>
    </p>
{% endspaceless %}

This example would return this HTML:

<p><a href="foo/">Foo</a></p>

Only space between tags is removed -- not space between tags and text.

You can also remove excess spaces/newlines manually, but that will reduce the readability of the template.

Antony Hatchkins
This wouldn't work. This would mean that the template extending skeleton don't contain SHPAML code. And SHPAML code needs signficant whitespace. (SHPAML is essentially pythonic HTML, like HAML)
nubela
as far as I understand it will treat shpaml tags as plaintext and will retain all the formatting. Only html tags are affected
Antony Hatchkins
You are right on that, it does still treat shpaml tags as plaintext, however, it doesn't solve the problem of retaining whitespace when overriding the block content in skeleton.shpaml. I just tried it.
nubela
A: 
           #maincontent

asd

You mean misalignment here? Well, align your index.shpaml accordingly:

{% extends "includes/skeleton.shpaml" %}
{% block content %}
            asd
            .test
                .test2 | meh
{% endblock %}
Antony Hatchkins
+1  A: 

It looks like the SHPAML preprocessor is not getting invoked BEFORE Django. What I typically do is write all my documents in SHPAML with a .shpaml extension, and then I convert them to Django with the .html extension, and then let Django do its magic. So you will want statements like "extends" and "include" to refer to the .html document that has already been preprocessed.

Your base shpaml doc will look something like this:

html
    body
        #main_page
            {% block body %}
            {% endblock %}

And then the document that extends it will look something like this:

{% extends 'base.html' %}
{% block body %}
    p
        This is a paragraph about {{ book }}...
{% endblock %}

And then you want to preprocess them BEFORE Django sees them. I usually preprocess them with a Python script right before doing "manage.py runserver."

Steve Howell
A: 

I've wrote a simple script to recursively explore a directory and find all shpaml files and convert them to *.htm. Thought I'd share it:

#!/usr/bin/env python

#===============================================================================
# Recursively explore this entire directory, 
# and convert all *.shpaml files to *.htm files.
#===============================================================================

import shpaml
import os, glob

count = 0

def main():
    global count
    cwd = os.path.dirname(os.path.abspath(__file__))
    convert_and_iterate(cwd)
    print("Done. Converted "+str(count)+" SHPAML files.")

def convert_and_iterate(path):
    global count

    for file in glob.glob(os.path.join(path,'*.shpaml')):
        #getting generic name
        file_basename = os.path.basename(file)
        gen_name = os.path.splitext(file_basename)[0]

        #opening shpaml file and converting to html
        shpaml_file = open(file)
        shpaml_content = shpaml_file.read()
        html_content = shpaml.convert_text(shpaml_content)

        #writing to *.htm
        html_file = open(os.path.join(path,gen_name+".htm"),"w")
        html_file.write(html_content)

        #incrementing count
        count += 1

    #transverse into deeper directories
    dir_list = os.listdir(path)
    for possible_dir in dir_list:
        if os.path.isdir(os.path.join(path,possible_dir)): 
            convert_and_iterate(os.path.join(path,possible_dir))


if __name__ == "__main__":
    main()
nubela