Programmieransatz einer ersten Erweiterung

Hallo zusammen,

viele wollen ja mit Yii ein kleines CMS bauen, dass wirklich nur die rudimentärsten Funktionen Neu, Bearbeiten, Löschen hat. Das ist auch mein Ziel, also habe ich das Programmierbeispiel mit dem Blog mal durchgearbeitet, und soweit auch verstanden.

Das ganze möchte ich nun um einen kleinen Terminkalender erweitern. Es sollen nur vom Anwender Termine angegeben werden können. Datum, Titel, Beschreibung, Ort. Diese 4 Informationen werden dann nach Datum sortiert in einem Portlet angezeigt.

Mein erster Ansatz dazu war folgender:

  1. Erstellen der SQL-Tabelle "Dates" (id int, date date, title varchar, content text, location varchar)

  2. aufrufen des yiic.php shell index.php

  3. model dates

  4. crud dates

Nachdem ich dann herausgefunden hatte, dass Yii meine Links verändert, und ein localhost/index.php?r=dates eben NICHT mehr funktioniert, konnte ich dann auch mein funktionierendes generiertes von Yii anschauen.

Jetzt mein Problem: Wie mache ich weiter? Wie erstelle ich ein neues Portlet, dass mir die 3 neusten "Termine" aufruft und anzeigt?

Hat jemand eine Idee, wie ich hier weiterkomme?

Yii gefällt mir aber soweit sehr gut!!

Wenn du Qiangs portlet-Erweiterung verwenden möchtest, kannst du z.B. so vorgehen:

[code=protected/components/KalenderPortlet.php]<?php

class Kalender extends XPortlet {

    public $anzahl=3;

    public $sonstigerConfigParameter='irgendwas';

    public function renderContent() {

        // Hole letzte Termine per ActiveRecord nach $termine

        // …

        $this->renderPartial('kalender', array('termine'=>$termine));

    }[/code]

[code=protected/components/views/kalender.php]<table>

<?php foreach ($termine as $termin): ?>

  <tr>…</tr>

<?php endforeach; ?>

</table>

[/code]

Und schon ist das Teil in beliebigen Views einsatzbereit (vorausgesetzt, Application.components.* ist importiert):

Danke für die Antwort!

Ich bekomme die Exception:

dates does not have a method named "init".

(die Klasse "Kalender" heisst bei mir dates, da meine SQL-Tabelle so heisst)

Das Prinzip habe ich verstanden, und die Quelltexte auch dementsprechend angepasst:

  • aber wo lege ich für meine Klasse dates eine leere init-Methode an?

Wo bekomme ich Dokumentation für die Methode renderPartial, und wo ist der Unterschied zwischen Render() und RenderPartial() ?

Ich verstehe glaub ich nicht ganz, was du mit der init() bezweckst…

Bzgl. Dokumentation: render() und renderPartial() sind ausführlich in der API-Dokumentation beschrieben. Sie ist die Referenzdoku für alle Detailfragen und sehr sehr ausführlich.

Bei render() wird ein layout-View (zu finden unter views/layout/main.php) um den aktuell gerenderten View herumgelegt. Bei renderPartial() passiert das nicht, und es wird nur der "nackte" gerenderte View ausgegeben.

Ah, ich verstehe. Yii ist wirklich mächtig, genau so etwas hatte ich immer gesucht.

Ich habe deinen obigen Code so angelegt, wie du ihn gepostet hattest, den Klassennamen auf Dates geändert, und wollte mit

das Widget platzieren. Leider meckert Yii dann mit der Exception  dates does not have a method named "init" und ich weiss nicht, warum?

aber danke soweit für die Hilfe.

Heisst nicht auch deine ActiveRecord-Klasse "Dates"? Dann gibt es natürlich einen Namenskonflikt und Yii versucht vermutlich, dein Widget als ActiveRecord zu initialisieren und wundert sich, wieso es dort keine init()-Methode gibt. Yii unterstützt noch keine Namespaces, so dass doppelte Klassennamen nicht erlaubt sind.

Richtig! Das ist es, meine Namen haben sich überschnitten. Meine Dummheit.

Jetzt meckert Yii aber wieder:

sagt mir:

KalenderPortlet does not have a method named "renderPartial".

  • Wenn ich das richtig verstehe, erbt KalenderPortlet von XPortlet, und "renderPartial" muss in XPortlet vorhanden sein, ist es aber nicht?? Oder wie interpretiere ich diese Fehlermeldung?

Sorry, kleiner Fehler: Bei einem Widget (und XPortlet extendet ja CWidget) gibt es nur render(), da ein Widget niemals in ein Layout eingebettet sein kann, sondern Bestandteil anderer Views ist.

Hmm okay, ich komme der Sache näher…

ich möchte mir bspw. den Titel und Content des Termins anzeigen lassen. Also gehe ich ins view und schreibe folgendes:

aber egal, ob ich es ($dates as $date) oder ($termine as $termin) nenne, er meckert mit

Description

Invalid argument supplied for foreach()

Source File

/var/www/yiibase/protected/components/views/dates.php(2)

Was mache ich falsch? Ich rufe es doch in der Kalenderportlet.php mit

auf, also muss es doch $termine heissen??? Oder versteh ich das falsch?

Kannst du mal den code aus renderContent() zeigen, damit wir sehen, wie du dir die Ergebnisse holst?

Ok, also hier mein Code:

protected/components/views/KalenderPortlet.php:

Da hatte ich das Beispiel oben wohl etwas missverständlich formuliert, es fehlt nämlich der wesentliche Teil ;).

An der Stelle wo es hieß "Hole letzte Termine per ActiveRecord nach $termine" muss sowas in der Art stehen:

Alles klar ! Jetzt hab ich endlich verstanden. Es funktioniert!! Danke für die Unterstützung. Hättest du gewusst, dass ich Yii-Neuling bin, hättest du sicherlich von anfang an geschrieben, dass ich hier den ActiveRecord nutzen muß.

So, damit spiel ich jetzt erstmal herum, vielleicht kommen ja noch fragen.

Hast du eine idee, warum mir index.php?r=dates/admin nicht das admin-interface von dates liefert, sondern einfach ewig "localhost contacted, waiting for reply" im Browser erscheint?

Nicht wirklich. Aber kannst du ja leicht prüfen: dates/admin wird ja auf den controller in protected/controller/DatesController und darin die Methode ActionAdmin aufgelöst. Im Zweifel hilft immer mal wieder ein

das man kurz mal wo einfügt, um zu prüfen, was Sache ist. Damit findest du sicher mehr raus. Viel Spaß beim Basteln ;).