Blog

All posts (105)

Pages: < Previous 1–10 11–20 21–30 31–40 41–50 51–60 61–70 71–80 81–90 91–100 101–110 Next >
Ordering: Ascending Descending

81. UTF-8 in a Web application (back-end)

2007-07-29 13:29:56 by Martynas Jusevičius

Following the post about UTF-8 in the front-end of a Web application, these are some points to check in the back-end:

Add a comment

82. DIY tips: Inheriting Views

2007-07-16 22:39:46 by Martynas Jusevičius

Sometimes you may come up with a View that does nothing else than some additional filtering compared to a more general View.
For example, imagine a product catalog with nested categories. One way to create Views for it is to have a top-level ProductListView showing all the categories and all the products in them, and a View for each of the nested categories, e. g. ValveListView, CompressorListView etc. Then, this situation allows some nice code reuse via inheritance of the Views. The specific category ListViews inherit from the ProductListView and only do the additional filtering of the products, making sure only valves or compressors or whatever appear in that category.

One way to implement the filtering is making Propel's Criteria object (used for filtering the database results) a protected field of the ProductListView. The XSLT template can be overridden in the constructor as well, if necessary. It would probably also make sense to move the inherited View into a sub-folder of ProductListView, but then include paths have to be modified accordingly.

Here is how the final inherited ValveListView might look like:

class ValveListView extends ProductListView
{

	public function __construct(Resource $resource = null)
	{
		parent::__construct($resource);

		$this->template->load(ROOT_DIR."view/views/productList/valveList/ValveList.xsl");
	}
	
	public function display(Request $request, Response $response)
	{
		$this->criteria->add(ProductPeer::TYPE, ProductPeer::CLASSKEY_VALVEPRODUCT);

		parent::display($request, $response);
	}

}

Add a comment

83. GoPHP5

2007-07-10 23:50:32 by Martynas Jusevičius

GoPHP5 initiative encourages developers and hosting providers to drop PHP 4 from February 5th 2008 and support at least PHP 5.2 from then on.

PHP 5 has many new and improved features such as a better object-oriented model, improved XML processing, WebService, and database access APIs etc. However, many of the shared hosting sites support only PHP 4, and that makes difficult for many projects and users to exploit the new features of PHP 5.

This is of course a very welcomed initiative, but not really big thing for our team though. Right from the beginning, we did not plan any support for PHP 4 in our DIY Framework. We felt that the new features by far outweighed the need for legacy support. But for those of you who had similar thoughts, it's the best timing to move on to PHP 5!

Add a comment

84. UTF-8 in a Web application (front-end)

2007-07-03 01:16:39 by Martynas Jusevičius

UTF-8 is an amazing thing for Web developers, especially those developing multilingual or localized sites. It keeps you away from the mess of various encodings for different languages since you can find almost all of the world's character in a single Unicode charset. It is a default encoding of XML and other standards. In short, everybody is encouraged to switch to UTF-8.

However, starting developing with UTF-8 can give you some headaches, too. Usually you'll notice wrong characters, most often non-ASCII ones. The most common source of this is UTF-8 mixed with other encodings in the application or user input, i. e. assuming some characters to be UTF-8 when they are actually not, or erroneous conversion to/from other encodings.

A simple way to avoid problems is to make UTF-8 the encoding for the entire application. However, that might be simpler to state than implement. We can give you some hints for developing Web application's front-end:

Next time, some hints for the back-end will follow. More information on W3C I18n: Character encodings and SitePoint's Scripters UTF-8 Survival Guide.

Add a comment

85. DIY tips: Form refill

2007-06-30 15:05:19 by Martynas Jusevičius

Developing with HTML forms, there is often a need to refill input fields with previously entered user data, e. g. when the user tries to submit the form, but some data is not valid and has to be corrected (and therefore the form has to be displayed again).

Here's how you can do it using the DIY Framework. First, in the Resource subclass that handles the form submission, you need to have the appropriate Form object created. And in most cases, you have it already, since it is used to access the submitted data (i. e. the request parameters) conveniently. For example, we create a CommentForm in our PostResource when there is a comment submitted:

$form = new CommentForm($request);

Then, you most likely validate the form by calling its validate() method and based on that result (or possibly other factors as well) decide if the submission request was successful and user data is to be saved or otherwise processed (e.g. the required comment fields are filled and the comment will be saved), or there was an error (e. g. authors name is missing in the comment) and the same View with the form has to be displayed again, only with the input fields refilled this time:

$errors = $form->validate();

Knowing that, we set the Request result attribute either as success or as failure:

$request->setAttribute("comment-result", "success");

Then, the final thing the resource has to do is to set the form object as a request attribute as well. To be able to determine later which errors caused the failure of submission, we also set the errors array:

$request->setAttribute("comment-form", $form);
$request->setAttribute("comment-errors", $errors);

The rest of the logic is handled by the View. It has has to set the appropriate form parameters and arguments if there was a submission attempt:

if ($request->getAttribute("comment-result") != null)
{
	$this->proc->setParameter("", "comment-result", $request->getAttribute("comment-result"));
	$this->resolver->setArgument("comment-errors", XMLSerializer::serialize($request->getAttribute("comment-errors")));
	$this->resolver->setArgument("comment-form", XMLSerializer::serialize($request->getAttribute("comment-form")));
}

And then, the XSLT template is where the actual “refilling” takes place. If the $comment-result (which has to be a top-level parameter in the stylesheet) is a failure, then the input field gets the value from the serialized Form (if there was any):

<input type="text" id="name" name="name" maxlength="40">
	<xsl:if test="$comment-result = 'failure'">
		<xsl:if test="document('arg://comment-form')//Name">
			<xsl:attribute name="value"><xsl:value-of select="document('arg://comment-form')//Name"/></xsl:attribute>
		</xsl:if>
	</xsl:if>
</input>

Add a comment Comments (330)

86. Typography on the Web

2007-06-22 21:40:57 by Martynas Jusevičius

In the digital era that we live in, computers and the Web have pretty advanced typesetting features with the help of vector fonts and standards like XML and Unicode. However, many people use them with an old-school typewriter-mindset, or maybe they're just being ignorant. That is why you can find examples of weird and wrong typography like -- imitating an M-dash (—) or ,,'' imitating quotes.

We try to use correct typography and encourage you to do so. There are more characters to use than a hyphen and one type of quotes. This table shows the most useful ones:

Character Name Named entity Decimal entity Common use
- Hyphen-minus &#45; Joins words; Separates syllables
N-dash &ndash; &#8211; Indicates a range
M-dash &mdash; &#8212; Indicates a break in a sentence
Hyphen &#8208; Joins words; Separates syllables
Minus &minus; &#8722; Mathematical expressions
Left double quotation mark &ldquo; &#8220; Quotations
Right double quotation mark &rdquo; &#8221; Quotations
Left single quotation mark &lsquo; &#8216; Quotations
Right single quotation mark &rsquo; &#8217; Quotations

For broader explanation, see a useful article The Trouble With EM ’n EN (and Other Shady Characters) on A List Apart.

Add a comment

87. (X)HTML embedded in RSS

2007-06-20 20:15:19 by Martynas Jusevičius

Can anybody show a working example of XHTML embedded in RSS 1.0? We've seen it done in RSS 2.0 and Atom, but not RSS 1.0.

We know one can put escaped HTML markup into the feed and the readers would understand it. But we do not do it on purpose, because escaped HTML is harmful. As an example of that, some RSS readers try to interpret our escaped markup which is actually sample code for XML or XSLT and should not be interpreted at all. We generate valid XHTML, so escaping it before embedding into another XML format makes no sense.

Or should we switch to Atom? But what we like about RSS 1.0 is that it is based on RDF :)

Add a comment Comments (1)

88. A rule for writing secure PHP applications

2007-06-18 14:07:55 by Martynas Jusevičius

One of the hottest topics in PHP is security. Hundreds of recommendations, articles, tutorials, and various check-lists addressing this issue have been written.

From our experience, there is a simple yet important rule that leads to more secure (and probably generally better) Web applications:

Do not mix PHP, (X)HTML, and/or SQL code together!

That will “automagically” protect you from the most common attacks such as SQL injection.

There are several techniques that can help you:

Add a comment Comments (1)

89. Drop the old proprietary formats

2007-06-16 19:19:40 by Martynas Jusevičius

The Web standards and their support in browsers have really improved. It is now time to drop the old proprietary and binary formats and replace them with open, standard technologies.

PDF
It is a proprietary binary format. You can't open it without a third-party plugin and you can't construct or process it without special libraries or applications.
Does not look very portable after all. So why would you ever publish something on the Web in PDF? Right, it is supposed to give precise control over the layout of the document and make it print nicely. But have you checked lately what (X)HTML and CSS are capable of these days? And if you'll need graphics or formulas in your content, there is SVG and MathML. Drop PDF and go for nice and rich webages.
Microsoft Office files
Very much the same as for PDF. But if you really need to publish in some office-suite format, choose OpenDocument (ODF), which is an XML-based standard.
Flash
Like PDF, Flash is proprietary, binary, requires a plugin to play it and special software to build it. Furthermore, it breaks accessibility and navigation, is hard to use on non-Microsoft platforms, and is not indexed by search engines.
Drop Flash and switch to SVG, which is an XML-based standard, supports animations and has a programming interface. Consider SMIL as well.
Raster images
Where possible, replace your raster drawings and graphics with SVG. That will make them scalable and improve accessibility, among other things. And for other kinds of pictures, at least consider switching from GIF to PNG, which supports transparency and a wider range of color depths and is a non-proprietary standard.

Add a comment

90. DIY tips: implementing simple CAPTCHA

2007-06-12 13:10:34 by Martynas Jusevičius

CAPTCHA is a popular way to test whether the user is a human. It is widely used on the Web, for example in blogs, wikis, and webmail applications. CAPTCHA provides a pretty good protection from spambots flooding the website with comments or entries, and other kinds of bots trying to make undesired batch changes automatically. Actually, the first ever comment on our blog before implementing CAPTCHA was spam :)

The most popular form of CAPTCHA is probably the image recognition. However, it can be inaccessible for some users, and W3C suggests some other, more accessible forms of testing. We decided to implement a simple arithmetical test that asks to enter the sum of 2 random numbers displayed.

We will show how easily you can implement this form of CAPTCHA using the DIY Framework. First, you need to modify the View that displays data submission form you want to protect. In our case, that was ReadPostView. We added several lines to the PHP class:

$randNumber1 = rand(1, 9);
$randNumber2 = rand(1, 9);
$this->proc->setParameter("", "rand-number-1", $randNumber1);
$this->proc->setParameter("", "rand-number-2", $randNumber2);
$request->getSession()->setAttribute("captcha", $randNumber1 + $randNumber2);

This code generates 2 random numbers in the range [1..9] that will be used for testing. Then, these numbers are passed to the XSLT template and their sum, i. e. the CAPTCHA test value, is set as a session attribute.

Changes to the XSLT code are pretty trivial. Firstly, add top-level parameters for those 2 numbers:

<xsl:param name="rand-number-1"/>
<xsl:param name="rand-number-2"/>

and then add the test field to the submission form:

<label for="captcha"><xsl:value-of select="$rand-number-1"/> + <xsl:value-of select="$rand-number-2"/> =</label>
<input type="text" id="captcha" name="captcha" maxlength="2"/>

The final thing you have to do is to add the actual check if the submitted sum was correct. In our case, comment submissions from post URLs were handled by PostResource. We added several lines to its comment handling:

if ($form->getCaptcha() != $request->getSession()->getAttribute("captcha"))
{
	$errors[] = new Error("invalidCaptcha");
	throw new Exception("Errors");
}

They check if the CAPTCHA value, i. e. the sum of 2 random numbers, is the same as submitted by the user in the CommentForm. If it is, the program flow continues and the comment is saved. Otherwise, an exception is raised, which later makes the View to display an error. You also need to handle this kind of error in the XSLT template if you want it to appear with a description (e. g. “The sum was wrong”). And, of course, as with every new form field, you need to add the test field to the CommentForm and its serialization in XMLSerializer.

That's it, a simple arithmetical CAPTCHA test was implemented! You can see how it works by commenting this post :)

Add a comment Comments (4)

Pages: < Previous 1–10 11–20 21–30 31–40 41–50 51–60 61–70 71–80 81–90 91–100 101–110 Next >
Ordering: Ascending Descending