Some PHP, Generated with Python

Been looking at some code recently that provides a mechanism to localize a user interface for different human languages. The mechanism for doing so looks something like this (repeated many times over);


function drawNameForm() {

global $lang;

?>

}

The global variable $lang is a giant associative array and is loaded before this function is called, depending on the users preferred language, perhaps something like these files, in terms of a PHP arrays;

// Filename: lang.en.php;

$lang = array (

'name' => 'Name',
'btn_ok' => 'OK',

);

?>

// Filename: lang.es.php;

$lang = array (

'name' => 'Nombre',
'btn_ok' => 'AUTORIZACION',

);

The code in question isn't an exception. I've seen many PHP applications handle localization in this way. In Internationalization and Localization with PHP the conclusion a "naive" reader might come to is this is the default best practice. Nothing wrong with the article but the necessity of simple example / short prose leaves other areas to the readers imagination.

The big problem with localization in this manner is that it's happening at runtime. Every page request resulted in the localized version of the page being generated dynamically - see here for a rough idea of why that's not so good.

Now it may be possible to cache the output HTML and store it as a static file but in a real example it's likely we'll have truly dynamic data mixed in there, such as something from a database, which makes caching tricky. Without caching the translation adds a significant baseline overhead to the generation of each page, which will increase the more complex the UI becomes.

Meanwhile there will be only a finite number of translations of the user interface, which will vary only when the UI itself changes (rarely - certainly not on a pre-request basis). So wouldn't it be better to have multiple versions of the drawNameForm() function, one per language e.g.;

// Filename: ui.en.php

function drawNameForm() {

?>

}

And...

// Filename: ui.es.php

function drawNameForm() {

global $lang;

?>

}

Of course who want's to manually maintain multiple versions of the same code?

For this specific problem solutions have already evolved, typically packaged as template engines. Jeff's file schemes implementation in WACT does "JIT" generation on PHP scripts, as you can see here. I believe (haven't looked) Smarty has similar functionality. Fine as long as you're happy with the template engine.

There are other, similar, categories of problem though, which have not been well solved yet. For example application configuration. Here's another suggestive snippet;

if ( $config['allow_bbcode'] ) {

if ( $user_sig != '' && $user_sig_bbcode_uid != '' ) {

$user_sig = ( $config['allow_bbcode'] ) ?

bbencode_second_pass($user_sig, $user_sig_bbcode_uid) :

preg_replace('/:[0-9a-z:]+]/si', ']', $user_sig);

}

if ( $bbcode_uid != '' ) {

$message = ( $board_config['allow_bbcode'] ) ?

bbencode_second_pass($message, $bbcode_uid) :

preg_replace('/:[0-9a-z:]+]/si', ']', $message);

}

}

}

The key line is;

if ( $config['allow_bbcode'] ) {

On every page request this condition (as well as many others) is being re-evaluated. Wouldn't it be better to simply eliminate the block of code, if $config['allow_bbcode'] is false? There have been attempts to build PHP installers, some very successful, designed for a single application (e.g eZ publish 3) with the most mature, generic attempt being Sandro's Zzoss Installer, which I've mentioned before here.

Around the point of writing installers in PHP is where I think things start to "fall apart", in general because PHP was designed specifically for web sites - it's not a general purpose solution. That's not to say "never" but rather, by taking other technologies into account, can life be made easier / PHP applications better?

Code generation has come up on this blog before. Another link from http://www.codegeneration.net/ since then, here;

PHP is amazing because it's so inexpensive to run. All you need is Apache, MySQL and PHP and you can run a web site or service.

...and add to that how easy it is to deploy a script - just drop it somewhere on your web server and away you go - something that opens the doors for "just in time" generation, for example.

Code generation often tends to be thought about in terms of building complete applications with some friendly "drag and drop", such as CodeCharge Studio. While that has it's place, it tends to be "all or nothing".

An interesting and alternative form of code generation, that I ran into today, is Aspect-Oriented PHP. It uses Java to do some basic parsing of a PHP script and merge with a second "aspect" script (see here to get a sense of what AOP is about). Right now it probably isn't a realistic proposition, in terms of performance but it's interesting because, first, they're using Java to do the work, which gives them a solid basis for dealing with things like multibyte characters or more complex parsing operations and because they're generating PHP on the fly.

Returning to the localization problem above, been looking at empy recently: "A powerful and robust templating system for Python". Some things that make empy attractive, so far, is it's intended for general purpose templating (not HTML specific), it's mature, the markup is very distinct from PHP and HTML (the only thing you really need to watch is the @ symbol) and it allows you to use Python itself as the template language, when needed.

An empy template to generate PHP from the drawNameForm() could look like this;

function drawNameForm() {

?>

}

The empy markup I've used is: @(name) and @(btn_ok) (empy has alot more than that but, for now, sticking with some basic variable references).

Viewing the output from this function in a browser results in the following HTML source;

In other words I can still use it as a working PHP script (in this example at least).

Meanwhile if I run it through a python script (which in turn invokes empy) like;


#!/usr/bin/python
# translate.py

# Load empy
import em

# Use a dictionary (like an associate PHP array)
# for sake of example. In practice use external files...

langs = {}

langs['en'] = {

'name': 'Name',
'btn_ok': 'OK',

}

langs['es'] = {

'name': 'Nombre',
'btn_ok': 'AUTORIZACION',

}

# Create an empy interpreter

interpreter = em.Interpreter()

# Load the template PHP script
tpl = open('ui.tpl.php').read()

# Loop through the available translations

for lang in langs:

# Give the interpreter a new file to write output to
interpreter.output = open('ui.'+lang+'.php','w')

# Reset for new parse (making it use the output file)
interpreter.reset()

# Populate the interpreters data space with the word list
# to write into the template
interpreter.globals = langs[lang]

# (Re-) Parse the template
interpreter.string(tpl)

interpreter.shutdown()

It spits out localized PHP scripts with filenames identifying the language e.g.;


function drawNameForm() {

?>

}

I can now use it as part of the build process for my application, as it's being prepared for a release. At runtime the code (hand coded) which uses this script might look like;


// Default to English in case of invalid values...
if ( !isset($_GET['lang'])|| !preg_match('/^[a-z]{2}$/',$_GET['lang']) {
$_GET['lang'] = 'en';
}

// Load the file of localized functions
require_once MY_LIB . 'ui.'.$_GET['lang'].'.php';

// Call the localized function
drawNameForm();

Anyway - just musings and an obvious solution, if you're already doing it. What I can't say is how well this kind of approach scales to a large PHP codebase but, guessing, so long as the scripts involved remain simple, focusing on performing a single task, no real problems.

Some particular points about Python. By taking advantage of things like py2exe or py2app you could distibute executable installers. Throw in some wxPython and you've got a cross platform GUI (which looks like the real thing - uses native widgets) for installing.

Any stories?

Replay

Category: programming Time: 2005-01-06 Views: 4
Tags:

Related post

  • Why are my emails generated with Python stuck in mail queue 2016-01-02

    I'm trying to send emails programmatically with Python. The emails stay in the mail queue (mailq). Details are below. My diagnosing abilities have reached their limit. Perhaps the issue is my ISP blocking outgoing emails from my (dynamic) IP address.

  • Delete **Contents:** in index of pdf generated with python-spihnx 2016-01-21

    I have a project created with python-sphinx and I use latexpdf to compile the final pdf. In the final pdf created, in the index it is visible a Contents: string that I would like to delete. The only way I found by now is to compile only the latex, op

  • Email generated with Python stuck in mailq, times out (Debian) 2016-01-18

    I want to send emails out, originating from my Debian computer. I do NOT want the emails to originate from my gmail account, like in most Python smtplib examples. I called my ISP regarding port 25, and they told me to use (port 587) or (port 465 with

  • How to create a date range until some date inclusive with python dateutils? 2016-01-22

    I'm trying to get a list of months in the given range. Specifically, given the range 2015-12-31 - 2016-01-01, I want to get the list 2015-12 and 2016-01. I'm using dateutil's rrule, but the until parameter isn't really helping since it seems to be lo

  • Linux + automated login and password with python 2011-11-14

    I write the following simple script , the target of the following script is to copy info_file from target Linux (red hat 5.1) machine to my current Linux machine without entering login or password I will happy to get some work examples with python th

  • Generate LaTeX Truth Table with Python Cheetah 2012-01-22

    While looking for code which can automatically generate truth table in LaTeX I stumbled on this Python generator. It appears that the code can be used from Cheetah's framework. Can anybody point me to a simple example of use. I started reading docume

  • Scraping asp and java script generated table with python 2.7, beautiful soup and selenium 2016-01-14

    I need to scrape a JavaScript generated table and write some of the data to a csv file. I am restricted to python 2.7, Beautiful Soup and/or Selenium. The closest code that will do part of what I need is in question 14529849, but all I am getting in

  • Python lexer/parser generator with specific requirements 2016-02-17

    I am looking for a python lexer/parser generator with the following requirements. I should preface this with the admission that I am not very familiar with lexers/parsers, so maybe some of the following is naive or just plain nonsensical. If so, let

  • PHP mixed with some JS code to update Wordpress theme settings 2013-12-10

    I am working on my first Wordpress Theme but I am facing a little problem in my code. In fact, I have created a little page in the administration to change some settings on my theme and, for example, to modify the background images of the theme which

  • How to set time field when generating a GPX track with Python OGR? 2015-02-17

    I want to generate a GPX file with Python OGR. In particular I want to generate a tracks (layer of features of OGR type wkbMultiLineString) My script is below. I get the error ERROR 1: No such field: 'time' Also it won't let me create a field time be

  • AWS SQS Invalid token when connecting with PHP, but ok with Python 2016-01-29

    I'm having a very peculiar issue with trying to connect to AWS SQS. When running this PHP code: $client = SqsClient::factory(array( 'credentials' => [ 'key' => 'somekey', 'secret' => 'somesecret' ], 'region' => 'eu-west-1', 'version' => 'la

  • Help with some php math in Wordpress 2015-09-04

    I've made a woocommerce store and I am using a dropshipper - so every product has an price and a trade price for me - which I am importing and storing as a custom field 'trade_price' on the product. I wanted to know if it would be possible to include

  • Get pairs of point coordinates for Daubechies wavelets generated with scipy.daub in Python 2016-02-04

    I've been trying to get the coordinates of the points that make up a Daubechies wavelet generated with scipy.daub, in order to send them across a websocket and have them plotted on a Canvas.js dynamic chart. I managed to send the data over to the bro

  • pass javascript var to php success , But can not plus php var with php var? 2012-12-12

    I have this code: <script type="text/javascript"> var foo = 'bar'; <?php file_put_contents('foo.txt', ' + foo + '); ?> var baz = <?php echo 42; ?>; alert(baz); </script> Why does this not write "bar" into my tex

  • Design PHP Apps with Excel Using Worksheet Server 2004-07-12

    From time to time, someone does something with PHP that is truly unique - something that goes far beyond the norm of PHP applications listed at Hotscripts and leaves you truly impressed by the capabilities of this language. One prime example is Jedox

  • PHP error with character ่กจ (JP) 2009-01-27

    I have the following code <?php if ($handle = opendir('C:/xampp/htdocs/movies')) { while (false !== ($file = readdir($handle))) { if ($file != "." && $file != "..") { echo $file."<br />\n"; } } closedir($hand

  • Why such popularity with Python? 2010-09-20

    Other than being annoyed at whitespace as syntax, I'm not a hater, I just don't get the fascination with Python. I appreciate the poetry of Perl, and have programmed beautiful web services in bash & korn, and shebang gnuplot. I write documents in tro

  • Making Apache able to write to PHP files with PHP running as DSO? 2010-12-22

    I have PHP running as a DSO. As such, my installer script (which writes to a config file) can't do any writing. How do I give apache (user: nobody) the ability to write to the file? --------------Solutions------------- I would only do this on a devel

  • Ruby isn't a PHP generator, right? 2011-09-28

    My boss was looking down on me about learning Ruby because "It's just a PHP generator" which I can't find anything about it being so. Is this the case? I understand that the Rails framework can be used to generate PHP code, but isn't Ruby in-and

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development

search

Front-end development

Database

development tools

Open Platform

Javascript development

.NET development

cloud computing

server

Copyright (C) avrocks.com, All Rights Reserved.

processed in 1.492 (s). 13 q(s)