dracoblue.net

Detect action/view/module and matched route in agavi

For each executed Module/Action(+View) there is an ExecutionContainer (AgaviExecutionContainer). So if you want to retrieve the current executed action, module or view, best is to do

$action = $this->getContext()->getActionName();
$view = $this->getContext()->getViewName();
$module = $container->getModuleName();

But what if you want to retrieve the "real" action, the one and only for the request? That's a little bit more difficult, so here a short introduction how to deal with that.

Whenever the routing of agavi does the work for you, by turning the input data and webbrowser call of a user, into a action and validated data, it triggers an action, executes the view for the outputtype and fills the template. But Slots can be used from the view and trigger then again validation+action+view for their parameters.

This is why the real request route can not be found in the execution container and must be found somewhere else. In the Request.

$route_names = $this->getContext()->getRequest()->getAttribute(
                    'matched_routes', 'org.agavi.routing'
                );

The route_names is nothing but an array, for instance:

array(
    'product.edit'
    // because our current route is named "product.edit"
    // in routing.xml
)

This information does help us indirectly to determine the action, which got called! Since the WebRouting has also a getRoute-method, which expects just a route_name, we can retrieve the info now easily:

// we want to have just the first one,
// thatswhy list($first) = $array style
[strong]list($route_name)[/strong] = $this->getContext()->getRequest()->getAttribute(
    'matched_routes', 'org.agavi.routing'
);

$route = $this->getContext()->getRouting()->getRoute($route_name);

The new $route-Variable now holds an array of all information about the route. In our case, just some are interesting.

$module = $route['opt']['module'];
$action = $route['opt']['action'];

One really should use that

only in case of a default slot, which is used directly in the output_types.xml or used on serveral different pages and has to determine on its own and by using module+action where it's actually embedded.

In agavi, open source, php by DracoBlue @ 05 Mar 2009 | 326 Words

Action/View/Module und Route in Agavi rausfinden

Für jedes Module, jede Action(+View) gibt es den ExecutionContainer (AgaviExecutionContainer). Wenn Du also das aktuelle Module, die ausgeführte Action oder den View rausfinden möchtest, machst Du das am einfachsten so:

$action = $this->getContext()->getActionName();
$view = $this->getContext()->getViewName();
$module = $container->getModuleName();

Aber was, wenn Du die "richtige" Action rausfinden möchtest? Die einzig wahre - für den Request? Das ist ein kleines bisschen schwieriger. Hier eine kurze Erklärung wie und warum das geht.

Wann immer man Agavi die Arbeit machen lässt (Umwandeln von Eingabedaten und dem eigentlichen Webbrowseraufruf des Users, in validierte Daten), passiert immer das gleiche. Es wird eine Action gestartet, der View für den passenden Outputtype ausgeführt und das Template gefüllt. Beim Erstellen eines Slots (z.B. aus der View herraus) wird wieder Validierung+Action+View für die Slot-Parameter ausgeführt.

Deshalb kann der echte die Request-Route nicht im ExecutionContainer gefunden werden, sondern irgendwo anders. Im Request.

$route_names = $this->getContext()->getRequest()->getAttribute(
                    'matched_routes', 'org.agavi.routing'
                );

Die Variable $route_names enthalt dann ein Array mit allen Route-Namen:

array(
    'product.edit'
    // Die aktuelle Route heißt "product.edit"
    // in der routing.xml
)

Diese Information hilft uns indirekt um nun auf die Action zu kommen, welche eigentlich ausgeführt wurde. Da das WebRouting auch eine getRoute-Methode hat, welche nur einen route_name erwartet, können wir die Information nun einfach auslesen:

// wir wollen nur die erste route, deswegen
// im Stil list($first) = $array
[strong]list($route_name)[/strong] = $this->getContext()->getRequest()->getAttribute(
    'matched_routes', 'org.agavi.routing'
);

$route = $this->getContext()->getRouting()->getRoute($route_name);

Die neue $route-Variable beinhaltet nun alle Informationen über die Route. In unserem Fall ist aber nur spezielles wichtig.

$module = $route['opt']['module'];
$action = $route['opt']['action'];

Diese Methode sollte man wirklich

nur benutzen, wenn man einen universellen Slot hat, weöcher direkt in einer output_types.xml oder in verschiedenen Seiten benutzt wird und selbstständig und über das modul+action rausfinden kann, wo er eigentlich eingebunden ist.

In agavi, open source, php by DracoBlue @ 05 Mar 2009 | 316 Words

PDT Autovervollständigungstipps (für Agavi)

Mit den PDT (PHP Development Tools für Eclipse) kannst Du die meisten Variablen in PHP autovervollständigen. Das aber meist nur, sofern sie richtig definiert sind oder das php-doc richtig eingepflegt ist.

Dieser Artikel zeigt ein paar Tipps, wie Du auch in unklaren Situationen die Autovervollständigung eindeutig machen kannst. Wenn Du lediglich

die aktuellste Version von PDT aufsetzen möchtest, schau Dir bitte das andere Tutorial an.

Graste hat ein kleines Script veröffentlicht, welches dem gesamten (Agavi-)Projekt in Eclipse sagt, dass die Variablen $template, $ro, $rd usw. vom richtigen Typ definiert sind. Diese sind normalerweise in Agavitemplates verfügbar, werden aber via .xml beim Compile-Vorgang reinkompiliert und sind daher für Eclipse nicht sichtbar.

Hier meine leicht veränderte autocomplete.php:

<?php
exit();
$slots = array();
$template = array(); // agavi 0.11 standard
$t = array(); // agavi 1.0 standard
$tm = new AgaviTranslationManager();
$ro = new AgaviWebRouting();
$rq = new AgaviWebRequest();
$ct = new AgaviController();
$us = new AgaviSecurityUser();
$rd = new AgaviWebRequestDataHolder();
?>

Diese Datei einfach als autocomplete.php in Dein Projekt speichern und Eclipse wird diese Variablen standardgemäß mit dieser Klasse initialisiert vermuten und schon hat man die nette Autovervollständigung auch in Agavitemplates.

Wenn Du den Rückgabetyp für eine Funktion auch für einen bestimmten Typ (und damit autovervollständigungsfähig) definieren möchtest, brauchst Du nur die PHP-Docs richtig zu setzen. In diesem Beispiel gibt die Funktion test123() ein SomeClass-getyptes Element zurück:

/**
 * [strong]@return SomeClass[/strong]
 */
function test123() {
    /* ... */
}

Manchmal möchte man, dass eine Variable für einen bestimmten Scope den richtigen Typ hat. Das geht dann wie folgt:

if (false) $instance = new [strong]SomeClass[/strong]();

oder besser sogar

/* @var $instance [strong]SomeClass[/strong] */

und Eclipse wird die Variable $instance nun für eine SomeClass halten.

Hast Du weitere Tipps? Dann schreib sie bitte in die Kommentare!

In agavi, eclipse, open source, pdt for eclipse, php by DracoBlue @ 23 Feb 2009 | 317 Words

PDT auto completion tips (for agavi)

In PDT (php development tools for eclipse) you are able to do auto completion (e.g. ctrl+space) on most of the classes, as long as they are defined properly or you have a proper php-doc set up. Check that tutorial, if you want to set up PDT.

Graste posted a snippet, which tells eclipse for the project (in this example it's agavi) that the variables (which are common for templates), like $template (or $ro, $rd and so on) are defined with correct type.

Here is a slightly modified autocomplete.php:

<?php
exit();
$slots = array();
$template = array(); // agavi 0.11 default
$t = array(); // agavi 1.0 default
$tm = new AgaviTranslationManager();
$ro = new AgaviWebRouting();
$rq = new AgaviWebRequest();
$ct = new AgaviController();
$us = new AgaviSecurityUser();
$rd = new AgaviWebRequestDataHolder();
?>

Just save that file to autocomplete.php in your project structure -> eclipse will use this classes as default, so you have neat auto completion even in agavi templates.

If you have return type for a function, and want the caller to be able to autocomplete: just use proper php-docs. For example, the following will give SomeClass-typed elements on a function test123:

/**
 * [strong]@return SomeClass[/strong]
 */
function test123() {
    /* ... */
}

If you just want autocomplete for a specific scope, you may use the following:

if (false) $instance = new [strong]SomeClass[/strong]();

or better

/* @var $instance [strong]SomeClass[/strong] */

and auto completion on $instance will work like if it was a SomeClass.

Got another tip? Feel free to add it in the comments!

In agavi, eclipse, open source, pdt for eclipse, php by DracoBlue @ 23 Feb 2009 | 280 Words

Vorladen von CSS-Bildern für :hover

Die Navigation von dracoblue.net habe ich mit CSS-Background Bildern und einem :hover-effect gemacht. Beim Hovern, wird das Bild dann einfach in einer etwas helleren Version zeigt.

Es gibt also:

http://dracoblue.net/style/menu_news_hover.png

und

http://dracoblue.net/style/menu_news.png

In meinem CSS, sieht das dann so aus:

a#newsLink {
    background: transparent url('menu_news.png') no-repeat;
}
a#newsLink:hover {
    background: transparent url('menu_news_hover.png') no-repeat;
}

All dass ist natürlich gängige Praxis, aber ich hatte damit ein Usability-Problem für meine Benutzer. Die

*hover.png Dateien werden erst geladen, sobald man mit der Maus über den Navigationseintrag geht, ihn also hover't. In der Perspektive des Serverbesitzers, ist man darüber vielleicht froh. Aber für den Benutzer, ist das neue (hellere) Bild, für knapp eine Sekunde nicht verfügbar. Es dauert ja ein bisschen, bis das Bild vom Server zum User kommt.

Hier nun meine Lösung, woe man die Bilder vorlädt (ohne Javascript oder stub-'s zu benutzen).

td#newsLink a {
  background: transparent url('menu_news.png') no-repeat;
}
td#newsLink a:hover {
  background: transparent url('menu_news_hover.png') no-repeat;
}
[strong]td#newsLink {
    background:
        transparent
        url('menu_news_hover.png')
        fixed no-repeat
        -120px -120px;
}[/strong]

In dem Beispiel habe ich das #newsLink auf das td des eigentlichen Links verschoben. Abschließend, habe ich eine neue Definition eingefügt, die ein sich nicht-wiederholendes und - mit Koordinaten -120x-120 - eindeutig unsichtbares Bild anzeigt.

In css, html, open source by DracoBlue @ 23 Feb 2009 | 224 Words

Page 26 - Page 27 - Page 28

Give something back

Were my blog posts useful to you? If you want to give back, support one of these charities, too!

Report hate in social media Campact e.V. With our technology and your help, we protect the oceans from plastic waste. Gesellschaft fur Freiheitsrechte e. V. The civil eye in the mediterranean

Recent Dev-Articles

Read recently

Recent Files

About