Using Spyce

If you are looking for a way to embed Python within HTML you might want to take a look at a web environment called Spyce. Two of its advantages are its features and its flexibility. Keep reading to learn how you can Spyce up your programs.

Introduction

The idea of “Python Server Pages” is nothing new or unique to one particular web environment. It’s an idea that is featured in several environments, including mod_python and Karrigell. However, while mod_python and Karrigell don’t completely focus on embedding Python within HTML, a web environment named Spyce does. Spyce allows for Python to be embedded, but it also contains a few more tricks when it comes to embedding, such as active tags. Moreover, the fact that Spyce can be used with several technologies with minimal configuration is a huge advantage. In this article, we’ll take a look at how Spyce is configured and what it offers.

Installing Spyce

Spyce can be obtained at SourceForge:

http://sourceforge.net/project/showfiles.php?group_id=53655

Simply download the archive and extract it to a directory that’s easily accessible.

Spyce can be installed in numerous ways, which is convenient since you probably won’t have to change the face of your existing environment in order to benefit from Spyce. You may choose to run Spyce as its own web server, which can run behind Apache, or you can use FastCGI, mod_python or plain old CGI. Spyce already comes with configuration directives that can be slightly modified and then used with Apache.

To run Spyce as its own web server, open the directory where you extracted spyce and run the file spiceCmd.py with the “-l” flag:

spyceCmd.py -l

Spyce is configured to run on port 8000 by default. If you wish to have Spyce listen to a different port, open the file spyceconf.py and change the port variable.

The remaining installation options require spyceApache.conf to be modified. Open it up and replace “XXX” with the directory to where you extracted Spyce. The file contains configuration directives for running Spyce behind Apache, running Spyce with FastCGI or CGI and running Spyce through mod_python. Simply uncomment the appropriate section of the file and make sure that all other sections are commented. Next, make a copy of spyceApache.conf and drop it in the conf directory of your Apache installation. Open up Apache’s httpd.conf and add this directive to the end:

Include conf/spyceApache.conf

Spyce should now be configured to work with your method of choice.

{mospagebreak title=Basic Syntax}

Let’s start with a form example to learn the basics of Spyce. Create a file called form.spy and place it in either Spyce’s www directory if you are using the Spyce web server or somewhere in Apache if you are not. We’ll start off with some simple HTML to describe the layout of the form:

<html>
   <head>
      <title>Profile</title>
   </head>
   <body>
       <form method=’POST’>
       First Name: <input type=’text’ name=’first’ /><br />
       Last Name: <input type=’text’ name=’last’ /><br />
       E-Mail: <input type=’text’ name=’email’ /><br />
       <input type=’submit’ value=’Submit Information’ />
       </form>
   </body>
   </head>
</html>

At the basis of your Spyce documents, assuming that you are using Spyce for embedding Python within HTML (it can be used for other purposes), will be your plain old vanilla HTML document. With Spyce, however, we are able to add functionality to the mix by using special tags. Let’s add a Spyce comment to the file:

[[-- Just a simple profile/personal information form --]]
<html>
   <head>
      <title>Profile</title>
   </head>
   <body>
       <form method=’POST’>
       First Name: <input type=’text’ name=’first’ /><br />
       Last Name: <input type=’text’ name=’last’ /><br />
       E-Mail: <input type=’text’ name=’email’ /><br />
       <input type=’submit’ value=’Submit Information’ />
       </form>
   </body>
   </head>
</html>

If you request the file, you’ll see that the comment is not displayed. Obviously, this is the proper behavior of comments. Next come statements, which, as their name suggests, are made of Python statements. Brackets can be used where indentation afterward would normally be required, such as a conditional statement. We’ll use a conditional statement to determine whether the form has been submitted or not:

[[-- Just a simple profile/personal information form --]]
[[ if request.post('first', None): { ]]
[[-- The form has been submitted --]]
[[ } else: { ]]
<html>
   <head>
      <title>Profile</title>
   </head>
   <body>
       <form method=’POST’>
       First Name: <input type=’text’ name=’first’ /><br />
       Last Name: <input type=’text’ name=’last’ /><br />
       E-Mail: <input type=’text’ name=’email’ /><br />
       <input type=’submit’ value=’Submit Information’ />
       </form>
   </body>
   </head>
</html>
[[ } ]]

We make use of the request module here, which can be accessed from every Spyce script. We use post to check whether a variable named first has been passed via the “POST” method. If it has, the value is returned inside a list, which equates to True. If it hasn’t, we set the default as None, which equates to False.

Next up are Python chunks, which simply contain sections of Python code. We’ll use one in our script to set variables for the form data:

[[-- Just a simple profile/personal information form --]]
[[ if request.post('first', None): { ]]
[[
first = request.post('first')[0]
last = request.post(‘last’)[0]
name = first + ‘ ‘ + last
email = request.post(‘email’)[0]
]]
[[ } else: { ]]
<html>
   <head>
      <title>Profile</title>
   </head>
   <body>
       <form method=’POST’>
       First Name: <input type=’text’ name=’first’ /><br />
       Last Name: <input type=’text’ name=’last’ /><br />
       E-Mail: <input type=’text’ name=’email’ /><br />
       <input type=’submit’ value=’Submit Information’ />
       </form>
   </body>
   </head>
</html>
[[ } ]]

The last instruction we’ll use in our script is an expression, which simply displays the end result of a particular Python expression. We’ll use it to display the information back to the user:

[[-- Just a simple profile/personal information form --]]
[[ if request.post('first', None): { ]]
[[
first = request.post('first')[0]
last = request.post(‘last’)[0]
name = first + ‘ ‘ + last
email = request.post(‘email’)[0]
]]
Name: [[=name]]<br />
E-Mail: [[=email]]
[[ } else: { ]]
<html>
   <head>
      <title>Profile</title>
   </head>
   <body>
       <form method=’POST’>
       First Name: <input type=’text’ name=’first’ /><br />
       Last Name: <input type=’text’ name=’last’ /><br />
       E-Mail: <input type=’text’ name=’email’ /><br />
       <input type=’submit’ value=’Submit Information’ />
       </form>
   </body>
   </head>
</html>
[[ } ]]

Our script is now complete. Try running and modifying it.

{mospagebreak title=Active Tags}

Spyce packs a few more features when it comes to embedding code. An interesting feature worth looking at is active tags, which are tags that basically take the place of Python code or other text, passing the code part off to a module. This can cut development time and reduce clutter in Spyce files, among other things. In my opinion, active tags are best understood if you skip the prose details and jump right into an example. First, let’s define a few tags in color.spi:

[[.tagcollection]]

[[.begin name=red buffers=True]]
<span style=’color: red;’>[[=_content]]</span>
[[.end]]

[[.begin name=green buffers=True]]
<span style=’color: darkgreen;’>[[=_content]]</span>
[[.end]]

[[.begin name=blue buffers=True]]
<span style=’color: blue;’>[[=_content]]</span>
[[.end]]

Before we continue, notice that most of the above Spyce commands come in a “[[.X]]” structure. These are called Spyce directives, and they are used to communicate with Spyce. Here, we use it to declare the file to be a tag collection and then to describe individual tags. Let’s now put the above tags to use in colortest.spy:

[[.taglib from=color.spi as=color]]
<color:red>Red</color:red><br />
<color:green>Green</color:green><br />
<color:blue>Blue</color:blue>

When you run colortest.spy, active tags should start to make sense. In color.spi, we defined three tags, red, green and blue. Notice how we set buffers to True. This allows us to access the content inside the tags with _content. In colortest.spy, _content is “Red”, “Green” and then “Blue”.

Active tags can also access attributes. Say, for example, that we want to define a tag that allows a custom color to be set through an attribute. We could add this definition on to color.spi:

[[.begin name=cust buffers=True]]
[[.attr name=code default='#000000']]
<span style=’color: [[=code]];’>[[=_content]]</span>
[[.end]]

Here’s the new tag in action:

[[.taglib from=color.spi as=color]]
<color:cust code=’goldenrod’>goldenrod</color:cust>

There are some situations where a tag will not come in pairs. For example, let’s say we wanted to add an information tag to color.spi. This is how it would be done:

[[.begin name=information singleton=True]]
Color Tag Collection<br />
red — displays text in red<br />
green — displays text in green<br />
blue — displays text in blue<br />
cust — displays text in the color specified in the code attribute<br />
[[.end]]

It’s also possible to create active tags from Python classes. Using this method, we can duplicate color.spi as color.py:

import spyceTag

def genColorTag(color):

   class color(spyceTag.spyceTagPlus):

      name = color
      buffer = True

      def syntax(self):
         self.syntaxPairOnly()
      def begin(self):
         self.getOut().write(“<span style=’color: red;’>”)
      def body(self, _content):
         self.getOut().write(_content)
      def end(self):
         self.getOut().write(“</span>”)

   return color

red = genColorTag(‘red’)
green = genColorTag(‘green’)
blue = genColorTag(‘blue’)

class cust(spyceTag.spyceTagPlus):

   name = ‘cust’
   buffer = True

   def syntax(self):
      self.syntaxPairOnly()
   def body(self, _content):
      if self._attrs.has_key(‘code’):
         code = self._attrs['code']
      else:
         code = ‘#000000′
      self.getOut().write(“<span style=’color: %s;’>%s</span>” %
(code, _content))

class information(spyceTag.spyceTagPlus):

   name = ‘information’

   def syntax(self):
      self.syntaxSingleOnly()
   def body(self, _content):
      self.getOut().write(“Color Tag Collection<br />”)
      self.getOut().write(“red — displays text in red<br />”)
      self.getOut().write(“green — displays text in
green<br />”)
      self.getOut().write(“blue — displays text in blue<br />”)
      self.getOut().write(“cust — displays text in the color
specified in the code attribute<br />”)

class color(spyceTag.spyceTagLibrary):
   tags = [red, green, blue, cust, information]

Creating a tag library in Python can take more effort, but it’s pretty straight-forward. We start off by generating the classes red, blue and green from the genColorTag function. The classes are subclasses of spyceTag.spyceTagPlus. Notice how we use the syntaxPairOnly method to indicate that the tag should come in a pair. Next, we create the cust tag. In the first three classes, we split the HTML generation between begin, body and end, but in cust, we do it all in body. There’s no reason why everything just can’t go in body to begin with, but I want to acknowledge the other two methods. Then, we create the information class, making sure to call syntaxSingleOnly. Finally, we create a color class and list all our tags in it.

{mospagebreak title=Handling Form Data}

Spyce contains a few methods that deal with handling form data. You’ve already seen one of them briefly, but let’s take a look at some more of them:

[[
import random
methods = [request.get, request.get1, request.post, request.post1,
           request.getpost, request.getpost1, request.postget, request.postget1]
genList = [[spy! method:
   <b>[[=str(method).replace('<', '&lt;')]]</b><br />
   [[ for field in ('A','B','C'): { ]]
      [[=field]]: [[=method(field)]]<br />
   [[ } ]]
   <br />]]
]]

[[-- Handle processing --]]
[[ if request.getpost1('A', None): { ]]
   [[ for method in methods: { ]]
      [[ genList(method) ]]
   [[ } ]]
[[ } ]]

[[-- The actual form --]]
<form method=’[[=random.choice(['POST', 'GET'])]]’>
A: <input type=’text’ name=’A’ /><br />
B: <input type=’text’ name=’B’ /><br />
C: <input type=’text’ name=’C’ /><br />
<input type=’submit’ value=’Submit’ />
</form>

The script above sends form data through either the “GET” or “POST” methods randomly, and then it displays the results of several of Spyce’s methods, which are listed in the methods list. Below that, we define getList. Notice, however, that getList deals with Spyce itself. The “[[!spy X]]” structure simply defines a function that can be accessed later. In this case, it’s a function that calls a method with either “A”, “B” or “C” as an argument—our field names. Later in the script, we call this function with each item in methods. Observe what each method returns, and observe what happens when “GET” and “POST” data are mixed.

Conclusion

Spyce has a lot to offer to web developers and developers looking for dynamic content in general. One of its main advantages is that it can work alone, with Apache, with mod_python, with FastCGI or with CGI without any major modifications. If one method is not available to you, there’s always more to fall back on. It offers several tags that can be used for unique purposes, and it offers a way for developers to save time by using active tags. Of course, there are also plenty of others features of Spyce that cannot be covered in a single article. Spyce isn’t the only way of embedding Python code, but it is arguably the most feature-filled way.

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan