<?xml version="1.0"?>
<record><wiki id="wiki?page_id=75">
	<page_name>GettingStarted:using_first_app</page_name>
	<page_id>75</page_id>
	<page_title>Using Your First Application</page_title>
	<content>==Using Your First Application==

A Web Lite application, at its core, provides 4 standard operations: Add new records, edit existing records, delete records, and find records. This section gives a brief overview of how to use your first Dataface application.
When you first create your Xataface application and there are no records in the database, the application will look quite plain. If you point your web browser to your newly created application it will look something like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-application-1.gif]]

You may be wondering why it says &quot;No records matched your request&quot; when you haven&apos;t even really made a request. This is because the &apos;default&apos; request that is performed if no other request is specified is to show the first record from the first table in the navigation menu. Since there are no records, it is true that there are NO records matching the default request.
So what can you do with this application anyways? Essentially there are 4 operations you will want to perform:

# Create new records
# Edit Existing records
# Find records
# Delete records

==Basic Navigation==

The navigation tabs (aka Navigation menu) at the top left represent the tables in your database. You can navigate to any of the tables in this list by clicking on that table:

[[Image:http://xataface.com/documentation/tutorial/getting_started/navmenu-1.gif]]

There are 3 &quot;views&quot; associated with tables in the database:

* &apos;&apos;&apos;Details&apos;&apos;&apos; - Shows the details of a single record in the table
* &apos;&apos;&apos;List&apos;&apos;&apos; - Shows the records in the current &quot;found set&quot; as a list. (in a table).
* &apos;&apos;&apos;Find&apos;&apos;&apos; - Allows users to find records matching certain criteria.

You can toggle between these 3 views using the tabs at the top of the page:

[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-tabs-1.gif]]

===The &quot;Found Set&quot;===

Throughout this tutorial you will see the phrase &quot;found set&quot; an awful lot, so it is important to understand just what this means. A &quot;found set&quot; is the set of all records in the current table that match the current &quot;find criteria&quot;. This begs the question, &quot;what is &apos;find criteria&apos;?&quot;. By default there is no find criteria. When you perform a search or a find on the current table, you add &quot;find criteria&quot; so that only the records satisfying these criteria will be included in the &quot;found set&quot;.

For example, if you click on the &quot;find&quot; tab, you will get a search form that allows you to search for records that match certain criteria. The &quot;find&quot; tab for the &quot;Course&quot; table in our application looks like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/find-form-1.gif]]

If you type in &quot;English&quot; in the &quot;Subject&quot; field and click &quot;Find&quot;, then the &quot;found set&quot; will consist of only records that contain the word &quot;English&quot; in their subject fields.

On the top left of the application window there will always be a &quot;Found&quot; line that indicates how many records are currently in the found set. e.g., 

This indicates that there are 256 records in the current table (which is the &apos;Groups&apos; table). There are currently only 225 records in the current &quot;found set&quot; (meaning that we have performed a &quot;find&quot; operation and it matched 225 of the records). It also indicates that the currently displayed record is record number 1 out of the 225 found records.

===The Actions Menu===

Just below the view tabs (&apos;details&apos;, &apos;list&apos;, and &apos;find&apos;) there are a few buttons that allow you to perform actions such as create new records, clear find parameters (i.e. Show All), and delete records.

[[Image:http://xataface.com/documentation/tutorial/getting_started/actions-menu-1.gif]]

&apos;&apos;&apos;Descriptions:&apos;&apos;&apos;

* &apos;&apos;&apos;new record&apos;&apos;&apos; - Creates a new record in the current table.
* &apos;&apos;&apos;show all&apos;&apos;&apos; - Clears all find criteria on current table so that all records are shown.
* &apos;&apos;&apos;delete&apos;&apos;&apos; - Deletes the current record in the table.
* &apos;&apos;&apos;delete found records&apos;&apos;&apos; - Deletes all records in the current &quot;found set&quot;. If no find criteria is specified this will delete all records in the table. 

===Creating new records===

The basic FacultyOfWidgetry application that we created in the previous section isn&apos;t very interesting when it doesn&apos;t contain any records, so let&apos;s create some Program records.

# Select the &quot;Program&quot; table by clicking on the &quot;Program&quot; option of the navigation menu.
# Click &quot;new record&quot; in the actions menu (top left).
# This will bring up a form to insert a new record that looks like: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/new-record-1.gif]]
# Fill in the form and click &quot;Save&quot;. If everything went OK, you will see the same form again, but with a &quot;success&quot; message at the top of the page: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/successfully-saved-1.gif]]

===Editing an existing record===

The &quot;details&quot; view allows you to view details or edit the current record. There should be at least 2 sub-tabs: &apos;View&apos; and &apos;Edit&apos;. If you click on the &apos;Edit&apos; tab, you will be presented with a form to edit the record. The form is identical to the &quot;create new record&quot; form.

===Deleting records===

If the &apos;list&apos; tab is selected, then you will see a button called &apos;delete found records&apos; in the actions menu (just below the view tabs). Alternatively if the &apos;details&apos; tab is selected, you will see a button called simply &apos;delete&apos;. 

[[Image:http://xataface.com/documentation/tutorial/getting_started/actions-menu-1.gif]]

Select &quot;delete&quot; to delete only the current record you are viewing in the &quot;details&quot; view.

Select &quot;delete found records&quot; to delete all of the records in the current found set. 

In either case, you will be prompted to confirm your decision before the records are actually deleted.

===Interface Overview===

Xataface applications provide an intuitive and consistent interface throughout. The following screenshot contains a map of some comment interface components along with some explanations:

[[Image:http://xataface.com/documentation/tutorial/getting_started/interface-schematic.png]]


Other topics
This short section is only intended to get you acquainted with the basics of Xataface applications. As your application becomes more complex with relationships and value-lists, there will be other usage scenarios of interest.</content>
	<keywords>&quot;find form&quot;,&quot;edit form&quot;,&quot;delete record&quot;,&quot;user interface&quot;,ui,template,look and feel</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=74">
	<page_name>GettingStarted:first_application</page_name>
	<page_id>74</page_id>
	<page_title>Creating your First Application</page_title>
	<content>==Creating Your First Application==

Build a simple Xataface application.

For our first Xataface application we will try to build a web site for Faculty of Widgetry (From the example in the &quot;Why Use Xataface&quot; page). The web site needs to store information about programs and courses. An entity-relationship diagram (ERD) for this website is included below:

[[Image:http://xataface.com/documentation/tutorial/getting_started/er-diagram.png]]

As the ERD shows, our database will need 2 tables (Course and Program). Our next step is to build this database. You can use any MySQL database administration tool to builld the database. My personal tool of choice is PHPMyAdmin.

===Step 1: Creating the database using PHPMyAdmin===

The following steps describe the procedure for creating this database using PHPMyAdmin.

# At the main menu of PHPMyAdmin, type &apos;FacultyOfWidgetry&apos; into the &apos;Create new database field&apos; as follows: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/new_database.gif]] &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;Then click &apos;Create&apos;.
# First we will create the &apos;Course&apos; table to hold course information. In the &apos;FacultyOfWidgetry&apos; page, fill in the &apos;Create new table text field as follows: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/create_table.gif]] &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt; Then click &apos;Go&apos;.
# This should bring up a form to specify the fields for the course table: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/course-table-def-small.gif]] &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt; Then click &quot;Save&quot;. The resulting SQL to create the Course table is as follows:&lt;code&gt;
CREATE TABLE `Course` (
 `CourseID` int(11) NOT NULL auto_increment,
 `ProgramID` int(11),
 `CourseTitle` varchar(64) NOT NULL default &apos;&apos;,
 `CourseDescription` text NOT NULL,
 `HTMLOutline` text NOT NULL,
 `PDFOutline` longblob NOT NULL,
 `PDFOutline_mimetype` varchar(64),
 `Subject` varchar(128) NOT NULL default &apos;&apos;,
 `CourseNumber` varchar(10) NOT NULL default &apos;&apos;,
 `Credits` int(5) NOT NULL default &apos;0&apos;,
 `LastModified` timestamp NOT NULL default CURRENT_TIMESTAMP,
 PRIMARY KEY (`CourseID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT=&apos;Store courses&apos; AUTO_INCREMENT=1 ;
&lt;/code&gt;
#In a similar fashion, create the Program table. The resulting SQL for this table is:&lt;code&gt;
CREATE TABLE `Program` (
 `ProgramID` int(11) NOT NULL auto_increment,
 `ProgramName` varchar(64) NOT NULL default &apos;&apos;,
 `ProgramDescription` text NOT NULL,
 `HTMLOutline` text NOT NULL,
 `PDFOutline` longblob NOT NULL,
 `PDFOutline_mimetype` varchar(32),
 `AdmissionDeadline` date NOT NULL default &apos;0000-00-00&apos;,
 `LastModified` timestamp NOT NULL default CURRENT_TIMESTAMP,
 PRIMARY KEY (`ProgramID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT=&apos;Academic Program&apos; AUTO_INCREMENT=1 ;
&lt;/code&gt;
# The database has been created with 2 tables: Program and Course. We can now move on to building the Xataface application.

===Step 2: Create Xataface Application===

Our Xataface application will provide a user-friendly front-end to our database. A basic application consists of a directory with a configuration file and an entry page (PHP file). Xataface comes with a PHP setup script (called makesite) to create the skeleton for your application. Alternatively you can set up the application manually.

Note: For the following instructions and examples, my Daface installation is located at /Users/shannah/Sites/dataface and the URL for the installation is http://localhost/~shannah/dataface.

====Method 1: Setting up application with the &apos;makesite&apos; script====

# From the command prompt, navigate to the dataface directory. (in my case &apos;&apos;/Users/shannah/Sites/dataface&apos;&apos;).
# This directory contains a file named &apos;makesite&apos;. It is a PHP script that can be used to build a website powered by Xataface. To find out the usage options for this script you can simply call the script with no parameters. E.g.,&lt;code&gt; 
stevepbook:~/Sites/dataface shannah$ ./makesite
&lt;/code&gt;
# This will give you usage instructions for the script as follows:&lt;code&gt;
makesite: invalid options entered.

 Usage: makesite &lt;site_path&gt; &lt;db_user&gt;:&lt;db_pass&gt;@&lt;db_host&gt;/&lt;db_name&gt; &lt;dataface_url&gt;
 or
 php makesite &lt;site_path&gt; &lt;db_user&gt;:&lt;db_pass&gt;@&lt;db_host&gt;/&lt;db_name&gt; &lt;dataface_url&gt;
 where 
 &lt;site_path&gt; = The path (absolute or relative) to your application directory.
 &lt;db_user&gt; = The MySQL username to connect to the database
 &lt;db_pass&gt; = The User&apos;s password to connect to the database
 &lt;db_host&gt; = The MySQL host name.
 &lt;db_name&gt; = The name of the mysql database for the application.
 &lt;dataface_url&gt; = The URL to the Xataface installation

 Examples:

 makesite ../FacultyOfWidgetry root:password@localhost/FacultyOfWidgetry /dataface

 The above command would create a site at ../FacultyOfWidgetry (i.e., the Faculty of 
 Widgetry directory in the parent directory. The database used for this site is 
 located at localhost, and the database name is FacultyOfWidgetry. The username
 to connect to the database is root and his password is password.
&lt;/code&gt;
# We create our FacultyOfWidgetry site using the following command:&lt;code&gt;
./makesite ../FacultyOfWidgetry \
    root@localhost/FacultyOfWidgetry \
    http://localhost/~shannah/dataface
&lt;/code&gt;
# This will create our application in the FacultyOfWidgetry folder if everything worked ok. The contents of the folder will look like: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/directory-structure-1.gif]]

You may be wondering what these files. Here is the short version (Read the next section &quot;Creating applications manually&quot; for more detailed information about the contents of these files.

The index.php file is the entry point for your application (i.e., you point the web browser at this file to use the application. 
The conf.ini file contains database connection settings and some other minor settings, like what should appear in the navigation menu.
The tables/Program (tables/Course) directory can contain configuration files specific to the Program (Course) table. More on that later. 

# Point your web browser to the FacultyOfWidgetry directory to see the application: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-application-1.gif]]
#Your application is now created. It will enable you to add, edit, delete, and find records in either the Course table or the Program table. There will be more on the basics of using this application in the next section.	

====Method 2: Setting up application manually====

Using the makesite script as described above is the recommended way to set up an application because it saves time. However, it is very easy to set up the application manually. Just follow these steps:

# Create a directory for the application somewhere in your web site (preferably outside your xataface directory). We will call our directory &apos;FacultyOfWidgetry&apos;. ):&lt;code&gt;
mkdir FacultyOfWidgetry
&lt;/code&gt;
# Create a PHP file to serve as the access point for the application. Generally we will name this file &apos;index.php&apos;, but you can name it anything. Place the following contents in the index.php file:&lt;code&gt;
&lt;?
require_once &apos;/path/to/dataface/dataface-public-api.php&apos;;
df_init(__FILE__, &apos;http://yourdomain.com/dataface&apos;);
$app =&amp; Dataface_Application::getInstance();
$app-&gt;display();
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;OK, I guess some explanations are in order.&lt;/p&gt;&lt;p&gt;
The first line imports the all of the public functions for dataface from the dataface-public-api.php file.&lt;/p&gt;&lt;p&gt;
The second line initializes the application for the current directory and specifies the URL to the dataface installation.&lt;/p&gt;&lt;p&gt;
The third line obtains an instance to the Application object - the core of your Dataface application.&lt;/p&gt;&lt;p&gt;
The fourth line simply displays the application.&lt;/p&gt;&lt;/nowiki&gt;
# Create a file named &apos;conf.ini&apos; to contain database connection information. Its contents should be:&lt;code&gt;
[_database]
	host = &quot;localhost&quot;
	user = &quot;dbuser&quot;
	password = &quot;secret&quot;
	name = &quot;FacultyOfWidgetry&quot;

[_tables]
	Course = &quot;Course&quot;
	Program = &quot;Program&quot;
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;&lt;b&gt;Explanations:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There are 2 sections in this INI file: &apos;_database&apos;, and &apos;_tables&apos;.&lt;/p&gt;&lt;p&gt;
The &apos;_database&apos; section specifies the database connection information for the MySQL database.&lt;/p&gt;&lt;p&gt;
The &apos;_tables&apos; section specifies which tables will be included in the navigation menu for the application.&lt;/p&gt;&lt;/nowiki&gt;
# At this point, the application is functional. However there is one more thing that should be done for security reasons. The conf.ini file contains sensitive password information and should not be served to the web. We will create an .htaccess file to tell Apache NOT to serve this (or any) .ini file. The .htaccess file should contain:&lt;code&gt;
&lt;FilesMatch &quot;\.ini$&quot;&gt;
	Deny from all
&lt;/FilesMatch&gt;&lt;/code&gt;
# The directory structure of your application will now look like: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-app-dir-structure-manual-1.gif]]&lt;nowiki&gt;&lt;p&gt;
Note, however, that there is also an .htaccess file that is hidden from this image.&lt;/p&gt;&lt;p&gt;You may be wondering why there is no &apos;tables&apos; directory like the directory structure that was generated by the makesite script. The &apos;tables&apos; directory is not required for the application to be functional. It will be required later on when we start to decorate the database.&lt;/p&gt;&lt;/nowiki&gt;
# The application is now ready to go. Point your web browser to the index.php file that you created. It will look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-application-1.gif]]

===Download source files===

[[File:http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-4-tar.gz|Download the source files]] for this application at a tar.gz archive.
These files reflect the state of the application at this point of the tutorial. As later sections make changes to the application you will be able to download those versions also.</content>
	<keywords>htaccess first application installation</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=73">
	<page_name>GettingStarted:Installation</page_name>
	<page_id>73</page_id>
	<page_title>Installation</page_title>
	<content>==Installation==

Download and installation instructions for the Web Lite framework.
Xataface is a 100% PHP Framework that comes with all dependencies as part of the installation. The framework itself lives inside a single directory that should be placed inside the document root of your web server so that it can be accessed from the web. You can install a single copy of Xataface to be used by multiple applications on your web server. Each application just &quot;requires&quot; the key files from the Web Lite framework.

===Downloading===

# Go to the Xataface Sourceforge project file releases page
# Download the latest file release.

===Installing===

# Unpack the gzipped tar archive that you downloaded somewhere in your web server&apos;s document root (i.e., make sure that the &apos;dataface&apos; directory is in a web-accessible location).
# Make the dataface/Dataface/templates_c directory writable by the web server.  An unsafe way to do this is to 
 chmod 777 Dataface/templates_c
But it would be better to just give write access to the web server user.
# Confirm that the installation worked by pointing the web browser to http://yourdomain.com/path/to/dataface/dataface_info.php . If it worked OK, you should receive a web page that says &quot;Dataface is installed correctly&quot;, along with some basic instructions for creating a Xataface Application. (Note: Sometimes this page will give you a false positive. i.e., it may say the installation worked but then your Xataface application receives errors. Check the troubleshooting section below to deal with these issues).

===Troubleshooting===

If your installation is not going as planned, don&apos;t panic. There is a possiblity that your system has a slightly different configuration and you have to make some small adjustments to make the installation work.

The general procedure for troubleshooting the installation is as follows:

# Check the [[Troubleshooting]] page.
# Look through the [http://xataface.com/forum forum] to see if others have experienced the same thing.
# Post your question in the forum if you can&apos;t find the answer already.

</content>
	<keywords>installation troubleshooting downloading </keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=72">
	<page_name>GettingStarted:Why_Use_Xataface</page_name>
	<page_id>72</page_id>
	<page_title>Why Use Xataface</page_title>
	<content>==Why Use Xataface?==

Some simple examples similar to those that are frequently encountered by web developers, and how dataface can be used to acheive a solution.
As a web services developer in the Faculty of Applied Sciences at Simon Fraser University, I am frequently getting requests to build websites that are manageable by the site owner. Most of these requests also specify certain types of content that must be stored on the website, and much of this content needs to be n-ary (i.e., there will be multiple instances of each type of content). Let me give you an example.

===Example 1: Website for Faculty of Widgetry===

The Faculty of Widgetry needs a website to publish information about its undergraduate programs. It is important for them to be able to publish admission requirements, and program overviews for each program. It is also important to have course outlines and timetables for each course. The Faculty of Widgetry has 12 undergraduate programs and over 100 courses offered.

====Solution 1: Static HTML====

To build this web site using only static HTML pages using Dreamweaver or some other HTML editor would require at least 112 pages to be created (one for each course and program). However, once we recognize that there are only 2 types of pages required (one for courses and one for programs), we can reduce the task down to creating 2 templates and filling in the main content for each program and course individually. Most HTML editors have some templating ability so you can make changes to the template and have the changes propogated to all pages that use that template with the click of a button.

This works great, but courses are added frequently, and outlines are changed. Do you really want to receive requests to update all of these pages every time there are changes to make? (If your answer is &apos;yes&apos;, then you probably won&apos;t be interested in reading the rest of this tutorial). Whether the Dean of the faculty knows it or not, it is very important for the program assistants to be able to update these web pages on their own. To acheive these goals you can:

* Install Dreamweaver on the Program Assistants&apos; computers, teach them how to use it, and allow them to perform updates.
* Install Contribute, which is a scaled down version of Dreamweaver to make it easier for the Program Assistants to edit the content.
* Use another solution that is equivalent to one of the above 2 solutions.

Installing Dreamweaver for each Program Assistant is a little overkill, and since it has the ability to do much more than just update content. In addition, Dreamweaver is really a developer&apos;s tool - not a secretary&apos;s tool, so it can be difficult to learn at first. The best reason NOT to install Dreamweaver on the Program Assistant&apos;s computer, however, is that it enables him/her to muck things up by accident (believe me, I has happened to me more times than I care to count).

Admittedly, Contribute is a viable option as it controls access to only certain portions of web pages to be edited, and it is targetted at secretaries (not developers) so it is easier to use. In fact, given the requirements for this web site (as stated above), this is a perfectly good solution. However you better hope that none of the following requirements are added:

* Each program web page should contain an up-to-date list of all of the courses required for the program, along with a link to the course outline for that course.
* Course outlines should be available in PDF format as well as HTML format.
* An index page showing all of the courses available should be added. This page must allow courses to be organized by program, course subject, or course number.
* Any other requirement that would have information formatted in more than one way.

If any of these requirements are likely to be added (EVER) then you would be well-advised to look into solutions that use a database back-end.

====Solution 2: Use a Content Management System (CMS)====

There are hundreds of content management systems available that will allow you to store and update content through the web (TTW). Some of them even have an assortment of add-ons that will allow you to store more specific types of information. Some good CMS&apos;s include Plone, Drupal, and Xoops. Suppose we want to develop the Faculty of Widgetry website using one of these CMS&apos;s. Any good CMS will allow you to create and edit HTML documents easily (without having to write any custom products). However, it is often the case that our documents require the content to be structured. For example, each program has some common data associated with it: Program Name, Admission Deadline, Program Description, Outline, Courses, etc... If we want to properly separate data from presentation, we would need to build a special content-type to store our programs. Most CMS&apos;s allow you to develop custom content-types using the underlying programming language and an API (Application Programming Interface). Some API&apos;s are easier to use than others and some are documented better than others. The common element is that each has its own proprietary interface for writing these add-ons.

If you are using a CMS and you are proficient in the creation of add-on content-types, then you will be able to build the Faculty of Widgetry website without great difficulty. However there are a number of reasons why you may choose NOT to use a CMS:

* Steep learning curve: Depending on the CMS it can be very time consuming and difficult to learn how to use and modify the CMS to suit you purposes.
* It is over-kill: Most CMS&apos;s are filled with features and modules that you will never need. In fact it can even be a pain to turn them off if you don&apos;t want them.
* You can get tied into the CMS: When you are using a CMS, you will start developing for the CMS. With all of your content in the CMS it may be difficult to migrate to a different solution later on. (The truth of this statement will vary for different CMS&apos;s). Choose your CMS carefully.

====Solution 3: Use an existing Application====

OK, OK, let&apos;s not get too carried away with trying to develop the website until we have checked the market to see if someone else has already done it better. Maybe there is already a PHP application that makes websites for Faculties easy. I mean, I can&apos;t be the first person that needed to build a website for a Faculty. In fact if you do a search or go to Hotscripts.com, you will probably find a handful of applications or scripts that almost do what you need. If you&apos;re lucky, maybe you can find an application that does exactly what you need (but frankly, I&apos;ve never been that lucky). If you find one, maybe it&apos;s worth taking it for a test drive. But beware. Using a system that almost does what you need but is difficult to modify to your needs can be worse than building it by scratch. Make sure that you are able to modify the application to suit your needs exactly.

====Solution 4: Use PHP and MySQL====

If all we want to do is separate the data from the presentation and allow the Program Assistants to update data on the website, why not just design a MySQL database with the appropriate tables and fields to store the required data. In our case we will need 2 tables:

&apos;&apos;&apos;Programs&apos;&apos;&apos;: 

* Fields:
** ProgramID : int
** ProgramName : varchar
** ProgramDescription: text
** AdmissionDeadline: date
** Outline_HTML : text
** Outline_PDF : blob


&apos;&apos;&apos;Courses&apos;&apos;&apos;:
* Fields:
** CourseID : int
** CourseSubject : varchar
** CourseTitle : varchar
** CourseNumber : int
** ProgramID : int
** CourseDescription : text
** Outline_HTML : text
** Outline_PDF : blob


Now it&apos;s easy to create a few web pages that extract data from the database and displays it as HTML. In fact if there is an existing page template that you can use for the header and footer, you can develop the entire Faculty website in under an hour (you just have to create 3 pages).

&apos;&apos;&apos;Question&apos;&apos;&apos;: How will the Program Assistants update the information in the database?

&apos;&apos;&apos;Answer&apos;&apos;&apos;: OK, let&apos;s assume that you&apos;re not going to teach them SQL and that a DB Admin tool will also be too difficult to learn. Then you have to create HTML forms to update records in the database.

Ouch! What was easy just became hard. Making HTML forms is a real pain, because you have to validate the input, deal with file uploads, and also make sure that everything is stored to the database OK without losing any information. Such a basic task, but it can be very difficult. This is when it is time to use Xataface.

====Solution 5: Use Xataface====

OK, this isn&apos;t really its own solution. It is more like &quot;Solution 4 Part II&quot;, because Xataface is intended to complement your custom application you built with solution 4, by providing an easy-to-use, configurable user interface that is targeted at secretaries and normal users (as opposed to database administrators). A Xataface application takes only seconds to set up and it will provide you with a full user interface for your users to edit information in the database.</content>
	<keywords>introduction motivation why</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=71">
	<page_name>GettingStarted:Introduction</page_name>
	<page_id>71</page_id>
	<page_title>Introduction</page_title>
	<content>Web Lite is a simple framework for building data-driven web applications in PHP and MySQL. This section introduces some of the concepts and applications of Dataface.

To fully understand what Xataface is, we must first define a few key terms:

&apos;&apos;&apos;Framework&apos;&apos;&apos; - A set of software routines that provide a foundation structure for an application. Frameworks take the tedium out of writing an application from scratch. (From Answers.com)

&apos;&apos;&apos;Data-driven design&apos;&apos;&apos;- Designing an application around the data that it will store.

Xataface is a &apos;&apos;Framework&apos;&apos; in the sense that it is a set of classes and libraries that take the tedium out of writing web applications. It provides a simple web interface to a MySQL database enabling users to update, delete, and find data in the underlying database. The interface is targeted at secretaries and end-users as opposed to database administrators.

Xataface enables &apos;&apos;data-driven design&apos;&apos; because it allows developers to develop web sites by first designing the database that will be used to store the data on the website, and then design the pages used to display the data. The developer can focus on the data because he or she does not have to worry about having to build forms to update the data. If the requirements of the application change, the developer can simply add a field to the database table and all associated web forms will be updated automatically (because they are all dynamically generated using the database schema).


===Requirements===

* [http://php.net PHP] &gt;= 4.3
* [http://mysql.com MySQL] &gt;= 3.2.3

===Key Technologies===

* [http://pear.php.net PEAR class libraries] (HTML_QuickForm, etc...)
* [http://smarty.net Smarty Templating Engine]
* [http://plone.org Plone] Javascript and CSS style sheets

===Development Procedures===

# Identify the data that will need to be stored for a web site.
##[[Image:http://xataface.com/documentation/tutorial/getting_started/er-diagram.png]]
# Design the database using your favorite database administration program (e.g., PHPMyAdmin)
##[[Image:http://xataface.com/documentation/tutorial/getting_started/phpMyAdmin-1-small.gif]]
# Tell Xataface some DB connection info, and voila! You have an application:
##[[Image:http://xataface.com/documentation/tutorial/getting_started/new-record-form-1-small.gif]]

===Where to go from here===

This tutorial will teach you the basics of Xataface and how to construct a simple application using the Xataface. After reading this tutorial you will be ready to tackle some medium to large web sites with the help of the Xataface reference documentation. You are also encouraged to mail the [http://xataface.com/forum Xataface forum] if you have questions.</content>
	<keywords>introduction requirements getting started</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=70">
	<page_name>documentation_guide</page_name>
	<page_id>70</page_id>
	<page_title>Documentation Guide</page_title>
	<content>Xataface uses a wiki to manage its online documentation which can be edited by anyone.  All you have to do is [http://xataface.com/wiki/index.php?-action=login login with your forum username and password] ([http://xataface.com/forum/profile.php?mode=register register for the forum here]).  Then when you are browsing a page of the wiki, you&apos;ll see an &apos;Edit&apos; tab along the top.  Click on this tab to start editing the page in your browser.  Wiki markup is a little simpler than HTML and a little more complex than plain text.  It is easy to get a handle on once you get started.  If you aren&apos;t sure how to format it exactly how you want, don&apos;t worry.  Someone may come by after you and improve on your formatting.  That&apos;s what the community approach is all about.

==The Documentation Team==

Join the Xataface documentation team to help participate in the planning of the documentation.  If you want to help out, contact [mailto:steve@weblite.ca Steve Hannah] and he&apos;ll add you to the documentation group where you can access the private documentation forums and meet the rest of the team.

==Using the Wiki==

The following is a brief guide in using the Xataface Wiki.  All following instructions assume that you are already [http://xataface.com/wiki/index.php?-action=login logged in] to the wiki.  You can use your forum username and password to login.

===Editing an Existing Page===

# Navigate to the page that you want to edit
# Click on the &quot;Edit&quot; tab along the top.
# Make changes to your page.
# Save the changes.

===Adding a New Page===

====Method 1: Add a link from an existing page===

# Navigate to an existing page that you want to link to your new page.
# Click on the &quot;Edit&quot; tab along the top.
# Somewhere in the content of the page, add a link to your new page (which doesn&apos;t exist yet), by adding the following markup&lt;code&gt;
[[The name of your new page]]
&lt;/code&gt;
# Save your changes.
# Click on the &quot;view&quot; tab along the top and find the place where you added your link.  It should be displayed with a &apos;?&apos; right after it.  Click on the &apos;?&apos; and it will bring you to the &quot;new page form&quot;.
# fill in the form with your page contents and click save.

====Method 2: Accessing new page form directly====

# Access the [http://xataface.com/wiki/index.php?-action=new&amp;-table=wiki new page form] directly.


===Uploading Images===

Image can be uploaded at [http://media.weblite.ca The Web Lite Media Manager].  You&apos;ll need an account to access this site.  If you are a member of the documentation team you can request an account from [mailto:steve@weblite.ca Steve Hannah] so that you can upload images here.

Steps:

# Log into [http://media.weblite.ca the Web Lite Media Manager].
# Click on &quot;Add New File&quot; in the menu on the left.
# Select a name for the file, and browse to the image you want to upload in the file upload field.  You don&apos;t need to check any category boxes.  Press save.
# Click on the &quot;View&quot; tab for your newly uploaded image.
# Copy the embed code for the image from the &quot;Embed Code&quot; field.
# In the wiki page add the embed code where you want your image to appear as follows:&lt;code&gt;
[[Image:EMBED_CODE]]
&lt;/code&gt; Where EMBED_CODE is the URL for the image as you copied and pasted out of the media manager.
# Save your changes.

===Uploading Video===

===Adding Source Code Snippets===</content>
	<keywords>documentation wiki</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=69">
	<page_name>checkbox</page_name>
	<page_id>69</page_id>
	<page_title>checkbox</page_title>
	<content>==The checkbox widget==

In the [[fields.ini file]] you can specify a field to be edited using a checkbox widget by setting [[widget:type]] to [[checkbox]].  A checkbox widget can function in 2 different ways depending on the parameters that you assign to the field.

[[toc]]

===Example 1: A TinyInt (boolean) field===

Suppose our table has a tinyint field named &quot;Active&quot; which specifies whether the record is currently in use.  This field will store a value of either 0 or 1.  So we configure this field in our [[fields.ini]] file to use a checkbox widget as follows:

&lt;code&gt;
[Active]
  widget:type=checkbox
&lt;/code&gt;

Results:

[[Image:http://media.weblite.ca/files/photos/Picture%2024.png?max_width=640]]

===Example 2: A repeating field (multiple checkboxes for one field===

Checkboxes can store multiple values in a single field by setting the [[vocabulary]] directive and applying it to a varchar or text field.  In this case there will be one value saved per line.  

In this example, suppose we have a varchar field named &apos;&apos;&apos;categories&apos;&apos;&apos; which uses the &apos;&apos;&apos;categories&apos;&apos;&apos; [[valuelist]] to specify the different categories that can be checked at any given time.  Our [[valuelists.ini file]] might look like:
&lt;code&gt;
[categories]
    __sql__ = &quot;select id,name from categories&quot;
&lt;/code&gt;

And our [[fields.ini file]] looks like:
&lt;code&gt;
[categories]
    widget:type=checkbox
    vocabulary=categories
&lt;/code&gt;
* Note that you don&apos;t need to name the field the same as the valuelist.  It just worked out this way.

Now if we save a record with categories 1, 3, and 5 checked, then the categories column of our row in the database will store something like:
&lt;code&gt;
1
3
5
&lt;/code&gt;
i.e. one category id per line.  Note that using this method, your database will not be normalized because you are storing multiple values in a single field.  However in many applications this is sufficient.

Results:

[[Image:http://media.weblite.ca/files/photos/Picture%2025.png?max_width=640]]

===Example 3: Using a &quot;Categories&quot; relationship===

&quot;&quot;&quot;(Note: This example requires Xataface version 1.2 or higher)&quot;&quot;&quot;

Example 2 above shows how we can easily add and remove a record from multiple categories using checkboxes.  However it required multiple pieces of information to be stored in a single database field which may or may not be advantageous for your database design.  If you&apos;re looking for a more normalized database schema you would probably design your database as follows for this case:

# Books table - Stores all of the books.
# Categories table - Stores all of the categories
# Book_Categories table - Stores mapping of books to categories.

With out table structure we will first want to define a relationship from Books to Categories to reflect the connection between books and categories.  The [[relationships.ini file]] for this might look like:

&lt;code&gt;
[categories]
    Books.Book_ID=&quot;$Book_ID&quot;
    Book_Categories.Category_ID=Categories.Category_ID
&lt;/code&gt;

And our [[fields.ini file]] for the Books table might look like:
&lt;code&gt;
[categories]
    widget:type=checkbox
    transient=1
    relationship=categories
&lt;/code&gt;
* Note that there is no need for our field to be named the same as our relationship.  It just turned out this way.  Also note that we used the transient=1 flag here because the Books table no longer has a categories field in the database.  This field is defined purely for the benefit of the edit form so that we will get a checkbox group to select the book&apos;s categories.

Results:
[[Image:http://media.weblite.ca/files/photos/Picture%2025.png?max_width=640]]

==Related Parameters==

# [[vocabulary]] - Assigns a valuelist to be used as the options for this checkbox group.
# [[repeat]] - A boolean value indicating whether this field should be treated as a &apos;repeating field&apos;.  A repeating field is one with multiple checkboxes.  By default the checkbox widget operates as a single checkbox that controls a boolean value.
# [[relationship]] - (Only applicable to [[transient]] fields).  If the [[relationship]] directive is set then this field can be used to add/remove records from a relationship.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=68">
	<page_name>relationship</page_name>
	<page_id>68</page_id>
	<page_title>The relationship fields.ini directive</page_title>
	<content>[[fields.ini file|Return to fields.ini file directives]]

[[toc]]

===Synopsis===

Certain types of widgets (e.g. grid (v1.0) and checkbox (v1.2)) support the relationship directive which allows them to effectively add/remove records from a specified relationship.  This directive only works with transient fields.

===Example 1: Checkboxes to add/remove categories===

(Note: This example requires Xataface 1.2 or higher to work)

Suppose we have a database that keeps track of courses and the branch of research that they belong to.  A course can be part of multiple branches.  We want to be able to select the branches that a particular course belongs to on the edit form for that course using checkboxes.

Table Structure:
&lt;code&gt;
courses:
   course_id : int (primary key)
   course_title : varchar

branches:
   branch_id : int (primary key)
   branch_name : varchar
   branch_description: text

course_branches:
   course_id : int
   branch_id : int
&lt;/code&gt;

Relationship definition:  (from the tables/courses/[[relationships.ini file]]):
&lt;code&gt;
[branches]
    course_branches.course_id=&quot;$course_id&quot;
    course_branches.branch_id=branches.branch_id
&lt;/code&gt;

Field definitions: (from tables/courses/[[fields.ini file]]):
&lt;code&gt;
[branches]
  transient=1
  relationship=branches
  widget:type=checkbox
&lt;/code&gt;

Things to notice:
# This is a many-to-many relationship (hence the need for the course_branches join table.
# The [branches] field is a transient field.
# The relationship directive from the [[fields.ini file]] references our branches relationship that was defined in the [[relationships.ini file]].
# You can call the field anything that you like.  There is no need for it to have the same name as the relationship.  It just turned out that way in this example.  

===Example 2: Using a grid widget===

Let&apos;s modify example 1 slightly to use a grid widget instead of checkboxes.  The grid widget will allow us edit the records in a relationship using dynamic table.  It automatically uses the correct widget for each column of the table according to the definition in the target table&apos;s [[fields.ini file]].  Most of the definition can remain the same.  We only change the [[fields.ini file]] directive:

&lt;code&gt;
[branches]
  transient=1
  relationship=branches
  widget:type=grid
  widget:columns=&quot;branch_name,branch_description&quot;
&lt;/code&gt;

In this case we are able to edit the branch name and description in each row of the grid.

===See Also===

* [[grid|The grid widget]]
* [[checkbox|The checkbox widget]]
* [[relationships.ini file|The relationships.ini file]]
* [[fields.ini file|The fields.ini file]]</content>
	<keywords>grid widget, relationship, checkbox</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=67">
	<page_name>grid</page_name>
	<page_id>67</page_id>
	<page_title>grid</page_title>
	<content>==widget:type = grid==

Suppose we have two tables, tbl_organisation and tbl_individuals, in the edit view for a record in the organisations table (tbl_organisations) we also want to be able to view and edit the individuals within this organisation we can use widget:type=grid

In the /tables/tbl_organisation/fields.ini we create a transient field by adding:

&lt;code&gt;
[Individuals]
widget:label = &quot;Individuals&quot;
transient=1
relationship=individuals
widget:type=grid
widget:columns=&quot;ind_firstname,ind_lastname,ind_tel&quot;
&lt;/code&gt;

The above assumes we have a relationship entry in our /tables/tbl_organisation/relationships.ini that looks like this:

&lt;code&gt;
[individuals]
__sql__ = &quot;SELECT * FROM tbl_individual WHERE org_id=&apos;$org_id&apos;&quot;
&lt;/code&gt;

The fields.ini will show the three columns shown in widget:columns from the table tbl_individual

Correct permissions need to be set to enable editing and deletion etc of these records.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=66">
	<page_name>table</page_name>
	<page_id>66</page_id>
	<page_title>table</page_title>
	<content>When using widget:type table, it will store the data as XML.

So the field type must be TEXT (or varchar... but text is better). You can decide which columns you want in the table by creating sub-fields in your fields.ini file as follows:

Suppose you want a column called &apos;name&apos; and a column called &apos;url&apos;

&lt;code&gt;
[myfield]
widget:type=table
[myfield:name]
[myfield:url]
&lt;/code&gt;

Now when you access the stored value using the Dataface API, the value of myfield will be stored as an array of associative arrays. e.g. 

&lt;code&gt;
foreach ( $record-&gt;val(&apos;myfield&apos;) as $vals){ echo $vals[&apos;name&apos;].&apos; -- &apos;.$vals[&apos;url&apos;]; }
&lt;/code&gt;</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=65">
	<page_name>LDAP_or_Active_Directory</page_name>
	<page_id>65</page_id>
	<page_title>How to authenticate users with LDAP or Active Directory</page_title>
	<content>[[toc]]

It is often easier to use the existing LDAP or Active Directory to authenticate users in Xataface than to create a new password for every user in the table users.

===In the conf.ini===

In the conf.ini file, in the [auth] part, you need to add your LDAP or AD configuration data :

&lt;code&gt;[_auth]
auth_type=ldap
users_table = xata_users
username_column = id
	ldap_host = &quot;xxx.xxx.xxx.xxx&quot;
	ldap_port = &quot;389&quot;
	ldap_base = &quot;OU=blabla,DC=blablabla&quot;&lt;/code&gt;

Here in the table users, you need the login but the password can be just &apos;&apos;PASS&apos;&apos;, because the password will be fetched into the LDAP base.
You need to add the [http://weblite.ca/svn/dataface/modules/Auth/ldap/trunk/ auth module] in the conf/modules directory.

===See Also===

* [[authentication]] - Overview of Authenthentication features in Xataface</content>
	<keywords>LDAP,Active Directory,Authentication</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=64">
	<page_name>How_to_authenticate_users_with_LDAP_or_Active_Directory</page_name>
	<page_id>64</page_id>
	<page_title>How_to_authenticate_users_with_LDAP_or_Active_Directory</page_title>
	<content>==How to authenticate users with LDAP or Active Directory==

</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=63">
	<page_name>How_to_granulate_permissions_on_each_field</page_name>
	<page_id>63</page_id>
	<page_title>How_to_granulate_permissions_on_each_field</page_title>
	<content>==How to granulate permissions on each field==

To reach this aim, there is the method fieldname__permissions to place into the delegate class of the table. 

===Getting the role===

First it is necessary to know the user&apos;s role. For this, the method getUser() is added in the class :
&lt;code&gt;function getUser(&amp;$record){
  $auth =&amp; Dataface_AuthenticationTool::getInstance();
    $user =&amp; $auth-&gt;getLoggedInUser();
return $user;
}&lt;/code&gt;


===Setting up the permissions for each field===

Next, the permissions are built for each column or field where they are needed, like in this example where the method name is formed with the field name, followed by 2 underscores then by &apos;&apos;permissions&apos;&apos; :

&lt;code&gt;function fieldname__permissions(&amp;$record){

$the_user =$this-&gt;getUser($record);
$user=$the_user-&gt;val(&apos;identifiant&apos;);
if ( !$user) return Dataface_PermissionsTool::NO_ACCESS();

    if ( $user==&apos;demande&apos; ){
        return Dataface_PermissionsTool::ALL();
    } elseif ($user==&apos;admin&apos;){
 return Dataface_PermissionsTool::ALL();
}
else {
        return Dataface_PermissionsTool::READ_ONLY();
    }
}&lt;/code&gt;


=== Also See ===

* [[viewable_editable_fields]] - How to make a field editable for some users and only viewable for some other users  
* [[no_access_text]] - Replace the default NO ACCESS permission text with another text.
* [[__field__permissions]] - Returns the default permissions for a field of a given record.
* [[Delegate_class_methods#toc5|Permissions]] - other Delegate class methods</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=62">
	<page_name>Customizing_the_look_and_feel_of_a_row_or_a_cell</page_name>
	<page_id>62</page_id>
	<page_title>Customizing_the_look_and_feel_of_a_row_or_a_cell</page_title>
	<content>==How to customize the look and feel of elements in the list view==

===Create a method in a delegate class===

In the delegate class, the method &apos;&apos;css__tableRowClass&apos;&apos; is implemented, like in this example :

&lt;code&gt;class tables_journal_interventions {
function css__tableRowClass(&amp;$record){
    if ( !$record-&gt;val(&apos;fermeture&apos;)){
        return &apos;intervention_close&apos;;
    }
    else return &apos;&apos;;
} 
}
&lt;/code&gt;

Here the function tests a condition : is there a value in the field &apos;&apos;fermeture&apos;&apos; ?

===Add the class in a CSS stylesheet===

Now the class is created in a CSS stylesheet.

&lt;code&gt;td.intervention_close {
        background-color: #FFE6E6 !important;
    } &lt;/code&gt;

This is a class for each cell, the &lt;td&gt; tag. The &apos;&apos;!important&apos;&apos;  attribute is added to be sure that this information has precedence over all the others. It is better to add this class in a [http://xataface.com/documentation/how-to/custom_javascripts custom CSS stylesheet].

===Remarks===

Beware that some versions of IE don&apos;t respect the background-color property on the &lt;tr&gt; tag, so it is probably better to write:

&lt;code&gt;

    tr.intervention_close td {
        background-color: #FFE6E6;
    }&lt;/code&gt;

i.e. to apply the background color to the individual cells. </content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=61">
	<page_name>lookup</page_name>
	<page_id>61</page_id>
	<page_title>The Lookup Widget</page_title>
	<content>Return to [[widget:type]] page to see list of all widget types.
Back to [[fields.ini file]] to see other fields.ini directives.

[[toc]]

===Synopsis===

The lookup widget allows users to look a record from another table to insert into the field.  It is like a select widget except that it doesn&apos;t use a vocabulary.  Instead you just specify a table on which it should search using the widget:table directive.  In order to use the lookup widget to edit a field, you should set the [[widget:type]] directive of the [[fields.ini file]] for the field to &apos;&apos;&apos;lookup&apos;&apos;.  I.e.
&lt;code&gt;
[fieldname]
    widget:type=lookup
    widget:table=mytable
&lt;/code&gt;

&apos;&apos;&apos;Note that the lookup widget requires the [[widget:table]] directive to be set to the target table of the lookup or it will not work properly.&apos;&apos;&apos;

===Required Directives===

The following [[fields.ini file]] directives are required to accompany the field definition if a lookup widget is used:

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Version
|-
| widget:table
| The name of the table in which the lookup widget should look up related records.
| 1.0
|}


===Optional Directives===

The following additional optional directives may be used to customize the behaviour of the lookup widget:

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Version
|-
| widget:filters:-limit
| Sets the number of records that are shown by default in the lookup widget.  Default is 30 if this is omitted. E.g.&lt;code&gt;widget:filters:-limit=100&lt;/code&gt; to show 100 records at a time.
| 1.0
|-
| widget:filters:-sort
| Specifies the columns to sort the results on. E.g. &lt;code&gt;widget:filters:-sort=category_name asc, year desc&lt;/code&gt;
| 1.0
|-
| widget:filters:*
| Any valid Xataface directive can be used to filter the results by specifying widget:filters:param  (where &quot;param&quot; is a valid Xataface GET parameter, which could include a column name to filter results on, or other filter directives). &lt;code&gt;widget:filters:country=Canada&lt;/code&gt; To only show results with Country=Canada.
| 1.0
|-
| widget:filters:*=$*
| Dynamic filters.  Causes the options in the record browser to be filtered on the value of another field in the form.  e.g. &lt;code&gt;widget:filters:country_id=&quot;$country_id&quot;&lt;/code&gt; would show only results with records having country_id matching the value of the &apos;country_id&apos; field in the current form.
| 1.3.1
|}

See [[URL Conventions]] for an overview of the types of GET parameters Xataface can take.  Any GET parameters that manipulate a query can be used with the widget:filters:* directive to modify the query results that are shown in the lookup widget.


===Example===

In this example we have a field named appointee that is supposed to reference the contacts table.  So in the [[fields.ini file]] we would have:

&lt;pre&gt;
[appointee]
    widget:type=lookup
    widget:table=contacts
&lt;/pre&gt;

Initially we just have a little find icon next to the field. If the user clicks it, a dialog pops up enabling them to search for the contact that they want:

[[Image:http://media.weblite.ca/files/photos/Picture%2023.png?max_width=640]]


===Additional Tips===

Although the lookup widget does not use a vocabulary as indicated in the Synopsis above, it is still useful to define a vocabulary in the fields.ini file for this field. The reason is because the lookup widget is only used with the edit action, where you are inserting or editing data into the field. However, it is not used to the display the data in the view or list actions. Therefore, you must still have a vocabulary defined to properly display these values.

In order to customize the display of the lookup widget&apos;s select list, you must edit the delegate class for the table which is referenced by the widget:table directive. There are two important points to note:

# The items in the selection list are formatted based on the getTitle(&amp;$record) delegate class function if it is defined. However, ...
# The Search box will search on text in VARCHAR and TEXT fields. If you need to search for data in numeric fields, you can create a grafted field using a function such as CONCAT() to display numbers as text.

Links:
* [http://xataface.com/forum/viewtopic.php?f=4&amp;t=6723 Lookup widget on view with compound primary key]</content>
	<keywords>lookup widget, widget:filters, widget:-filters:limit, widget:table</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=60">
	<page_name>widget:type_textarea</page_name>
	<page_id>60</page_id>
	<page_title>widget:type_textarea</page_title>
	<content></content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=59">
	<page_name>no_access_text</page_name>
	<page_id>59</page_id>
	<page_title>no_access_text</page_title>
	<content>Whenever the NO_ACCESS permission is given for a field, normally the text NO ACCESS appears.  But we might want to display another text.  Here is an example of the text subscribe is used instead of NO ACCESS whenever the NO_ACCESS permissions is given.

&lt;code&gt;function no_access_text(&amp;$record){
		return &quot;Subscribe&quot;;
	}
&lt;/code&gt;</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=58">
	<page_name>Selected_Records_Actions</page_name>
	<page_id>58</page_id>
	<page_title>Selected_Records_Actions</page_title>
	<content>==Creating a Custom &apos;&apos;Selected Records&apos;&apos; Action==

[[toc]]

If you view the &apos;&apos;list&apos;&apos; tab in any of your Xataface applications, you&apos;ll notice that there is a checkbox next to each row of the list, and there are a number of actions listed at the bottom of the list that you can perform on the selected records.  Xataface comes pre-built with only a few of these actions:

# Delete selected
# Update selected
# Copy selected

However it is quite easy to add your own actions here that are performed on selected records.  This article describes exactly how to do this.

===What is a &apos;&apos;Selected Record&apos;&apos; action?===

A &apos;&apos;Selected Record&apos;&apos; action is no different than any other action in Xataface, except that it is meant to act on the records that have been selected in the list tab.

==Example Action:  Approve Records==

Consider a news site where news stories are automatically imported into the database en masse, but each news story has a field &apos;&apos;approved&apos;&apos; to indicate whether the store has been approved to appear on the site yet.   The usage pattern of this application involves a lot of looking through lists of news stories and approving them.  Therefore it would be convenient if the user could just select the rows that he wants to approve and click a button to approve them all.

Out of the box Xataface would allow the user to select the records, click &apos;&apos;update selected records&apos;&apos;, then update them all via the &apos;&apos;update selected records&apos;&apos; form.  But avoiding this extra step will improve usability greatly.

===Step 1: Design the Action===

First we need to specifically decide how our action will work.  In this case, the flow goes as follows:

# User selects the news items they want to approve.
# User clicks the &apos;&apos;Approve Selected&apos;&apos; button. (to be created)
# Our action approves the selected records.
# User is automatically redirected back to the list tab with a message stating how many records were successfully approved, and whether there were any errors.

===Step 2: Gather Our Tools===

Before we actually create the action, let&apos;s look at a few tools that we&apos;ll be using from the Xataface framework to make this happen.

# In the [[actions.ini file]], the &apos;&apos;[[selected_result_actions]]&apos;&apos; category is reserved for actions that act on selected records of the list tab.  E.g.&lt;code&gt;
[delete_selected]
    ...
    category=selected_result_actions
    ...
&lt;/code&gt;
# The [http://dataface.weblite.ca/df_get_selected_records df_get_selected_records()] function returns an array of [http://dataface.weblite.ca/Dataface_Record Dataface_Record] objects that represent the rows that were selected to initiate the action.  E.g.&lt;code&gt;
$app =&amp; Dataface_Application::getInstance();
$query =&amp; $app-&gt;getQuery();
$records = df_get_selected_records($query);
foreach ($records as $record){
    ...
}
&lt;/code&gt;
# The [http://dataface.weblite.ca/checkPermission Dataface_Record::checkPermission()] method allows us to see if the current user has access to a specific permission on the given record.  We&apos;ll use this method to ensure that the user has permission to approve the news record. E.g.&lt;code&gt;
if ( !$record-&gt;checkPermission(&apos;edit&apos;, array(&apos;field&apos;=&gt;&apos;approved&apos;)) ){
    return PEAR::raiseError(&quot;You don&apos;t have permission to edit the approved field for this record.&quot;);
}
&lt;/code&gt;
# The Xataface will pass the redirect URL where your action should send the user upon completion of the action as the &apos;&apos;--redirect&apos;&apos; attribute of the &apos;&apos;POST&apos;&apos; variables.  This value is base64_encoded so you&apos;ll need to decode it before redirecting.  E.g.:&lt;code&gt;
if ( @$_POST[&apos;--redirect&apos;] ) 
    $url = base64_decode($_POST[&apos;--redirect&apos;]);
$url .= &apos;&amp;--msg=&apos;.urlencode($updated.&apos; records were deleted.&apos;);
header(&apos;Location: &apos;.$url);
exit;
&lt;/code&gt;

===Step 3: Create the Action===

We will call our action &apos;&apos;approve_news&apos;&apos; so we&apos;ll place it in the &apos;&apos;actions/approve_news.php&apos;&apos; file of our application:
&lt;code&gt;
&lt;?php
class actions_approve_news {
    function handle(&amp;$params){
        // First get the selected records
        $app =&amp; Dataface_Application::getInstance();
        $query =&amp; $app-&gt;getQuery();
        $records =&amp; df_get_selected_records($query);

        $updated = 0;  // Count the number of records we update
        $errs = array();   // Log the errors we encounter

        foreach ($records as $rec){
            if ( !$rec-&gt;checkPermission(&apos;edit&apos;), array(&apos;field&apos;=&gt;&apos;approved&apos;)) ){
                $errs[] = Dataface_Error::permissionDenied(
                    &quot;You do not have permission to approve &apos;&quot;.
                    $rec-&gt;getTitle().
                    &quot;&apos; because you do not have the &apos;edit&apos; permission.&quot;);
                continue;
            }
            $rec-&gt;setValue(&apos;approved&apos;, 1);
 
            $res = $rec-&gt;save(true /*secure*/);
            if ( PEAR::isError($res) ) $errs[] = $res-&gt;getMessage();
            else $updated++;
            
        }
        
        if ( $errs ){
            // Errors occurred.  Let&apos;s let the user know.
            // The $_SESSION[&apos;--msg&apos;] content will be displayed to the user as a message
            // in the next page request.
            $_SESSION[&apos;--msg&apos;] = &apos;Errors Occurred:&lt;br/&gt; &apos;.implode(&apos;&lt;br/&gt; &apos;, $errs);
        } else {
            $_SESSION[&apos;--msg&apos;] = &quot;No errors occurred&quot;;
        }
        

        $url = $app-&gt;url(&apos;-action=list&apos;);   // A default URL in case no redirect was supplied
        if ( @$_POST[&apos;--redirect&apos;] ) $url = base64_decode($_POST[&apos;--redirect&apos;]);
        $url .= &apos;&amp;--msg=&apos;.urlencode($updated.&apos; records were deleted.&apos;);

        // Redirect back to the previous page
        header(&apos;Location: &apos;.$url);
        exit;
    }
}
&lt;/code&gt;

===Step 4: Add the action to your actions.ini file===

The actions.ini file allows us to specify how and where this action is used, and by whom.  We can specify permissions that are required to perform the action, conditions that are required to display the action, confirmation messages that are to be displayed to the user when they are about to perform the action, and more.  Our [[actions.ini file]] entry looks like:

&lt;code&gt;
[approve_news]
    label=&quot;Approve&quot;
    description=&quot;Approve selected records&quot;
    permission = edit
    category=selected_result_actions
    confirm=&quot;Are you sure you want to approve the selected records?&quot;
    icon=&quot;${dataface_site_url}/images/approve.gif&quot;
    condition=&quot;$query[&apos;-table&apos;] == &apos;news&apos;&quot;
&lt;/code&gt;

This should be fairly straight forward.  The only special items here are the &apos;&apos;category&apos;&apos; and &apos;&apos;confirm&apos;&apos; directives.  The &apos;&apos;condition&apos;&apos; directive tells Xataface that this action should only be shown for the &apos;&apos;news&apos;&apos; table. 

The &apos;&apos;confirm&apos;&apos; directive defines a confirmation message that should be displayed to the user when they attempt to approve records.

The &apos;&apos;icon&apos;&apos; directive allows you to specify the path to an icon to display for the action.  In our case we have an icon located in the images directory of our application.

===Step 5: Trying it out===

Now when we go to the &apos;&apos;list&apos;&apos; tab of the &apos;&apos;news&apos;&apos; table there is an &apos;&apos;Approve&apos;&apos; button along the bottom where it says &quot;With Selected&quot;.  You we can click on this button to approve any of the selected rows.


	</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=57">
	<page_name>Creating_a_Dashboard</page_name>
	<page_id>57</page_id>
	<page_title>Creating_a_Dashboard</page_title>
	<content>==Creating a Dashboard for your Users==

[[toc]]

Xataface allows you to build powerful data-driven applications quickly, but these applications may be daunting to your users if they don&apos;t know what they can do with the application.  Most applications provide some sort of dashboard or control panel with some introductory instructions and links to commonly used actions in the application.  This makes the application more intuitive for users so that they can start using it right away, even without instruction from the developer.

===Characteristics of a Dashboard===

# Should be the default page when someone visits the application.
# Should be customized to show menus and content that are relevant to the current user.  (i.e. different users may see different links and content on their dashboard).
# Should contain at least some basic instructions so that the user understands what the application does when he visits the dashboard for the first time.
# Should contain links to frequently used actions.

===Strategies: 8 ways to skin the cat===

There are many viable strategies for adding a dashboard to your Xataface application.  This article presents only one.  It has been chosen because it satisfies all of the desired characteristics of a dashboard listed above, and it is easy to implement.

This strategy involves the following components:

# Create a dummy &apos;&apos;dashboard&apos;&apos; table.
# Create a dashboard action and associated template.
# Make sure our dashboard action is the default action for our application (more complex than just using the [[default_action]] directive in the [[conf.ini file]].

==Our Sample Application==

Consider our sample application, a publications management system for professors and research groups at a university.  It allows users to manage their publications using either BibTex format or a web-based form, and embed those publications into their webpage in a slick sortable format.  Currently, when the user accesses the application for the first time, they are shown the &apos;&apos;list&apos;&apos; tab of the &apos;&apos;bibliographies&apos;&apos; table.  This isn&apos;t all that informative and it may not be obvious to the user that their first step should be to create a new bibliography via the &apos;&apos;new record&apos;&apos; button.  Ideally we would like the user to go directly to a dashboard page with options to:

# Add New Bibliography
# Edit an Existing Bibliography
# Embed a Bibliography into their Webpage

And we want some basic instructions so that the user knows what to do when they first access the page.

==The Steps==

To create this dashboard we will follow the steps listed below (and mentioned above in the &apos;&apos;strategies&apos;&apos; section.

===Step 1: Create a dummy &apos;&apos;dashboard&apos;&apos; table===

This may seem unorthodox but it just happens to make our lives easier in the long run.  By creating a dummy table we are able to cause that table to be listed first in the &apos;&apos;_tables&apos;&apos; section of the [[conf.ini file]] and thus be the default table when users visit our application.

&lt;code&gt;
CREATE TABLE dashboard (
    dashboard_id int(11) not null auto_increment primary key
);
INSERT INTO dashboard values (1);
&lt;/code&gt;

===Step 2: Make &apos;&apos;dashboard&apos;&apos; table default===

We now modify the conf.ini file to list the &apos;&apos;dashboard&apos;&apos; table first:
&lt;code&gt;
[_tables]
    dashboard=Dashboard
    bibliographies=Bibliographies
&lt;/code&gt;

===Step 3: Create a Dashboard action and associated template===

This is the step where we actually create our dashboard action.  There are three parts to this story:

====Creating Action PHP Class====

The actual action will be located in the &apos;&apos;actions/dashboard.php&apos;&apos; file of our application, and looks like:

&lt;code&gt;
&lt;?php
class actions_dashboard {
    function handle(&amp;$params){
        $bibs = df_get_records_array(&apos;bibliographies&apos;, array());
        df_display(array(&apos;bibliographies&apos;=&gt;$bibs), &apos;dashboard.html&apos;);
    }
}
&lt;/code&gt;

All this does is loads the &apos;&apos;bibliographies&apos;&apos; records owned by the current user. Elsewhere we are using security filters so that the user can only see &apos;&apos;his&apos;&apos; bibliographies, which is why we don&apos;t need to specify any query here in the &apos;&apos;df_get_records_array&apos;&apos; function.

It then passes those bibliographies to the &apos;&apos;dashboard.html&apos;&apos; template that we create next.

====Creating the Action&apos;s Template====

The template for our action is located in the &apos;&apos;templates/dashboard.html&apos;&apos; file:
&lt;code&gt;
{use_macro file=&quot;Dataface_Main_Template.html&quot;}
    {fill_slot name=&quot;main_column&quot;}
        &lt;h1&gt;Welcome to the BibTeX Publication Management System (BPMS)&lt;/h1&gt;
        
        &lt;p&gt;This system allows you to manage your publications and publish
        them on the web.  Some common actions you may perform with this system
        include:
            &lt;ul&gt;
                &lt;li&gt;&lt;img src=&quot;{$ENV.DATAFACE_URL}/images/add_icon.gif&quot;/&gt;
                    &lt;a href=&quot;{$ENV.DATAFACE_SITE_HREF}?-table=bibliographies&amp;-action=new&quot;&gt;
                        Create New Bibliography&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;&lt;img src=&quot;{$ENV.DATAFACE_URL}/images/edit.gif&quot;/&gt; 
                   Edit existing bibliography: 
                   &lt;select onchange=&quot;window.location.href=this.options[this.selectedIndex].value&quot;&gt;
                    &lt;option value=&quot;&quot;&gt;Select ...&lt;/option&gt;
                    {foreach from=$bibliographies item=bibliography}
                        &lt;option value=&quot;{$bibliography-&gt;getURL(&apos;-action=edit&apos;)}&quot;&gt;
                            {$bibliography-&gt;getTitle()}
                        &lt;/option&gt;
                    
                    {/foreach}
                &lt;/select&gt;
                &lt;/li&gt;
                &lt;li&gt;&lt;img src=&quot;{$ENV.DATAFACE_URL}/images/file.gif&quot;/&gt; 
                    Embed your bibliography in a webpage:
                    &lt;select onchange=&quot;window.location.href=this.options[this.selectedIndex].value&quot;&gt;
                    &lt;option value=&quot;&quot;&gt;Select ...&lt;/option&gt;
                    {foreach from=$bibliographies item=bibliography}
                        &lt;option value=&quot;{$bibliography-&gt;getURL(&apos;-action=view&apos;)}#embed&quot;&gt;
                            {$bibliography-&gt;getTitle()}
                        &lt;/option&gt;
                    
                {/foreach}
                &lt;/select&gt;
                &lt;/li&gt;
                
            &lt;/ul&gt;
    {/fill_slot}
{/use_macro}
&lt;/code&gt;

A few key things to notice in this template:

# It extends the &apos;&apos;Dataface_Main_Template.html&apos;&apos; template placing its content in the &apos;&apos;main_column&apos;&apos; slot.  This allows our action to still display within the header and footer of our application.
# It makes use of the {$ENV.DATAFACE_SITE_URL} and {$ENV.DATAFACE_SITE_HREF} variables to refer to the site&apos;s base url and create links to the desired common actions.
# It provides a direct link to the &apos;&apos;new bibliography record&apos;&apos; form.
# It uses some slick javascript combined with select lists to allow the user to select any of his current bibliogaphies and edit them, or embed them into a webpage.

====Adding entry to the actions.ini file====

Currently our dashboard action has no permissions attached to it so users can see it whether they are logged in or not.  In this particular application we want to require users to log in, and we have set permissions for all logged in users to NO_ACCESS().  Unfortunately this permission setting is only helpful if our action requires a particular permission to access it.  We&apos;ll require the &apos;view&apos; permission for this action, by adding the following to the actions.ini file:

&lt;code&gt;
[dashboard]
    permission=view
&lt;/code&gt;


===Step 4: Specify permissions===

We still want to specify permissions for our &apos;&apos;dashboard&apos;&apos; table to ensure that only logged in users can access the dashboard.  So we create a delegate class for the &apos;&apos;dashboard&apos;&apos; table at &apos;&apos;tables/dashboard/dashboard.php&apos;&apos; with the following contents:

&lt;code&gt;
&lt;?php
class tables_dashboard {
    function getPermissions(&amp;$record){
        if ( getUser() ){
            return Dataface_PermissionsTool::ALL();
        }
        return null;
    }
}
&lt;/code&gt;

&apos;&apos;&apos;Note that we have defined the getUser() function elsewhere as a means of obtaining the current user and checking if a user is indeed logged in.&apos;&apos;&apos;

Notice that this [[getPermissions]] method returns all permissions only if the user is logged in.  Otherwise it returns null, which means that it should use the same permissions as the rest of the application as defined in the [[Application Delegate Class]].

===Step 6: Make &apos;&apos;dashboard&apos;&apos; the default action for the &apos;&apos;dashboard&apos;&apos; table===

Now we just have one more detail that needs to be taken care of.  We want the &apos;&apos;dashboard&apos;&apos; action to be the default action for the &apos;&apos;dashboard&apos;&apos; table only.  By default we would see the &apos;&apos;list&apos;&apos; action which isn&apos;t helpful at all, so we will want to add a rule in our application delegate class to ensure that the user only sees our custom &apos;&apos;dashboard&apos;&apos; action if they access the &apos;&apos;dashboard&apos;&apos; table.  We define a beforeHandleRequest() method in our conf/ApplicationDelegate.php (the application delegate class) file for this purpose:

&lt;code&gt;
&lt;?php
class conf_ApplicationDelegate {
    
...
    function beforeHandleRequest(){
        ...
        $app =&amp; Dataface_Application::getInstance();
	$query =&amp; $app-&gt;getQuery();
	if ( $query[&apos;-table&apos;] == &apos;dashboard&apos; and ($query[&apos;-action&apos;] == &apos;browse&apos; or $query[&apos;-action&apos;] == &apos;list&apos;) ){
	    $query[&apos;-action&apos;] = &apos;dashboard&apos;;
	}
        
        
    }
    
    ...
}
&lt;/code&gt;

This simply checks to see if the table is &apos;&apos;dashboard&apos;&apos; and changes the current action to &apos;&apos;dashboard&apos;&apos; if so.

===Step 7: Try it out===

At this point, we are ready to try out our new dashboard to see how it works.  When we load our application it should now go to the dashboard action that we created.  We should also see &apos;&apos;Dashboard&apos;&apos; listed as the first table in the tables menu.

This dashboard presents a major improvement to our application as it is now much more user friendly.

&lt;nowiki&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/pub-dashboard.png?max_width=640&quot;/&gt;
&lt;/nowiki&gt;</content>
	<keywords>dashboard</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=56">
	<page_name>struct</page_name>
	<page_id>56</page_id>
	<page_title>struct</page_title>
	<content></content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=55">
	<page_name>blob</page_name>
	<page_id>55</page_id>
	<page_title>blob</page_title>
	<content></content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=54">
	<page_name>Email</page_name>
	<page_id>54</page_id>
	<page_title>Email</page_title>
	<content>==Xataface Email Module==

[[toc]]

The Xataface Email module allows you to convert your database into a mailing list so that you can easily send email to any found set of records, as long as the records contain an email address to send to.

==Features==

* Send email to any found set.
* Mail merge macros
* HTML Email support (uses NicEdit WYSIWYG editor for email editing).
* Opt out support (allows recipients to opt out of your mailing list).

==Requirements==

* Xataface 1.0+
* MySQL 4.1+
* PHP 5+

==Download==

https://sourceforge.net/project/platformdownload.php?group_id=253820

==Installation==

# Download and extract Email directory so that it is located inside the xataface/modules directory (i.e. xataface/modules/Email)
# Add the following to the &apos;&apos;[_modules]&apos;&apos; section of your application&apos;s conf.ini file:&lt;code&gt;
modules_Email=&quot;modules/Email/Email.php&quot;
&lt;/code&gt;
# Configure the [email] action in your application&apos;s actions.ini file.  See the section called &apos;Configuration&apos; for configuration details.
# Add a line to your crontab file to send out pending email periodically.  The line should look like:&lt;code&gt;
* * * * * /usr/bin/php &lt;cronpath&gt; &lt;indexpath&gt; &lt;indexurl&gt; mail

where &lt;cronpath&gt; is the absolute path to the cron.php script.
      &lt;indexpath&gt; is the absolute path to your application&apos;s index.php script.
      &lt;indexurl&gt; is the absolute url to your application&apos;s index.php script.
		
For example:

* * * * * /usr/bin/php /var/www/xataface/modules/Email/cron.php \
		/var/www/myapp/index.php \
		http://example.com/myapp/index.php \
		mail
&lt;/code&gt; If you want to see what this line should be like for your server, you can simply point your browser to the email_install action of your application (i.e. http://example.com/yourapp/index.php?-action=email_install) and it will generate this line to copy and paste into your crontab.  Note that the /usr/bin/php portion of this line may vary according to your environment.  It represents the path to your PHP binary.
# That&apos;s it!  You&apos;re ready to send email.  See the &apos;&apos;Usage&apos;&apos; section to see how to send email from your application.

==Configuration==

Though the email action may work out of the box, you will likely have to configure it to work the way you want.  Some examples of things you will want to configure include:

# Limit the email action to only be available for certain tables.
# Apply permissions to the action so that only administrators can send email.
# Set the name of the column that contains email address (default is &apos;email&apos;).
# Change the name of the table that is used to store sent email messages.

===Overriding the &apos;&apos;[email]&apos;&apos; action===

The first thing you need to do to configure the email action is override it in your appliation&apos;s actions.ini file.  You can do this by adding the following to your [[actions.ini file]]:
&lt;code&gt;
[email &gt; email]
&lt;/code&gt;

Now any directives you add in this section will override the email action.

====Examples:====

=====Limiting email action to certain tables=====

In your appliation&apos;s [[actions.ini file]]:
&lt;code&gt;		
[email &gt; email]
    condition=&quot;$query[&apos;-table&apos;] == &apos;Pledge&apos; or $query[&apos;-table&apos;] == &apos;User&apos;&quot;
&lt;/code&gt;


=====Limiting email action by permission=====

By default your users require the &apos;&apos;email&apos;&apos; permission in order to have access to the email form.  This permission is not included with any roles by default so you&apos;ll need to extend any roles that you want to have access to the email access and explicitly add the &apos;&apos;email&apos;&apos; permission.  The exception to this rule is if you have assigned your users the &apos;&apos;Dataface_PermissionsTool::ALL()&apos;&apos; permissions in your &apos;&apos;getPermissions()&apos;&apos; method.

Suppose you want the &apos;&apos;READ ONLY&apos;&apos; role to have access to the email action, you could add the following to your application&apos;s [[permissions.ini file]]:
&lt;code&gt;
[READ ONLY extends READ ONLY]
     email=1
&lt;/code&gt;   			

=====Changing the name of the email address column=====

By default, the Email module will try to guess which column contains the email address for a table.  Generally it looks for a column named &apos;&apos;email&apos;&apos;.  You can override this setting to explicitly tell the module which column contains the email address by overriding the &apos;&apos;email_column&apos;&apos; directive of the &apos;&apos;email&apos;&apos; action in your application&apos;s [[actions.ini file]]:
&lt;code&gt;
[email &gt; email]
    email_column = &quot;emailAddress&quot;
&lt;/code&gt;

=====Changing the name of the table that stores the sent email====

Xataface automatically stores each sent email for your records.  By default it stores these emails in a table named &apos;&apos;newsletters&apos;&apos;.  You can override this table name with the &apos;&apos;email_table&apos;&apos; directive in your application&apos;s [[actions.ini file]].  This table will be automatically created by Xataface when email is sent out.
&lt;code&gt;
[email &gt; email]
    email_table = &quot;newsletters&quot;
&lt;/code&gt;
	
=====Altogether=====

&lt;code&gt;
[email &gt; email]
    condition=&quot;$query[&apos;-table&apos;] == &apos;Pledge&apos; or $query[&apos;-table&apos;] == &apos;User&apos;&quot;
    permission=email
    email_column = &quot;emailAddress&quot;
    email_table = &quot;newsletters&quot;
&lt;/code&gt;


==Usage:==

===Sending Email to All Records of a Table===

# Navigate to a table for which your email module is enabled, and click on the &apos;&apos;list&apos;&apos; tab.
# Click on the &quot;Email&quot; icon in the upper right corner.  This should display an email form.&lt;nowiki&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/email_icons.png&quot;/&gt;
&lt;/nowiki&gt;
# Fill in the email form and press Save.&lt;nowiki&gt;
&lt;div&gt;&lt;img src=&quot;http://media.weblite.ca/files/photos/email_form.png?max_width=500&quot;/&gt;&lt;/div&gt;
&lt;/nowiki&gt;
# You should receive a message saying that the email has been queued for delivery.  Your cron script will automatically begin sending emails the next time around.  So make sure that you have yoru cron script set up properly.

===Opting Out of the Email List===

If you have received an email that was sent via the email module you can easily opt out of the mailing list by clicking on the link at the end of the email.  This link will bring you to a webpage that asks you to confirm that you no longer wish to receive email from this list.



==Using a View to add Email Action to Related Record List==

You can simulate a many-to-many [[relationships.ini file|relationship]] in a mysql view by creating a view with all possible combinations. 

e.g. If you have a Many to Many [[relationships.ini file|relationship]] between books and authors your [[relationships.ini file|relationship]] from the books table might be something like: 

&lt;code&gt;

[authors] 
__sql__ = &quot;select * from authors a inner join book_authors ab on a.author_id=ab.author_id where ab.book_id=&apos;$book_id&apos;&quot; 

&lt;/code&gt;

And your relationship from the authors table would be something like: 
&lt;code&gt;
[books] 
__sql__ = &quot;select * from books b inner join book_authors ab on b.book_id=ab.book_id where ab.author_id=&apos;$author_id&apos;&quot; 
&lt;/code&gt;

Now if our goal was to be able to send email to all authors of a particular book (i.e. send to the authors relationship), we could create a view: 
&lt;code&gt;
create view book_authors_maillist as 
select * from authors a inner join book_authors ab on a.author_id=ab.author_id 
&lt;/code&gt;

This view can now be used in xataface like a regular table (if you add a [[fields.ini file]] for it and [[Key|mark the primary key columns]]). If you wanted to find all authors for a certain book you would just do: 

index.php?-action=list&amp;-table=book_authors_maillist&amp;book_id=10 

So you could easily create an action in the [[actions.ini file]] that would like to the mail action on the book_authors_maillist table with the parameters you wanted. 

e.g. 

&lt;code&gt;
[related_authors_mail] 
    category=related_list_actions 
    url=&quot;{$site_href}?-action=email&amp;-table=book_authors_maillist&amp;book_id={$record-&gt;val(&apos;book_id&apos;)}&quot; 
    icon=&quot;{$dataface_url}/images/mail_icon.gif&quot; 
    url_condition=&quot;$record&quot; 
    condition=&quot;$query[&apos;-table&apos;]==&apos;books&apos; and $query[&apos;-relationship&apos;] == &apos;authors&apos;&quot; 
    permission=&quot;email&quot; 
&lt;/code&gt;


This action would send mail to only the authors related to the current books. It would be made available in the icons in the upper right on the related list view of only the authors of a book.

===Mail Merge===

The &apos;Embed Macro&apos; shown above the email form lists the fields which may be included in the email.

Say you have a field called &apos;email_firstname&apos;. You would type this into the message area like this: %email_firstname%

When the email is sent, this is substituted for the record of that recipient.

Eg. Dear %email_firstname% would be received by email as Dear Tom

If the particular record of the field you are merging is blank, then (in this case) the first name will not be shown.</content>
	<keywords>Email,Email module,Sending Email,Maillist</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=53">
	<page_name>fieldname__permissions</page_name>
	<page_id>53</page_id>
	<page_title>fieldname__permissions</page_title>
	<content>==fieldname__permissions() method==

[[toc]]

The fieldname__permissions() methods will allow you to define custom permissions on a particular field in the [[delegate class]].  For example to specify permissions on a field named &apos;&apos;foo&apos;&apos; you would define the &apos;&apos;foo__permissions()&apos;&apos; method, and to define permissions on a field named &apos;&apos;role&apos;&apos; you would define the &apos;&apos;role__permissions()&apos;&apos; method.


==Example #1==

(Note this example needs to be refined to be more clear)

&lt;code&gt;
function approval_level__permissions(&amp;$record){
	return array(&apos;edit&apos;=&gt;0); //this is will merge with what the permissions for the normal record
}
&lt;/code&gt;

Here we are targeting the &apos;&apos;approval_level&apos;&apos; field of the [[delegate class]].  The permissions method takes a return value an array of permissions.  So for example:

&lt;code&gt;
$permissions[&apos;new&apos;] = 0;
$permissions[&apos;edit&apos;] = 0;
&lt;/code&gt;

Would be an example of an array of permissions which the key being the permission name and the value being a boolean to specify whether they have (1) or don&apos;t (0) have permissions to that field.  We don&apos;t have to specify a complete array of permissions (ie. permission of edit, new, readonly, etc, etc), but rather only the ones we want specifically.  The reason being that the permissions array in the return value gets merged with the permissions that this record normally gets from the record permissions.

So if the record normally gives the permissions new=0, edit=1.  Then the return value from approval_level will merge with the original permissions to produce an array like this:

&lt;code&gt;
$permissions[&apos;new&apos;] = 0;
$permissions[&apos;edit&apos;] = 1;
&lt;/code&gt;

=== Also See: ===

* [[How_to_granulate_permissions_on_each_field]]
* [[__field__permissions]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=52">
	<page_name>How_to_Add_Custom_Sections_to_View_Tab</page_name>
	<page_id>52</page_id>
	<page_title>How_to_Add_Custom_Sections_to_View_Tab</page_title>
	<content>==How to Add Custom Sections to the View tab==

[[toc]]

The &apos;&apos;View&apos;&apos; tab is intended to give the user a detailed view of the contents of a record.  By default it shows the values of each non-empty field grouped into their appropriate field groups.  It also shows the most recent 5 related records from each relationship in the record.  You can also add your own sections by implementing the [[section__xxx]] method of the delegate class.

==Example 1: A &quot;Hello World&quot; Section==

We&apos;ll start by adding a simple section that simply displays &quot;Hello World&quot; to the user.  In the delegate class for your table, add the following method:
&lt;code&gt;
function section__hello(&amp;$record){
    return array(
        &apos;content&apos; =&gt; &apos;Hello World!!!&apos;,
        &apos;class&apos; =&gt; &apos;main&apos;
    );
}
&lt;/code&gt;

Now if you reload our application and click on the &quot;View&quot; tab for any of the records in the database, you&apos;ll notice a section labelled &apos;&apos;hello&apos;&apos; with the text &apos;&apos;Hello World!!!&apos;&apos; in it.

Let&apos;s dissect the above code so that we can better understand what is going on here.

# The function &apos;&apos;section__hello()&apos;&apos; defines a section named &apos;&apos;hello&apos;&apos;.  If you wanted to define a section named &apos;&apos;foo&apos;&apos; you would call the function &apos;&apos;section__foo()&apos;&apos;
# This function returns an array with the keys &apos;&apos;content&apos;&apos;, and &apos;&apos;class&apos;&apos;.
# The &apos;&apos;content&apos;&apos; key points to the actual HTML content of the section.  In this case it is simply the text &apos;&apos;Hello World!!!&apos;&apos;.
# The &apos;&apos;class&apos;&apos; key defines where the section should be displayed.  It accepts values of &apos;&apos;left&apos;&apos; and &apos;&apos;main&apos;&apos; only.  If it is set to &apos;&apos;left&apos;&apos;, then the section will be displayed in the left column.  A value of &apos;&apos;main&apos;&apos; indicates that it should be displayed in the main column.

===Customizing the Section Label===

&apos;&apos;hello&apos;&apos; is a boring label, so let&apos;s add our own custom label by adding the &apos;&apos;label&apos;&apos; key to the array returned by our method:
&lt;code&gt;
function section__hello(&amp;$record){
    return array(
        &apos;content&apos; =&gt; &apos;Hello World!!!&apos;,
        &apos;class&apos; =&gt; &apos;main&apos;,
        &apos;label&apos; =&gt; &apos;Message of the Day&apos;
    );
}
&lt;/code&gt;

Now if you load the view tab of your application, you&apos;ll notice that the section has a heading &quot;Message of the Day&quot;.

===Customizing the Section Order===

A section can also specify an &apos;&apos;order&apos;&apos; attribute to define the order in which this section should appear.  It defaults to 0 which may cause the section to appear at the top of the view tab.  You can push it to the bottom of the view tab by assiging a higher number to the &apos;&apos;order&apos;&apos; attribute:
&lt;code&gt;
&lt;code&gt;
function section__hello(&amp;$record){
    return array(
        &apos;content&apos; =&gt; &apos;Hello World!!!&apos;,
        &apos;class&apos; =&gt; &apos;main&apos;,
        &apos;label&apos; =&gt; &apos;Message of the Day&apos;,
        &apos;order&apos; =&gt; 10
    );
}
&lt;/code&gt;

Now if you reload the view tab you&apos;ll notice that the section has moved to the bottom of the page.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=51">
	<page_name>fieldgroup_template</page_name>
	<page_id>51</page_id>
	<page_title>fieldgroup_template</page_title>
	<content>==Using a custom template for a field group on the edit form==

[[toc]]

Xataface allows you to partition your fields into &apos;&apos;groups&apos;&apos; so that similar fields are grouped together on the edit form.  The default layout of the fields remains simply vertical, but you can customize this layout (on a per-group basis) by creating a custom template and then assigning this template to the field group with the &apos;&apos;template&apos;&apos; directive.


===Example===

For example, in your [[fields.ini file]] if you wanted to group your address fields together you might have:
&lt;code&gt;
[fieldgroup:address]
    label=&quot;Address Information&quot;
    template=&quot;AddressInformationGroup.html&quot;

[address_1]
    group=address

[city]
    group=address

[state]
    group=address
&lt;/code&gt;

Then you would add the a template named &apos;&apos;AddressInformationGroup.html&apos;&apos; to your application&apos;s &apos;&apos;templates&apos;&apos; directory to display how the fields are laid out:
&lt;code&gt;
&lt;table width=&quot;100%&quot;&gt;
    &lt;tr&gt;&lt;th&gt;Address 1:&lt;/th&gt;
    &lt;td&gt;{$elements.address_1.html}&lt;/td&gt;

    &lt;th&gt;City:&lt;/th&gt;
    &lt;td&gt;{$elements.city.html}&lt;/td&gt;

    &lt;th&gt;State:&lt;/th&gt;
    &lt;td&gt;{$elements.state.html}&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;/code&gt;
This would display all of the fields in this group in a single row (horizontally) instead of vertically.

Note that this is an over-simplified example that doesn&apos;t take account for display error messages, required notices, grouped fields, and other information that you can obtain from the {$elements} array.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=50">
	<page_name>__field__permissions</page_name>
	<page_id>50</page_id>
	<page_title>__field__permissions</page_title>
	<content>This method can be used to set the default permissions for all fields in a designated table, when specified in that table&apos;s delegate class. It comes in handy in situations when you want to deny access to all fields except for those designated, rather then specifying each field to deny individually. For example, to revoke edit permissions from all fields but one, the user must first have edit permissions to the table overall, otherwise the Edit tab/action will not appear. Then, use this __field_permissions method to revoke edit permissions from all fields. Finally, use the fieldname__permissions method (see below) to allow access to only those fields needed.

=== Also See: ===

* [[How_to_granulate_permissions_on_each_field]]
* [[fieldname__permissions]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=49">
	<page_name>Troubleshooting</page_name>
	<page_id>49</page_id>
	<page_title>Troubleshooting</page_title>
	<content>==Xataface Troubleshooting==

This document is intended to help Xataface developers through some of the most common issues.

[[toc]]

==All I get is a blank white screen!==

The most common issue mentioned in the forums is that an application comes up with a blank white screen in the web browser.  This can happen for a number of reasons but the most common reason is because PHP has encountered a fatal error and your PHP installation is not set up to display errors.  

The first step to troubleshooting this problem must be to find out what the error is.  You can do that in one of the following ways:

# Check your Apache error log if you know where it is.  One common location on many linux installations is &lt;code&gt;
/var/log/httpd/error_log
&lt;/code&gt; but your system may have it located elsewhere.  If you cannot find your error log, continue to the next option.
# Turn on the &apos;&apos;display_errors&apos;&apos; flag in your &apos;&apos;php.ini&apos;&apos; file.  I.e., in your &apos;&apos;php.ini&apos;&apos; file, find where it says &lt;code&gt;
display_errors Off
&lt;/code&gt; and change it to &lt;code&gt;
display_errors On
&lt;/code&gt;.  After this is done, restart your apache webserver.  If you don&apos;t know where your &apos;&apos;php.ini&apos;&apos; file is located see the section later in this document on locating your &apos;&apos;php.ini&apos;&apos; file.  If you don&apos;t have access to your php.ini file, move on to the next option.
# In your application&apos;s &apos;&apos;.htaccess&apos;&apos; file, add the following directives to enable displaying errors:&lt;code&gt;
php_flag display_errors on
&lt;/code&gt; .  Note that this method will only work if your apache config file allows you to override these values at the directory level.  If you still get a blank white screen after this, continue to the next option.
# At the beginning of your application&apos;s index.php file, add the following:&lt;code&gt;
&lt;?php
error_reporting(E_ALL);
ini_set(&apos;display_errors&apos;, &apos;on&apos;);
&lt;/code&gt; .  Note that if the error occurs in the parsing or compiling of your PHP files you will still get a blank screen.  But this will at least display runtime errors on the page.

Once you can see the error messages that caused the blank white screen you are in a much better position to solve the problem.

==Locating your php.ini file==

Locating your &apos;&apos;php.ini&apos;&apos; file is actually quite easy.  The quickest way is to create a php script with the following contents:
&lt;code&gt;
&lt;?php
phpinfo();
&lt;/code&gt;
then navigate to this page in your web browser.  This look at the line where it says the &apos;&apos;php.ini file&apos;&apos;.  It will list the path there.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=48">
	<page_name>tab</page_name>
	<page_id>48</page_id>
	<page_title>tab</page_title>
	<content>==tab directive of the fields.ini file==

[[toc]]

The &apos;&apos;tab&apos;&apos; directive of the [[fields.ini file]] specifies which tab of the record edit form a field should be displayed on.  Xataface supports multiple tabs on the edit form by way of this &apos;&apos;tab&apos;&apos; directive.  If no fields contain the &apos;&apos;tab&apos;&apos; directive then all fields are displayed in a single tab (named &apos;&apos;__main__&apos;&apos;).

==Example 1: Placing address info on separate tab==

Consider the following &apos;&apos;people&apos;&apos; table: 
&lt;code&gt;
CREATE TABLE `people` (
    person_id int(11) not null auto_increment primary key,
    first_name varchar(32) not null,
    last_name varchar(32) not null,
    address varchar(100),
    city varchar(100),
    province varchar(100),
    country varchar(100),
    postal_code varchar(20)
)
&lt;/code&gt;

We want to split the fields into two tabs:
* Personal Info
* Address Info

===Splitting form into tabs===
We&apos;ll do this in two steps.  We use the &apos;&apos;tab&apos;&apos; directive to assign all address-related fields to the &apos;&apos;address_info&apos;&apos; tab.  In the tables/people/fields.ini file:
&lt;code&gt;
[address]
    tab=address_info

[city]
    tab=address_info

[province]
    tab=address_info

[country]
    tab=address_info

[postal_code]
    tab=address_info
&lt;/code&gt;

Now, when we load the edit form of the &apos;&apos;people&apos;&apos; table, we see two tabs:

* __main__
* address_info

&lt;nowiki&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/Picture 9.png?max_width=640&quot;/&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/Picture 10.png?max_width=640&quot;/&gt;
&lt;/nowiki&gt;

&apos;&apos;__main__&apos;&apos; is the name assigned to the default tab (for all fields that don&apos;t have a tab defined explicitly.


===Customizing the tab labels===

Next we will customize the tab labels by adding the following to the beginning of the [[fields.ini file]]:
&lt;code&gt;
[tab:__main__]
    label=&quot;Personal Information&quot;

[tab:address_info]
    label=&quot;Address Information&quot;
&lt;/code&gt;

&lt;nowiki&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/Picture 11.png?max_width=640&quot;/&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/Picture 12.png?max_width=640&quot;/&gt;
&lt;/nowiki&gt;


===Reordering the tabs===

If we want to reorder the tabs so that the &apos;&apos;address_info&apos;&apos; tab comes first, we would just reorder the definitions of the tabs:
&lt;code&gt;
[tab:address_info]
    label=&quot;Address Information&quot;

[tab:__main__]
    label=&quot;Personal Information&quot;
&lt;/code&gt;

&lt;nowiki&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/Picture 13.png?max_width=640&quot;/&gt;
&lt;/nowiki&gt;

===Try This Example App===

You can try this tiny sample application out [http://dev.weblite.ca/tab_test here].</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=47">
	<page_name>visibility:fieldName</page_name>
	<page_id>47</page_id>
	<page_title>visibility:fieldName</page_title>
	<content>==Example==

&lt;code&gt;visibility:ConferenceID = hidden&lt;/code&gt;

This will make the ConferenceID in the relationship list view disappear.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=46">
	<page_name>widget:atts</page_name>
	<page_id>46</page_id>
	<page_title>widget:atts</page_title>
	<content>==widget:atts Directive Reference==

The widget:atts directive in the fields.ini file allows any arbitrary HTML attributes to be added to any of the fields.  It may also be used to specify javascript event handler functions that the widget should call upon the specified event.  In particular, here are some examples of possible widget:atts directives:

===Available Widget Event Handlers===

{| class=&quot;listing listing2&quot;
|-
! name
! description
! version
|-
| [[field_size|widget:atts:size]]
| This directive sets the length of the input area a text box field, but it does not limit the number of characters that can be entered.  For example: &lt;nowiki&gt;&lt;br/&gt;widget:atts:size = 50&lt;/nowiki&gt;
| ?
|-
| [[field_maxlength|widget:atts:maxlength]]
| This directive limits the maximum number of characters that can be entered into a text box field.  For example: &lt;nowiki&gt;&lt;br/&gt;widget:atts:maxlength = 25&lt;/nowiki&gt;
| ?
|-
| [[field_style|widget:atts:style]]
| This directive specifies the style (font-size, font-family, etc.) for the field.  For example: &lt;nowiki&gt;&lt;br/&gt;widget:atts:style = &quot;font-size: 24pt; font-family: Apple Chancery&quot;&lt;/nowiki&gt;
| ?
|-
| [[field_rows|widget:atts:rows]]
| This directive specifies the number of rows for a text area field to display.  For example: &lt;nowiki&gt;&lt;br/&gt;widget:atts:rows = 10&lt;/nowiki&gt;
| ?
|-
| [[field_cols|widget:atts:cols]]
| This directive specifies the number of columns for a text area input field (1 character = 1 column).  For example: &lt;nowiki&gt;&lt;br/&gt;widget:atts:cols = 10&lt;/nowiki&gt;
| ?
|-
| [[field_javascript_onchange|widget:atts:onchange]]
| This directive will cause the specified javascript function to be called with the value of the field whenever its value is changed (i.e. when you change the field and tab out of it).  For example: &lt;nowiki&gt;&lt;br/&gt;widget:atts:onchange = &quot;doJsFunction();&quot;&lt;/nowiki&gt;
| ?
|-
| [[field_javascript_onclick|widget:atts:onclick]]
| This directive will cause the specified javascript function to be called with the value of the field whenever it is clicked.  For example: &lt;nowiki&gt;&lt;br/&gt;widget:atts:onclick = &quot;doJsFunction();&quot;&lt;/nowiki&gt;
| ?
|}

===Helpful tutorials===

See the bottom of this page in the Getting Started tutorial for more details on the basic directives above:

[http://xataface.com/documentation/tutorial/getting_started/customizing Customizing Field labels, descriptions, and widgets]

This tutorial talks about how to use the javascript directives:

[http://xataface.com/documentation/how-to/custom_javascripts]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki></record>