2011-07-22
Administration Themes
A theme consists of a color set, background images, the icon and a progress animation. At the moment 7 colors are available in trunk. Because of the favorite icons it is easier to spot the right tabs, too.
2011-07-13
Papaya Callbacks
- Code duplication if you have several callbacks in one class
- Validation before you can use the callback
- Easy to use, self speaking API for callbacks
PapayaObjectCallbacks is defined as a sub object with lazy initialization. An array is used to define the callbacks functions and the default return value. If you have a complex/large list of callback functions, I suggest to define a new class that extends PapayaObjectCallbacks. With a special class you can define the dynamic properties/methods using PHPDoc comments.
public function callbacks(PapayaObjectCallbacks $callbacks = NULL) {
if (isset($callbacks)) {
$this->_callbacks = $callbacks;
} elseif (is_null($this->_callbacks)) {
$this->_callbacks = new PapayaObjectCallbacks(
array(
'onEventOne' => TRUE,
'onEventTwo' => 'default'
)
);
}
return $this->_callbacks;
}To call the function is really simple. Just do it!
$result = $this->callbacks()->onEventOne($argument);If no function was assigned to the callback the defined default will be returned. Otherwise the assigned function is called and its return value will be used. So no validation of the assignment is needed.
The user (of your class with the callbacks) can assign the callback function, now.
$someObject->callbacks()->onEventOne = array($this, 'someCallbackHandler');In PHP equal or greater 5.3 an anonymous function is possible:
$someObject->callbacks()->onEventOne = function($context, $argumentOne) { ... };The first argument of the callback is always a context object. The reason for this is, that we still have to be PHP 5.2 compatible, so we can not use the PHP syntax for it. In addition you can edit the context without a local variable. By default this is an instance of stdClass but you can assign any object.
$someObject->callbacks()->onEventOne->context->someProperty = 'some value';If you like to see the implementation, you can find it in the papaya SVN.
2009-05-08
papaya CMS Nightly Builds
2009-02-05
Multi Language XSLT: Language Texts
Currently I am refactoring the default templates for the upcoming papaya CMS 5 release. I will show you some of the concepts in this blog. As you probably know papaya CMS uses XSLT for its templates, which is imho a perfect choice for web applications.
You get a strict split between application logic and layout. But XSLT can do more. How about translating layout texts, like the caption of a more link, format numbers and dates? Sounds nice, doesn't it?
In the first step you need to separate the layouts texts from the xslt and create language files for easier management.
The template for this is quite small:
<xsl:template name="language-text">
<xsl:param name="text"></xsl:param>
<xsl:choose>
<xsl:when
test="$LANGUAGE_TEXTS_CURRENT/text[@ident = $text]">
<xsl:value-of
select="$LANGUAGE_TEXTS_CURRENT/text[@ident = $text]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
<xsl:otherwise>
</xsl:choose>
</xsl:template>
This will check for an element text in the variable $LANGUAGE_TEXTS_CURRENT with an attribute ident that has the same value like the parameter $text and output it's content.
To fill up the variable, create a xml file with your texts.
<texts> <text ident="SAMPLE">Sample text</text> </texts>
At the top of the XSL file define a global parameter and load a xml file into it. The Xpath function document() loads XML data from an URI. By default the URI is relative to the current xsl file.
<xsl:param name="LANGUAGE_TEXTS_CURRENT"
select="document('./de-DE.xml')/texts"/>
Of course this whould be only a single fixed language file. So you have to use a variable for the file name. Xpath concat() supports a dynamic count of parameters - no need for nesting.
<xsl:param name="LANGUAGE_TEXTS_CURRENT"
select="document(concat('./', $PAGE_LANGUAGE, '.xml'))/texts"/>
Now you can call the template to get the language specific text.
<xsl:call-template name="language-text"> <xsl:with-param name="text">SAMPLE</text> </xsl:call-template>
This is still a little noisy, but in standard XSLT you can not help it. However if your processor supports the EXSLT extension you can. With EXSLT you can convert a template into a function. The result whould look like this:
<xsl:value-of select="language:text('SAMPLE')" />
Less source and easier to read. You could use it in an output tag, too.
<img src="sample.png" alt="{language:text('SAMPLE')}" />
The PHP 5 ext/xsl using the libxslt library supports EXSLT. To convert the template to a function you change the declaration from "xsl:template" to "func:function" after you did import the EXSLT function namespace:
<func:function name="language:text">
<xsl:param name="text"/>
<func:result>
<xsl:choose>
<xsl:when
test="$LANGUAGE_TEXTS_CURRENT/text[@ident = $text]">
<xsl:value-of
select="$LANGUAGE_TEXTS_CURRENT/text[@ident = $text]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
<xsl:otherwise>
</xsl:choose>
</func:result>
</func:function>
Here's still one little problem, if you haven't translated the language xml file to the current language or you missed a phrase the result is the text identifier. It whould be nice to fall back to a default language. So declare an additional parameter and add a condition to the template.
<xsl:param name="LANGUAGE_TEXTS_FALLBACK"
select="document('./en-US.xml')/texts"/>
<func:function name="language:text">
<xsl:param name="text"/>
<func:result>
<xsl:choose>
<xsl:when
test="$LANGUAGE_TEXTS_CURRENT/text[@ident = $text]">
<xsl:value-of
select="$LANGUAGE_TEXTS_CURRENT/text[@ident = $text]"/>
</xsl:when>
<xsl:when
test="$LANGUAGE_TEXTS_FALLBACK/text[@ident = $text]">
<xsl:value-of
select="$LANGUAGE_TEXTS_FALLBACK/text[@ident = $text]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
<xsl:otherwise>
</xsl:choose>
</func:result>
</func:function>
You can extend this idea and have default and project specific language files.
Have fun experimenting.
2009-01-13
2008-03-31
Database check
2008-01-17
Papaya Tips
2007-12-02
papaya 5 RC1
2007-11-27
New Backend: Overview page, toolbars and new icons
The applications menubar is now one of these groups. Each user can add up to 5 individual application links to the button group (The limit is an option). The last button shows all applications and allows to add/remove buttons from the button group.

The overview page shows tasks, messages and page informations for the current user. The amount of items in each list are user options.
The icons in the new interface are based on the Tango Icon Theme. Some are copied, some are new, some are modified (got emblems). The flags are the FamFamFam Flag Icons created by Mark James. He created another great set of icons, too. But Silk has only 16x16 bitmaps. For papaya we need larger sizes, too. So we had to create our own. But you will recognice some of them if you know Silk.
We hope you will like it.
2007-11-15
Searchable Listboxes

The javascript adds a little input field just before the select box. You input a text and the select will only show items that matches your input. All larger selects (with optgroups) got the new feature.
2007-11-14
papaya CMS in the iX 12/07
2007-10-23
2007-10-12
2007-10-11
Browser Compatibility
2007-10-10
Several Websites with one installation

Here are the 5 options.
"default" - The domain handling does nothing, default options are used
"domain" - Redirects to the requested page on another domain
"page" - Redirects to a specified page on another domain
"language" - Redirects to a language if the main page is called without a language (e.g. / or /index.html to index.de.html)
"tree" - Limits the domain to a subtree of the pages
The last option "tree" allows you to have several websites with one papaya CMS installation. They will share the users and other data but are limited to one part of the pages.
2007-09-28
Upload Files
Finally we got an upload progress bar in the new media database using the uploadprogress extension. Looks nice, doesn't it?The Javascript extends the used form with an onsubmit event to track the progress. So the upload still works without JS.
2007-09-03
Database debugging in Firebug
2007-08-31
PHP errors and debugs in Firebug

Nice detail: It works in other browsers using Firebug Lite.












