-
Scripts can be located anywhere.
Scripts can be located anywhere in the site hierarchy. Though not necessary, it's good practice to put all the scripts of one level in a single element. An abundance of code could all go in a single element file. It is not necessary to put each script in its own separate element. Like all elements, when a single element name defines elements at more than one level of a site, the deeper script element is the one used by the page.
- Scripts belong in code blocks.
A code block is a multiLineElement (see Glossary) whose name begins with the codeBlockMarker (see ElementsSettings). One code block may contain any number of Python functions. The name of an element containing scripts is not significant or used in any context. An element will be treated as code only if the element name begins with the codeBlockMarker.
Example:
#.oneCodeBlock#
def helloWorld:
return "Hello World"
#
- Scripts are valid Python code.
The entire multiLineElement is compiled and executed each time the code element appears in a page hierarchy. The code block must qualify for compilation or a warning will be generated and the entire block will be unavailable to pages. Python functions defined.
- Scripts must return a value.
If nothing is returned, the Python None object will be used, and "None" will appear on the page where the script was called. The returned value of each script is converted to StringType using the Python built-in str() operation.
- Scripts can reference elements.
A script can use element values simply by referencing the element as a variable by name.
#.code#
def displayFileName():
return fileName
#
fileName is an auto-generated element. All elements are available to scripts.
- Scripts use the "page" element for direct access to elements.
Each content file is processed in the context of an Elements.Page class instance. The "page" element is a reference to the page's own Page instance which contains the content and all elements for the page.
Each Page instance holds the names and values of all the page's elements in a Python dictionary named "elements". "page.elements" references the dictionary of elements. A script can reference any element using this notation:
page.elements["elementName"]
where elementName is the name of the element.
There are at least a few reasons to reference the page object and page.elements dictionary:
- when required to call an Internal Tool, like parseFile(page, f)
- when referencing elements whose names do not conform to the Python identifier rules (see below)
- to avoid declaring some element global. When using the page.elements["elementName"] notation, there is no need to declare global elementName in scripts which want to change the element value (See the globals section.)
- in a situation like the sample found at the bottom of the In-line Math example page where you have the element name as a string, not as a variable
- The page content is available in an element called pageString.
page.elements["pageContent"] references the content of the page in it's current state—the state it is in when the script is called. The pageContent is a list of strings. Each list item is a single line of content.
- Scripts must manage illegal element names.
Legal Python names may only contain letters, numbers and the underscore character ("_") and can not begin with a number. (See the docs.) However, the Elements application allows almost any string in element names. Scripts will be unable to reference Python-illegally named elements directly. Here are a few various ways to access the value of an illegally named element called "2002-03-17Story":
- s = page.elements['2002-03-17Story']
Use the page.elements[] notation.
- In the page hierarchy, define a second, legally named, element:
#pageContent {2002-03-17Story}
Then, in the script, reference the legal name.
s = pageContent
- s = "{2002-03-17Story}"
This is appropriate only for inserting the unexamined value in the page content, not if the script needs to process the value.
Note, there is nothing wrong or problematic in using element names which do not conform to Python naming rules beyond what is described here.
- Scripts can change and create elements using a "global" declaration.
Scripts can alter existing elements and create new elements by using the Python global declaration. For example, this script changes the value of "xyz" element and creates a new element named "pdq":
#xyz 2
#.code#
def sampleScript(s):
#declare globals
global xyz, pdq
# coerce to int, add 2
xyz = int(xyz) + 2
# instantiate new element
pdq = s
# always return something
return ""
#
There is no need to declare globals when using the page.elements[] notation.
- All single line elements are StringType.
The type of all single line elements is StringType, except for compiled scripts and the two comma delimited lists in ElementSettings.If a script needs to treat an element as a different type, the element value must be coerced to the proper Python type. (If x = "2", to convert x to the integer, use int(x).)
- All multiLineElements are ListType.
The type of multiLineElements (see Glossary) is ListType. Each item of the list is a string one line long. When using a multiLineElement in a script, you can cycle through the list items using standard list techniques or convert to a string. To convert a list element called "myElement" to a string, do this in the script:
s = string.join(myElement, '\n')
MultiLineElements are ListType to facilitate speedy string manipulations.
Before the script finishes, you can convert the element back to a list or leave it as a string with usually no noticeable slow down. Convert back to a list like so:
global myElement
myElement = string.split(myElement, '\n')
Be sure to declare the element "global" before converting it back to a list.
- Scripts can import Python modules.
These modules are already available in the script's global context: "os, sys, string, shutil, copy, time, types, webbrowser, exceptions". To use any other modules, scripts will need to use the Python import statement to make the module available.
To import modules which are not located in any of the standard locations for Python modules, (e.g. ~/Python/Lib) place the module in the same path as the script which initiates the Elements process. Then, in one of the site code blocks, import the module.
- Simple scripts can be inline.
{time.ctime()} --> Fri May 2 15:31:30 2003
{1+2} --> 3
- Scripts can be called in the name of an element.
e.g.
#.code#
def foo():
return 'bar'
#{foo()}_{fileName} 'blah'
results in a new element-->
#bar_scripts 'blah'
- Script comments start with "#".
Don't confuse the Elements elementMarker (see ElementsSettings) with the Python comment character. A "#" in a script begins a Python comment. Elements ships with "#" as the first character of an element declaration. They are unrelated objects that happen to use the same value.
The Python comment character cannot be changed. The Elements elementMarker can be changed in the ElementsSettings file.