Split up docs.

This commit is contained in:
andrey
2002-02-26 21:13:54 +00:00
parent ca2042cb95
commit 6de35bae1f
9 changed files with 7199 additions and 0 deletions

411
docs/appendixes.sgml Normal file
View File

@@ -0,0 +1,411 @@
<part id="appendixes">
<title>Appendixes</title>
<chapter id="troubleshooting">
<title>Troubleshooting</title>
<para></para>
<sect1>
<title>Smarty/PHP errors</title>
<para>
Smarty can catch many errors such as missing tag attributes
or malformed variable names. If this happens, you will see an error
similar to the following:
</para>
<example>
<title>Smarty errors</title>
<programlisting>
Warning: Smarty: [in index.tpl line 4]: syntax error: unknown tag - '%blah'
in /path/to/smarty/Smarty.class.php on line 1041
Fatal error: Smarty: [in index.tpl line 28]: syntax error: missing section name
in /path/to/smarty/Smarty.class.php on line 1041</programlisting>
</example>
<para>
Smarty shows you the template name, the line number and the error.
After that, the error consists of the actual line number in the Smarty
class that the error occured.
</para>
<para>
There are certain errors that Smarty cannot catch, such as missing
close tags. These types of errors usually end up in PHP compile-time
parsing errors.
</para>
<example>
<title>PHP parsing errors</title>
<programlisting>
Parse error: parse error in /path/to/smarty/templates_c/index.tpl.php on line 75</programlisting>
</example>
<para>
When you encounter a PHP parsing error, the error line number will
correspond to the compiled PHP script, not the template itself. Usually
you can look at the template and spot the syntax error. Here are some
common things to look for: missing close tags for {if}{/if} or
{section}{/section}, or syntax of logic within an {if} tag. If you
can't find the error, you might have to open the compiled PHP file and
go to the line number to figure out where the corresponding error is in
the template.
</para>
</sect1>
</chapter>
<chapter id="tips">
<title>Tips & Tricks</title>
<para>
</para>
<sect1>
<title>Blank Variable Handling</title>
<para>
There may be times when you want to print a default value for an empty
variable instead of printing nothing, such as printing "&amp;nbsp;" so that
table backgrounds work properly. Many would use an {if} statement to
handle this, but there is a shorthand way with Smarty, using the
<emphasis>default</emphasis> variable modifier.
</para>
<example>
<title>Printing &amp;nbsp; when a variable is empty</title>
<programlisting>
{* the long way *}
{if $title eq ""}
&amp;nbsp;
{else}
{$title}
{/if}
{* the short way *}
{$title|default:"&amp;nbsp;"}</programlisting>
</example>
</sect1>
<sect1>
<title>Default Variable Handling</title>
<para>
If a variable is used frequently throughout your templates, applying
the default modifier every time it is mentioned can get a bit ugly. You
can remedy this by assigning the variable its default value with the
<link linkend="language.functions.assign">assign</link> function.
</para>
<example>
<title>Assigning a template variable its default value</title>
<programlisting>
{* do this somewhere at the top of your template *}
{assign var="title" value=$title|default:"no title"}
{* if $title was empty, it now contains the value "no title" when you print it *}
{$title}</programlisting>
</example>
</sect1>
<sect1>
<title>Passing variable title to header template</title>
<para>
When the majority of your templates use the same headers and footers, it
is common to split those out into their own templates and include them.
But what if the header needs to have a different title, depending on
what page you are coming from? You can pass the title to the header when
it is included.
</para>
<example>
<title>Passing the title variable to the header template</title>
<programlisting>
mainpage.tpl
------------
{include file="header.tpl" title="Main Page"}
{* template body goes here *}
{include file="footer.tpl"}
archives.tpl
------------
{config_load file="archive_page.conf"}
{include file="header.tpl" title=#archivePageTitle#}
{* template body goes here *}
{include file="footer.tpl"}
header.tpl
----------
&lt;HTML&gt;
&lt;HEAD&gt;
&lt;TITLE&gt;{$title|default:"BC News"}&lt;/TITLE&gt;
&lt;/HEAD&gt;
&lt;BODY&gt;
footer.tpl
----------
&lt;/BODY&gt;
&lt;/HTML&gt;</programlisting>
</example>
<para>
When the main page is drawn, the title of "Main Page" is passed to the
header.tpl, and will subsequently be used as the title. When the
archives page is drawn, the title will be "Archives". Notice in the
archive example, we are using a variable from the archives_page.conf
file instead of a hard coded variable. Also notice that "BC News" is
printed if the $title variable is not set, using the
<emphasis>default</emphasis> variable modifier.
</para>
</sect1>
<sect1>
<title>Dates</title>
<para>
As a rule of thumb, always pass dates to Smarty as timestamps.
This allows template designers to use <link
linkend="date.format">date_format</link> for full control over date
formatting, and also makes it easy to compare dates if necessary.
</para>
<para>
NOTE: As of Smarty 1.4.0, you can pass dates to Smarty as unix
timestamps, mysql timestamps, or any date parsable by strtotime().
</para>
<example>
<title>using date_format</title>
<programlisting>
{$startDate|date_format}
OUTPUT:
Jan 4, 2001
{$startDate|date_format:"%Y/%m/%d"}
OUTPUT:
2001/01/04
{if $date1 < $date2}
...
{/if}</programlisting>
</example>
<para>
When using {html_select_date} in a template, The programmer will most
likely want to convert the output from the form back into timestamp
format. Here is a function to help you with that.
</para>
<example>
<title>converting form date elements back to a timestamp</title>
<programlisting>
// this assumes your form elements are named
// startDate_Day, startDate_Month, startDate_Year
$startDate = makeTimeStamp($startDate_Year,$startDate_Month,$startDate_Day);
function makeTimeStamp($year="",$month="",$day="")
{
if(empty($year))
$year = strftime("%Y");
if(empty($month))
$month = strftime("%m");
if(empty($day))
$day = strftime("%d");
return mktime(0,0,0,$month,$day,$year);
}</programlisting>
</example>
</sect1>
<sect1>
<title>WAP/WML</title>
<para>
WAP/WML templates require a php Content-Type header to be passed along
with the template. The easist way to do this would be to write a custom
function that prints the header. If you are using caching, that won't
work so we'll do it using the insert tag (remember insert tags are not
cached!) Be sure that there is nothing output to the browser before the
template, or else the header may fail.
</para>
<example>
<title>using insert to write a WML Content-Type header</title>
<programlisting>
// be sure apache is configure for the .wml extensions!
// put this function somewhere in your application, or in Smarty.addons.php
function insert_header() {
// this function expects $content argument
extract(func_get_arg(0));
if(empty($content))
return;
header($content);
return;
}
// your Smarty template _must_ begin with the insert tag example:
{insert name=header content="Content-Type: text/vnd.wap.wml"}
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"&gt;
&lt;!-- begin new wml deck --&gt;
&lt;wml&gt;
&lt;!-- begin first card --&gt;
&lt;card&gt;
&lt;do type="accept"&gt;
&lt;go href="#two"/&gt;
&lt;/do&gt;
&lt;p&gt;
Welcome to WAP with Smarty!
Press OK to continue...
&lt;/p&gt;
&lt;/card&gt;
&lt;!-- begin second card --&gt;
&lt;card id="two"&gt;
&lt;p&gt;
Pretty easy isn't it?
&lt;/p&gt;
&lt;/card&gt;
&lt;/wml&gt;</programlisting>
</example>
</sect1>
<sect1 id="tips.componentized.templates">
<title>Componentized Templates</title>
<para>
This tip is a bit of a hack, but still a neat idea. Use at your own
risk. ;-)
</para>
<para>
Traditionally, programming templates into your applications goes as
follows: First, you accumulate your variables within your PHP
application, (maybe with database queries.) Then, you instantiate your
Smarty object, assign the variables and display the template. So lets
say for example we have a stock ticker on our template. We would
collect the stock data in our application, then assign these variables
in the template and display it. Now wouldn't it be nice if you could
add this stock ticker to any application by merely including the
template, and not worry about fetching the data up front?
</para>
<para>
You can embed PHP into your templates with the {php}{/php} tags.
With this, you can setup self contained templates with their own
data structures for assigning their own variables. With the logic
embedded like this, you can keep the template & logic together. This
way no matter where the template source is coming from, it is always
together as one component.
</para>
<example>
<title>componentized template</title>
<programlisting>
{* Smarty *}
{php}
// setup our function for fetching stock data
function fetch_ticker($symbol,&$ticker_name,&$ticker_price) {
// put logic here that fetches $ticker_name
// and $ticker_price from some resource
}
// call the function
fetch_ticker("YHOO",$ticker_name,$ticker_price);
// assign template variables
$this->assign("ticker_name",$ticker_name);
$this->assign("ticker_price",$ticker_price);
{/php}
Stock Name: {$ticker_name} Stock Price: {$ticker_price}</programlisting>
</example>
<para>
As of Smarty 1.5.0, there is even a cleaner way. You can include php in
your templates with the {include_php ...} tag. This way you can keep
your PHP logic separated from the template logic. See the <link
linkend="builtin.functions.include.php">include_php</link> function for
more information.
</para>
<example>
<title>componentized template with include_php</title>
<programlisting>
load_ticker.php
---------------
&lt;?php
// setup our function for fetching stock data
function fetch_ticker($symbol,&$ticker_name,&$ticker_price) {
// put logic here that fetches $ticker_name
// and $ticker_price from some resource
}
// call the function
fetch_ticker("YHOO",$ticker_name,$ticker_price);
// assign template variables
$this->assign("ticker_name",$ticker_name);
$this->assign("ticker_price",$ticker_price);
?&gt;
index.tpl
---------
{* Smarty *}
{include_php file="load_ticker.php"}
Stock Name: {$ticker_name} Stock Price: {$ticker_price}</programlisting>
</example>
</sect1>
<sect1>
<title>Obfuscating E-mail Addresses</title>
<para>
Do you ever wonder how your E-mail address gets on so many spam mailing
lists? One way spammers collect E-mail addresses is from web pages. To
help combat this problem, you can make your E-mail address show up in a
scrambled looking form in the HTML source, yet it it will look and work
correctly in the browser. This is done with the escape modifier.
</para>
<example>
<title>Example of Obfuscating an E-mail Address</title>
<programlisting>
index.tpl
---------
Send inquiries to
&lt;a href="mailto:{$EmailAddress|escape:"hex"}&gt;{$EmailAddress|escape:"hexentity"}&lt;/a&gt;
OUTPUT:
Send inquiries to
&lt;a
href="mailto:%62%6f%62%40%6d%65%2e%6e%65%74"&gt;&amp;#x62;&amp;#x6f;&amp;#x62;&amp;#x40;&amp;#x6d;&amp;#x65;&amp;#x2e;&amp;#x6e;&amp;#x65;&amp;#x74;&lt;/a&gt;
</programlisting>
</example>
<para>
Although this looks like a mess in the HTML source, it will render
correctly in your browser, and the mailto: hyperlink will go to the correct
address.
</para>
<para>
TECHNICAL NOTE: This method isn't 100% foolproof. Although highly unlikely,
a spammer could conceivably write his e-mail collecter to decode these
values.
</para>
</sect1>
</chapter>
<chapter id="resources">
<title>Resources</title>
<para>
Smarty's homepage is located at http://www.phpinsider.com/php/code/Smarty/.
You can join the mailing list by sending an e-mail to
subscribe-smarty@lists.ispi.net. An archive of the mailing list can be
viewed at http://marc.theaimsgroup.com/?l=smarty&amp;r=1&amp;w=2
</para>
</chapter>
<chapter id="bugs">
<title>BUGS</title>
<para>
Check the BUGS file that comes with the latest distribution of Smarty, or
check the website.
</para>
</chapter>
</part>

46
docs/common.dsl Normal file
View File

@@ -0,0 +1,46 @@
;; -*- Scheme -*-
;;
;; $Id$
;;
;; This file contains stylesheet customization common to the HTML
;; and print versions.
;;
;; Stylesheets Localization
(define %default-language% "en")
(define %use-id-as-filename% #t)
(define %gentext-nav-tblwidth% "100%")
(define %refentry-function% #t)
(define %refentry-generate-name% #f)
(define %funcsynopsis-style% 'ansi)
(define ($legalnotice-link-file$ legalnotice)
(string-append "copyright" %html-ext%))
(define %generate-legalnotice-link% #t)
(define %footnotes-at-end% #t)
(define %force-chapter-toc% #t)
(define newline "\U-000D")
(define %number-programlisting-lines% #f)
(define %linenumber-mod% 1)
(define %shade-verbatim% #t)
(define ($generate-book-lot-list$)
;; REFENTRY generate-book-lot-list
;; PURP Which Lists of Titles should be produced for Books?
;; DESC
;; This parameter should be a list (possibly empty) of the elements
;; for which Lists of Titles should be produced for each 'Book'.
;;
;; It is meaningless to put elements that do not have titles in this
;; list. If elements with optional titles are placed in this list, only
;; the instances of those elements that do have titles will appear in
;; the LOT.
;;
;; /DESC
;; AUTHOR N/A
;; /REFENTRY
(list (normalize "table")))
(define (php-code code)
(make processing-instruction
data: (string-append "php " code "?")))

4054
docs/designers.sgml Normal file

File diff suppressed because it is too large Load Diff

198
docs/getting-started.sgml Normal file
View File

@@ -0,0 +1,198 @@
<part id="getting.started">
<title>Getting Started</title>
<chapter id="overview">
<title>Overview</title>
<sect1 id="what.is.smarty">
<title>What is Smarty?</title>
<para>
Smarty is a template engine for PHP. One of the unique aspects about
Smarty is that it compiles the template files into native PHP scripts
upon the first invocation. After that, it just executes the compiled
PHP scripts. Therefore, there is no costly template file parsing for
each request, and each template can take full advantage of PHP compiler
cache solutions such as Zend Cache (http://www.zend.com) or APC
(http://apc.communityconnect.com).
</para>
<para>
Some of Smarty's features:
</para>
<itemizedlist>
<listitem><para>It is extremely fast.</para></listitem>
<listitem><para>It is efficient since the PHP parser does the
dirty work.</para></listitem>
<listitem><para>No template parsing overhead, only compiles once.</para></listitem>
<listitem><para>It is smart about recompiling only the template
files that have changed.</para></listitem>
<listitem><para>You can make <link linkend="bundled.plugins.commands">custom
functions</link> and custom <link linkend="variable.modifiers">variable
modifiers</link>, so the template language is extremely extensible.</para></listitem>
<listitem><para>Configurable template delimiter tag syntax, so you can use
{}, {{}}, &lt;!--{}--&gt;, etc.</para></listitem>
<listitem><para>The if/elseif/else/endif constructs are passed to the
PHP parser, so the {if ...} expression syntax can be as simple or as complex
as you like.</para></listitem>
<listitem><para>Unlimited nesting of sections, ifs, etc. allowed.</para></listitem>
<listitem><para>It is possible to embed PHP code right in your template files,
although this may not be needed (nor recommended)
since the engine is so customizable.</para></listitem>
<listitem><para>Built-in caching support (new in 1.3.0)</para></listitem>
<listitem><para>Arbitrary template sources (new in 1.4.0)</para></listitem>
<listitem><para>Custom cache handling functions (new in 1.4.7)</para></listitem>
</itemizedlist>
</sect1>
<sect1 id="how.smarty.works">
<title>How Smarty works</title>
<sect2 id="features.compiling"><title>Compiling</title>
<para>
Smarty compiles the templates into native PHP code on-the-fly. The actual
PHP scripts that are generated are created implicitly, so theoretically you
should never have to worry about touching these files, or even know of their
existence. The exception to this is debugging Smarty template syntax errors,
discussed later in this document.
</para>
</sect2>
<sect2 id="features.caching">
<title>Caching</title>
<para>
Smarty can cache the output of your generated templates. By default
this is disabled. If you <link linkend="variable.caching">enable
caching</link>, Smarty will store a copy of the generated template
output, and use this until the copy <link
linkend="variable.cache.lifetime">expires</link>, regenerating a new
one. The default cache expire time can be configured from the
class. The exception to the rule is the <link
linkend="builtin.functions.insert">insert</link> tag. Anything
generated by the insert tag is not cached, but run dynamically on
every invocation, even within cached content.
</para>
<para>
TECHNICAL NOTE: Any time you change a template, change values in
config files or change the content that gets displayed in a
template, you can turn on compile_check to regenerate the caches
that are affected, or wait for the cache to expire to see the
results of the changes. You clear caches manually by deleting files
from the cache directory, programatically with <link
linkend="api.clear.cache">clear_cache</link> or <link
linkend="api.clear.all.cache">clear_all_cache</link>, or turn on
$compile_check (or $force_compile).
</para>
<para>
TECHNICAL NOTE: As of Smarty 1.4.6, if you have caching enabled AND
you have compile_check enabled, the cached file will regenerate if
an involved template or config file has been modified, regardless
of the cache expire time. This results in a slight performance hit
since it has to check the templates and config files for
modification times. Therefore if you are not actively changing
templates or config files, it is advisable to leave compile_check
off. As of Smarty 1.4.7, enabling $force_compile will cause cache
files to always be regenerated.
</para>
</sect2>
</sect1>
</chapter>
<chapter id="installation">
<title>Installation</title>
<sect1 id="installation.requirements">
<title>Requirements</title>
<para>
Smarty requires PHP 4.0.4pl1 or later. See the
<link linkend="bugs">BUGS</link> section for caveats.
</para>
</sect1>
<sect1 id="installation.smarty">
<title>Installing Smarty</title>
<para>
Installing Smarty is fairly straightforward, there are a few things to
be aware of. Smarty creates PHP scripts from the templates. This
usually means allowing user "nobody" (or whomever the web server runs
as) to have permission to write the files. Each installation of a
Smarty application minimally needs a templates directory and a compiled
templates directory. If you use configuration files you will also need
a directory for those. By default these are named "templates",
"templates_c" and "configs" respectively. If you plan on using caching,
you will need to create a "cache" directory, also with permission to
write files.
</para>
<para>
TECHNICAL NOTE: You can get around the need to allow the web server
user write access to compile templates. Smarty needs to compile the
templates only once. This can be done from the command line, using the
CGI version of PHP. example: "php -q index.php". Once the templates are
compiled, they should run fine from the web environment. If you change
a template, you must recompile from the command line again. If you do
not have the CGI version of PHP available and you are concerned about
world-writable directory access, you can chmod 777 the compile_dir, let
the templates compile once as the web server user, then change the
directory mode to 755. If you are using the caching feature of Smarty,
the cache directory must always have write access for the web server
user.
</para>
<para>
TECHNICAL NOTE: If you do not have access to the php.ini file, you can
change non-server settings (such as your include_path) with the
ini_set() command (available in PHP 4.0.4 or later.) example:
ini_set("include_path",".:/usr/local/lib/php");
</para>
<para>
Copy the Smarty.class.php, Smarty.addons.php and Config_File.class.php
scripts to a directory that is in your PHP include_path. NOTE: PHP will
try to create a directory alongside the executing script called
"templates_c". Be sure that directory permissions allow this to happen.
You will see PHP error messages if this fails. You can also create the
directory yourself before hand, and change the file ownership
accordingly. See below.
</para>
<para>
TECHNICAL NOTE: If you don't want to use include_path to find the
Smarty files, you can set the SMARTY_DIR constant to the full path to
your Smarty library files. Be sure the path ends with a slash!
</para>
<example>
<title>Example of installing Smarty</title>
<screen>
# be sure you are in the web server document tree
# this assumes your web server runs as user "nobody"
# and you are in a un*x environment
gtar -zxvf Smarty-[version].tar.gz
mkdir templates_c
chown nobody:nobody templates_c
chmod 700 templates_c
# if you are using caching, do the following
mkdir cache
chown nobody:nobody cache
chmod 700 cache</screen>
</example>
<para>
Next, try running the index.php script from your web browser.
</para>
</sect1>
<sect1 id="smarty.constants">
<title>Constants</title>
<para></para>
<sect2 id="constant.smarty.dir">
<title>SMARTY_DIR</title>
<para>
This should be the full system path to the location of the Smarty
class files. If this is not defined, then Smarty will attempt to
determine the appropriate value automatically. If defined, the path
must end with a slash.
</para>
<example>
<title>SMARTY_DIR</title>
<programlisting>
// set path to Smarty directory
define("SMARTY_DIR","/usr/local/lib/php/Smarty/");
require_once(SMARTY_DIR."Smarty.class.php");</programlisting>
</example>
</sect2>
</sect1>
</chapter>
</part>

336
docs/html-common.dsl Normal file
View File

@@ -0,0 +1,336 @@
;; -*- Scheme -*-
;;
;; $Id$
;;
;; Returns the depth of the auto-generated TOC (table of contents) that
;; should be made at the nd-level
(define (toc-depth nd)
(if (string=? (gi nd) (normalize "book"))
3 ; the depth of the top-level TOC
1 ; the depth of all other TOCs
))
(element (funcdef function)
($bold-seq$
(make sequence
(process-children)
)
)
)
(define (is-true-optional nl)
(and (equal? (gi (parent nl)) (normalize "parameter"))
(equal? 0 (string-length (strip (data (preced nl)))))
(equal? 0 (string-length (strip (data (follow nl)))))
)
)
(define (has-true-optional nl)
(is-true-optional
(node-list-first-element
(select-elements
(descendants nl)
(normalize "optional"))
)
)
)
(define (count-true-optionals nl)
(let loop
((result 0)
(nl (select-elements (descendants nl) (normalize "optional")))
)
(if(node-list-empty? nl)
result
(if(is-true-optional(node-list-first nl))
(loop (+ result 1) (node-list-rest nl))
(loop result (node-list-rest nl))
)
)
)
)
;; there are two different kinds of optionals
;; optional parameters and optional parameter parts
;; an optional parameter is identified by an optional tag
;; with a parameter tag as its parent
;; and only whitespace between them
(element optional
;;check for true optional parameter
(if (is-true-optional (current-node))
;; yes - handle '[...]' in paramdef
(process-children-trim)
;; no - do '[...]' output
(make sequence
(literal %arg-choice-opt-open-str%)
(process-children-trim)
(literal %arg-choice-opt-close-str%)
)
)
)
;; now this is going to be tricky
(element paramdef
(make sequence
;; special treatment for first parameter in funcsynopsis
(if (equal? (child-number (current-node)) 1)
;; is first ?
(make sequence
;; start parameter list
(literal "(")
;; is optional ?
( if (has-true-optional (current-node))
(literal %arg-choice-opt-open-str%)
(empty-sosofo)
)
)
;; not first
(empty-sosofo)
)
;;
(process-children-trim)
;; special treatment for last parameter
(if (equal? (gi (ifollow (current-node))) (normalize "paramdef"))
;; more parameters will follow
(make sequence
;; next is optional ?
( if (has-true-optional (ifollow (current-node)))
;; optional
(make sequence
(literal " ")
(literal %arg-choice-opt-open-str%)
)
;; not optional
(empty-sosofo)
)
(literal ", " )
)
;; last parameter
(make sequence
(literal
(let loop ((result "")(count (count-true-optionals (parent (current-node)))))
(if (<= count 0)
result
(loop (string-append result %arg-choice-opt-close-str%)(- count 1))
)
)
)
( literal ")" )
)
)
)
)
(element function
(let* ((function-name (data (current-node)))
(linkend
(string-append
"function."
(string-replace
(string-replace function-name "_" "-")
"::" ".")))
(target (element-with-id linkend))
(parent-gi (gi (parent))))
(cond
;; function names should be plain in FUNCDEF
((equal? parent-gi "funcdef")
(process-children))
;; if a valid ID for the target function is not found, or if the
;; FUNCTION tag is within the definition of the same function,
;; make it bold, add (), but don't make a link
((or (node-list-empty? target)
(equal? (case-fold-down
(data (node-list-first
(select-elements
(node-list-first
(children
(select-elements
(children
(ancestor-member (parent) (list "refentry")))
"refnamediv")))
"refname"))))
function-name))
($bold-seq$
(make sequence
(process-children)
(literal "()"))))
;; else make a link to the function and add ()
(else
(make element gi: "A"
attributes: (list
(list "HREF" (href-to target)))
($bold-seq$
(make sequence
(process-children)
(literal
)
(literal "()"))))))))
(element classname
(let* ((class-name (data (current-node)))
(linkend
(string-append
"class."
(string-replace
(case-fold-down class-name) "_" "-")))
(target (element-with-id linkend))
(parent-gi (gi (parent))))
(cond
;; function names should be plain in SYNOPSIS
((equal? parent-gi "synopsis")
(process-children))
;; if a valid ID for the target class is not found, or if the
;; CLASSNAME tag is within the definition of the same class,
;; make it bold, but don't make a link
((or (node-list-empty? target)
(equal? (case-fold-down
(data (node-list-first
(select-elements
(node-list-first
(children
(select-elements
(children
(ancestor-member (parent) (list "refentry")))
"refnamediv")))
"refname"))))
class-name))
($bold-seq$
(process-children)))
;; else make a link to the function and add ()
(else
(make element gi: "A"
attributes: (list
(list "HREF" (href-to target)))
($bold-seq$
(process-children)))))))
(element constant
(let* ((constant-name (data (current-node)))
(linkend
(string-append "constant."
(case-fold-down
(string-replace constant-name "_" "-"))))
(target (element-with-id linkend))
(parent-gi (gi (parent))))
(cond
; ;; constant names should be plain in FUNCDEF
; ((equal? parent-gi "funcdef")
; (process-children))
;; if a valid ID for the target constant is not found, or if the
;; CONSTANT tag is within the definition of the same constant,
;; make it bold, add (), but don't make a link
((or (node-list-empty? target)
(equal? (case-fold-down
(data (node-list-first
(select-elements
(node-list-first
(children
(select-elements
(children
(ancestor-member (parent) (list "refentry")))
"refnamediv")))
"refname"))))
constant-name))
($bold-mono-seq$
(process-children)))
;; else make a link to the function and add ()
(else
(make element gi: "A"
attributes: (list
(list "HREF" (href-to target)))
($bold-mono-seq$
(process-children)))))))
(element example
(make sequence
(make element gi: "TABLE"
attributes: (list
(list "WIDTH" "100%")
(list "BORDER" "0")
(list "CELLPADDING" "0")
(list "CELLSPACING" "0")
(list "CLASS" "EXAMPLE"))
(make element gi: "TR"
(make element gi: "TD"
($formal-object$))))))
(element (paramdef parameter)
(make sequence
font-posture: 'italic
(process-children-trim)
)
)
(mode book-titlepage-recto-mode
(element authorgroup
(process-children))
(element author
(let ((author-name (author-string))
(author-affil (select-elements (children (current-node))
(normalize "affiliation"))))
(make sequence
(make element gi: "DIV"
attributes: (list (list "CLASS" (gi)))
(literal author-name))
(process-node-list author-affil))))
)
(define (chunk-element-list)
(list (normalize "preface")
(normalize "chapter")
(normalize "appendix")
(normalize "article")
(normalize "glossary")
(normalize "bibliography")
(normalize "index")
(normalize "colophon")
(normalize "setindex")
(normalize "reference")
(normalize "refentry")
(normalize "part")
(normalize "sect1")
(normalize "sect2")
(normalize "section")
(normalize "book") ;; just in case nothing else matches...
(normalize "set") ;; sets are definitely chunks...
))
(define ($section-body$)
(make element gi: "DIV"
attributes: (list (list "CLASS" (gi)))
($section-separator$)
($section-title$)
(if (or (not (node-list-empty? (select-elements (children (current-node))
(normalize "sect2"))))
(not (node-list-empty? (select-elements (children (current-node))
(normalize "sect3")))))
(build-toc (current-node) 1)
(empty-sosofo))
(process-children)))

21
docs/html.dsl Normal file
View File

@@ -0,0 +1,21 @@
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY docbook.dsl SYSTEM "/usr/share/sgml/docbook/html/docbook.dsl" CDATA DSSSL>
<!ENTITY html-common.dsl SYSTEM "html-common.dsl">
<!ENTITY common.dsl SYSTEM "common.dsl">
]>
<style-sheet>
<style-specification id="docbook-smarty-html" use="docbook">
<style-specification-body>
(define %html-ext% ".html")
&html-common.dsl;
&common.dsl;
</style-specification-body>
</style-specification>
<external-specification id="docbook" document="docbook.dsl">
</style-sheet>

34
docs/manual.sgml Normal file
View File

@@ -0,0 +1,34 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
<!ENTITY preface SYSTEM "preface.sgml">
<!ENTITY getting.started SYSTEM "getting-started.sgml">
<!ENTITY smarty.for.designers SYSTEM "designers.sgml">
<!ENTITY smarty.for.programmers SYSTEM "programmers.sgml">
<!ENTITY appendixes SYSTEM "appendixes.sgml">
]>
<book id="index">
<bookinfo id="bookinfo">
<title>Smarty - the compiling PHP template engine</title>
<authorgroup id="authors">
<author>
<firstname>Monte</firstname><surname>Ohrt &lt;monte@ispi.net&gt;</surname>
</author>
<author>
<firstname>Andrei</firstname><surname>Zmievski &lt;andrei@php.net&gt;</surname>
</author>
</authorgroup>
<edition>Version 2.0</edition>
<copyright>
<year>2001</year>
<year>2002</year>
<holder>ispi of Lincoln, Inc.</holder>
</copyright>
</bookinfo>
&preface;
&getting.started;
&smarty.for.designers;
&smarty.for.programmers;
&appendixes;
</book>

69
docs/preface.sgml Normal file
View File

@@ -0,0 +1,69 @@
<preface id="preface">
<title>Preface</title>
<para>
It is undoubtedly one of the most asked questions on the PHP mailing
lists: how do I make my PHP scripts independent of the layout? While
PHP is billed as "HTML embedded scripting language", after writing a
couple of projects that mixed PHP and HTML freely one comes up with the
idea that separation of form and content is a Good Thing [TM]. In
addition, in many companies the roles of layout designer and programmer
are separate. Consequently, the search for a templating solution
ensues.
</para>
<para>
In our company for example, the development of an application goes on
as follows: After the requirements docs are done, the interface
designer makes mockups of the interface and gives them to the
programmer. The programmer implements business logic in PHP and uses
interface mockups to create skeleton templates. The project is then
handed off to the HTML designer/web page layout person who brings the
templates up to their full glory. The project may go back and forth
between programming/HTML a couple of times. Thus, it's important to
have good template support because programmers don't want anything to
do with HTML and don't want HTML designers mucking around with PHP
code. Designers need support for config files, dynamic blocks and
other interface issues, but they don't want to have to deal with
intricacies of the PHP programming language.
</para>
<para>
Looking at many templating solutions available for PHP today, most of
them provide a rudimentary way of substituting variables into templates
and do a limited form of dynamic block functionality. But our needs
required a bit more than that. We didn't want programmers to be dealing
with HTML layout at ALL, but this was almost inevitable. For instance,
if a designer wanted background colors to alternate on dynamic blocks,
this had to be worked out with the programmer in advance. We also
needed designers to be able to use their own configuration files, and
pull variables from them into the templates. The list goes on.
</para>
<para>
We started out writing out a spec for a template engine back in late
1999. After finishing the spec, we began to work on a template engine
written in C that would hopefully be accepted for inclusion with PHP.
Not only did we run into many complicated technical barriers, but there
was also much heated debate about exactly what a template engine should
and should not do. From this experience, we decided that the template
engine should be written in PHP as a class, for anyone to use as they
see fit. So we wrote an engine that did just that and
<productname>SmartTemplate</productname> came into existence (note: this
class was never submitted to the public). It was a class that did
almost everything we wanted: regular variable substitution, supported
including other templates, integration with config files, embedding PHP
code, limited 'if' statement functionality and much more robust dynamic
blocks which could be multiply nested. It did all this with regular
expressions and the code turned out to be rather, shall we say,
impenetrable. It was also noticably slow in large applications from all
the parsing and regular expression work it had to do on each
invocation. The biggest problem from a programmer's point of view was
all the necessary work in the PHP script to setup and process templates
and dynamic blocks. How do we make this easier?
</para>
<para>
Then came the vision of what ultimately became Smarty. We know how fast
PHP code is without the overhead of template parsing. We also know how
meticulous and overbearing the PHP language may look to the average
designer, and this could be masked with a much simpler templating
syntax. So what if we combined the two strengths? Thus, Smarty was
born...
</para>
</preface>

2030
docs/programmers.sgml Normal file

File diff suppressed because it is too large Load Diff