Planeta

  • Nuno Mariz

    Smallr

    Por nmariz, em 22 Novembro 2007 18:51 - Mais entradas deste utilizador
    small.net
    I've just released smallr. It lets you generate small web addresses with a keyword that make it easy to remember, will not break in emails and will never expire.
    Basically is a TinyURL clone, with a keyword addon.
    There will be an API for webservices with JSON and XML, eventually a Firefox extension.
    Test it and send me some feedback.
    I hope you enjoy it.
  • Pedro Lima

    To manage the website content in a flexible way it's practical to have some portions of some pages generated from variables created as FlatPages. For example, in a frontpage I have a "featured item" section which renders a flatpage variable.

    def frontpage(request):
        fp = FlatPage.objects.get(url='featured')
        return render_to_response('frontpage.html', {'fp':fp })
    
    then in the template
    ...<div id="featured">{{ fp.content }}</div> ...
    

    But sometimes it would also be nice to put some template tags inside those flatpages. Django does not seem to provide a tag for such task (most probably because it can be a bad idea from the security point of view), but the ssi tag does exactly the same thing for files in the filesystem. Based on ssi, the code bellow defines a new tag that includes the content of a variable as a template.

    def do_templatevar(parser, token):
        bits = token.contents.split()
        if len(bits) != 2:
            raise TemplateSyntaxError, "%s tag takes one argument" % bits[0]
        return TemplateVarNode(parser.compile_filter(bits[1]))
    
    register.tag('templatevar', do_templatevar)
    
    class TemplateVarNode(Node):
        def __init__(self, content):
            self.content = content
    
        def render(self, context):
            content = self.content.resolve(context)
            try:
                t = Template(content)
                return t.render(context)
            except TemplateSyntaxError, e:
                if settings.DEBUG:
                    return "[Included template had syntax error: %s]" % e
                else:
                    return '' # Fail silently
    

    Now I can put the following code in my flat page

    <p>This is my media_url: {{ MEDIA_URL }}</p>
    

    And it will work if I define my template as

    ...<div id="featured">{% templatevar fp.content %}</div> ...
    

    A last remark to mention databasetemplateloader that allows to load template data from the database. I never tried it, but seems to be a more generic solution (and also a way to have a Zope 1 experience in Django).

  • Pedro Lima

    To manage the website content in a flexible way it's practical to have some portions of some pages generated from variables created as FlatPages. For example, in a frontpage I have a "featured item" section which renders a flatpage variable.

    def frontpage(request):
        fp = FlatPage.objects.get(url='featured')
        return render_to_response('frontpage.html', {'fp':fp })
    
    then in the template
    ...<div id="featured">{{ fp.content }}</div> ...
    

    But sometimes it would also be nice to put some template tags inside those flatpages. Django does not seem to provide a tag for such task (most probably because it can be a bad idea from the security point of view), but the ssi tag does exactly the same thing for files in the filesystem. Based on ssi, the code bellow defines a new tag that includes the content of a variable as a template.

    def do_templatevar(parser, token):
        bits = token.contents.split()
        if len(bits) != 2:
            raise TemplateSyntaxError, "%s tag takes one argument" % bits[0]
        return TemplateVarNode(parser.compile_filter(bits[1]))
    
    register.tag('templatevar', do_templatevar)
    
    class TemplateVarNode(Node):
        def __init__(self, content):
            self.content = content
    
        def render(self, context):
            content = self.content.resolve(context)
            try:
                t = Template(content)
                return t.render(context)
            except TemplateSyntaxError, e:
                if settings.DEBUG:
                    return "[Included template had syntax error: %s]" % e
                else:
                    return '' # Fail silently
    

    Now I can put the following code in my flat page

    <p>This is my media_url: {{ MEDIA_URL }}</p>
    

    And it will work if I define my template as

    ...<div id="featured">{% templatevar fp.content %}</div> ...
    

    A last remark to mention databasetemplateloader that allows to load template data from the database. I never tried it, but seems to be a more generic solution (and also a way to have a Zope 1 experience in Django).

  • Pedro Lima

    Boxes as template tags

    Por pvl, em 26 Setembro 2007 00:00 - Mais entradas deste utilizador

    With CSS it's very simple to do the markup of a square box. But to make those popular boxes with round corners most approaches use nested divs. For a flexible size box the following markup is typical:

    <div class="box">
      <div class="box-outer">
        <div class="box-inner">
          <h2>Headline</h2>
          <p>Content</p>
        </div>
      </div>
    </div>
    

    It's a bad idea to repeat this code all over the templates. So a template tag can be a good option. The kind of template that would be interesting to have is one that outputs the boilerplate divs given the headline and the content. Something like:

    {% menubox "Box title here" %}
        <p>Content here</p>
    {% endmenubox %}
    

    Django makes the writing of this tag very easy and the documentation is very clear. Bellow is the result for such tag.

    from django.template import Library, Node, TemplateSyntaxError
    
    register = Library()
    
    def do_menubox(parser, token):
        nodelist = parser.parse(('endmenubox',))
        parser.delete_first_token()
        try:
            tag_name, title = token.split_contents()
        except ValueError:
            raise TemplateSyntaxError, "%r tag requires exactly two arguments" % \
                  token.contents.split()[0]
        return MenuboxNode(nodelist, parser.compile_filter(title))
    
    class MenuboxNode(Node):
        
        def __init__(self, nodelist, title):
            self.nodelist = nodelist
            self.title = title
            
        def render(self, context):
            title = self.title.resolve(context)
            output = self.nodelist.render(context)
            return '''<div class="box"><div class="box-outer"><div 
    class="box-inner"><h2>%s</h2>%s</div></div></div>''' % (title, output)
    
    register.tag('menubox', do_menubox)
    

    Update: The tag now also works with variable names in the title. The following would output the value of titlevar as the title of the box

    {% menubox titlevar %}
        <p>Content here</p>
    {% endmenubox %}
    
  • Pedro Lima

    Boxes as template tags

    Por pvl, em 26 Setembro 2007 00:00 - Mais entradas deste utilizador

    With CSS it's very simple to do the markup of a square box. But to make those popular boxes with round corners most approaches use nested divs. For a flexible size box the following markup is typical:

    <div class="box">
      <div class="box-outer">
        <div class="box-inner">
          <h2>Headline</h2>
          <p>Content</p>
        </div>
      </div>
    </div>
    

    It's a bad idea to repeat this code all over the templates. So a template tag can be a good option. The kind of template that would be interesting to have is one that outputs the boilerplate divs given the headline and the content. Something like:

    {% menubox "Box title here" %}
        <p>Content here</p>
    {% endmenubox %}
    

    Django makes the writing of this tag very easy and the documentation is very clear. Bellow is the result for such tag.

    from django.template import Library, Node, TemplateSyntaxError
    
    register = Library()
    
    def do_menubox(parser, token):
        nodelist = parser.parse(('endmenubox',))
        parser.delete_first_token()
        try:
            tag_name, title = token.split_contents()
        except ValueError:
            raise TemplateSyntaxError, "%r tag requires exactly two arguments" % \
                  token.contents.split()[0]
        return MenuboxNode(nodelist, parser.compile_filter(title))
    
    class MenuboxNode(Node):
        
        def __init__(self, nodelist, title):
            self.nodelist = nodelist
            self.title = title
            
        def render(self, context):
            title = self.title.resolve(context)
            output = self.nodelist.render(context)
            return '''<div class="box"><div class="box-outer"><div 
    class="box-inner"><h2>%s</h2>%s</div></div></div>''' % (title, output)
    
    register.tag('menubox', do_menubox)
    

    Update: The tag now also works with variable names in the title. The following would output the value of titlevar as the title of the box

    {% menubox titlevar %}
        <p>Content here</p>
    {% endmenubox %}
    
  • Nuno Mariz
    Django on iPhone
  • Nuno Mariz
    Django on iPhone
  • Nuno Mariz
    The Web Server Gateway Interface (WSGI) is a standard interface between web server software and web applications written in Python. Having a standard interface makes it easy to use an application that supports WSGI with a number of different web servers.
    One implementation is wsgiref that was added to Python 2.5 Standard Library.
    Here is a simple web application that writes "Hello World":
    def index(environ, start_response):
        start_response("200 Ok", [('content-type', 'text/html')])
        return ['Hello World!']
    
    if __name__ == "__main__":
        from wsgiref.simple_server import make_server
        server = make_server(HOST, PORT, index)
        print 'Starting up HTTP server on port %i...' % PORT
        server.serve_forever()
    

    This is nice, but is not very useful for us, so lets add some kind of controller(or url dispatcher):
    from dispatcher import Dispatcher
    
    dispatcher = Dispatcher()
    dispatcher.add(r'^/$', 'views.index')
    dispatcher.add(r'^/hello/(?P<username>\w+)/$', 'views.hello')
    
    HOST = 'localhost'
    PORT = 8000
    
    if __name__ == "__main__": 
        from wsgiref.simple_server import make_server
        server = make_server(HOST, PORT, dispatcher)
        print 'Starting up HTTP server on port %i...' % PORT
        server.serve_forever()
    

    As you can see I've used a regular expression for the url mapping, just like Django uses.
    Here is the dispatcher(dispatcher.py):
    import re
    
    class Dispatcher(object):
        def __init__(self, handle404 = None):
            self.urls = dict()
            self.request_path = ''
            if handle404:
                self.handle404 = handle404
            else:
                self.handle404 = self._404
    
        def __call__(self, environ, start_response):
            self.request_path = environ.get('PATH_INFO', '')
            for url in self.urls:            
                regex = re.compile(url)
                if regex.match(self.request_path):
                    m = regex.match(self.request_path)                        
                    mod_name, func_name = self._get_mod_func(self.urls[url])                
                    try:
                        callback = getattr(__import__(mod_name, {}, {}, ['']), func_name)
                    except ImportError, e:
                        raise Exception, "Could not import %s. Error was: %s" % (mod_name, str(e))
                    except AttributeError, e:
                        raise Exception, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))                
                    args = (environ, start_response)
                    kwargs = dict()                
                    for i in regex.groupindex:
                        kwargs[i] = m.group(i)
                    # Run callback with environ, start_response and args
                    return callback(*args, **kwargs)
            # No match with the defined urls
            return self.handle404(environ, start_response)
                
        def _get_mod_func(self, callback):
            """
            Converts 'path.to.module.funtion' to ['path.to.module', 'function']
            """
            try:
                d = callback.rindex('.')
            except ValueError:
                return callback, ''
            return callback[:d], callback[d+1:]
        
        def _404(self, environ, start_response):
            start_response("404 Not Found", [('content-type', 'text/html')])
            return ['Not Found']
    
        def add(self, regex, handler):
            self.urls[regex] = handler
    

    And here is the views(views.py):
    def index(environ, start_response):
        start_response("200 Ok", [('content-type', 'text/html')])
        return ['Index']
    
    def hello(environ, start_response, username):
        start_response("200 Ok", [('content-type', 'text/html')])
        return ['Hello %s' % username]
    

    Simple eh?
    This is just a start, now we can add more features, like encapsulate the start_response method and add some kind of HttpResponse.
    I don't what do reinvent the wheel here and add another web framework to Python, just like Joe Gregorio says in this article. But to prove how trivial is to make a simple framework with WSGI and don't worry about the deployment at development phase.
  • Nuno Mariz
    The Web Server Gateway Interface (WSGI) is a standard interface between web server software and web applications written in Python. Having a standard interface makes it easy to use an application that supports WSGI with a number of different web servers.
    One implementation is wsgiref that was added to Python 2.5 Standard Library.
    Here is a simple web application that writes "Hello World":
    def index(environ, start_response):
        start_response("200 Ok", [('content-type', 'text/html')])
        return ['Hello World!']
    
    if __name__ == "__main__":
        from wsgiref.simple_server import make_server
        server = make_server(HOST, PORT, index)
        print 'Starting up HTTP server on port %i...' % PORT
        server.serve_forever()
    

    This is nice, but is not very useful for us, so lets add some kind of controller(or url dispatcher):
    from dispatcher import Dispatcher
    
    dispatcher = Dispatcher()
    dispatcher.add(r'^/$', 'views.index')
    dispatcher.add(r'^/hello/(?P<username>\w+)/$', 'views.hello')
    
    HOST = 'localhost'
    PORT = 8000
    
    if __name__ == "__main__": 
        from wsgiref.simple_server import make_server
        server = make_server(HOST, PORT, dispatcher)
        print 'Starting up HTTP server on port %i...' % PORT
        server.serve_forever()
    

    As you can see I've used a regular expression for the url mapping, just like Django uses.
    Here is the dispatcher(dispatcher.py):
    import re
    
    class Dispatcher(object):
        def __init__(self, handle404 = None):
            self.urls = dict()
            self.request_path = ''
            if handle404:
                self.handle404 = handle404
            else:
                self.handle404 = self._404
    
        def __call__(self, environ, start_response):
            self.request_path = environ.get('PATH_INFO', '')
            for url in self.urls:            
                regex = re.compile(url)
                if regex.match(self.request_path):
                    m = regex.match(self.request_path)                        
                    mod_name, func_name = self._get_mod_func(self.urls[url])                
                    try:
                        callback = getattr(__import__(mod_name, {}, {}, ['']), func_name)
                    except ImportError, e:
                        raise Exception, "Could not import %s. Error was: %s" % (mod_name, str(e))
                    except AttributeError, e:
                        raise Exception, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))                
                    args = (environ, start_response)
                    kwargs = dict()                
                    for i in regex.groupindex:
                        kwargs[i] = m.group(i)
                    # Run callback with environ, start_response and args
                    return callback(*args, **kwargs)
            # No match with the defined urls
            return self.handle404(environ, start_response)
                
        def _get_mod_func(self, callback):
            """
            Converts 'path.to.module.funtion' to ['path.to.module', 'function']
            """
            try:
                d = callback.rindex('.')
            except ValueError:
                return callback, ''
            return callback[:d], callback[d+1:]
        
        def _404(self, environ, start_response):
            start_response("404 Not Found", [('content-type', 'text/html')])
            return ['Not Found']
    
        def add(self, regex, handler):
            self.urls[regex] = handler
    

    And here is the views(views.py):
    def index(environ, start_response):
        start_response("200 Ok", [('content-type', 'text/html')])
        return ['Index']
    
    def hello(environ, start_response, username):
        start_response("200 Ok", [('content-type', 'text/html')])
        return ['Hello %s' % username]
    

    Simple eh?
    This is just a start, now we can add more features, like encapsulate the start_response method and add some kind of HttpResponse.
    I don't what do reinvent the wheel here and add another web framework to Python, just like Joe Gregorio says in this article. But to prove how trivial is to make a simple framework with WSGI and don't worry about the deployment at development phase.
  • Nuno Mariz
    If you are using PIL(Python Imaging Library) on Mac OS X(Tiger), you will probably have a "decoder jpeg not available" when resizing a jpeg image.
    This probably means that PIL doesn't have JPEG support, because libjpeg wasn't found when PIL was being configured.
    Here is the solution:
    • Download, compile and install jpeglib and zlib
    • Edit PIL setup.py and change to:
      JPEG_ROOT = "/usr/local/include"
      ZLIB_ROOT = "/usr/local/include"
      
    • Compile:
      python setup.py build_ext -i
      
    • Test:
      python selftest.py
      
    • If the result is something like this:
      "57 tests passed."
      
    • You are ready to go:
      python setup.py install