TEE-11 Backend Zweite Tabelle

Aus Contao Community Documentation

Version vom 5. Februar 2011, 19:54 Uhr von Stefan.sl (Diskussion | Beiträge)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
MsgError.png Unvollständiger Artikel: dieser Artikel ist noch nicht sauber bearbeitet.

Bitte erweitere ihn und entferne erst anschliessend diesen Hinweis.

Tagebuch einer Extension-Entwicklung

betrifft
TYPOlight Version ab TL 2.8
Extensions Extension Creator


Die zweite Tabelle

Ich habe mich lange davor gedrückt, aber jetzt muss es an meine zweite Tabelle gehen: tl_gw_meldungen.

Meldungen sind Teilnahmen von Turnierpaaren an Turnieren. Sie bestehen aus

  • dem Datum der Turnierteilnahme,
  • dem Ort,
  • der Startgruppe (Altersklasse) und der Startklasse (aus regeltechnischen Gründen müssen die NICHT zwingend mit den entsprechenden Werten, die beim Turnierpaar eingetragen sind übereinstimmen),
  • der Tanzart (Standard/Lateinamerikanisch),
  • der Turnierart (hier unterscheidet man "offene Turniere", "Einladungsturniere", "Landesmeisterschaften", "Deutsche Meisterschaften" usw),
  • der Anzahl der gestarteten Paare,
  • dem Platz (da es geteilte Plätze wie 5.-7. geben kann gibt es platz_von und platz_bis), und
  • einem Freitext als Bemerkung.

Soviel zur Domain specific knowledge.

Schauen wir uns nochmal die SQL-Definition in config/database.sql an:

-- 
-- Table `tl_gw_meldungen`
-- 
CREATE TABLE `tl_gw_meldungen` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `pid` int(10) unsigned NOT NULL default '0',
  `sorting` int(10) unsigned NOT NULL default '0',
  `tstamp` int(10) unsigned NOT NULL default '0',
  `datum` date NOT NULL default '2000-01-01',
  `startgruppe` varchar(32) NOT NULL default '',
  `startklasse` varchar(12) NOT NULL default '',
  `lat_std` char(32) NOT NULL default '',
  `turnierort` varchar(128) NOT NULL default '',
  `turnierart` varchar(64) NULL default NULL,
  `anzahlpaare` int(4) NULL default NULL,
  `platz_von` int(4) NULL default NULL,
  `platz_bis` int(4) NULL default NULL,
  `bemerkung` text NULL,
  PRIMARY KEY  (`id`),
  KEY `pid` (`pid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Die ersten 4 Felder sind ja so "default". Hier macht pid (Parent-ID) aber auch Sinn. Die Meldungen sind "Childs" der Turnierpaare. Im Backend wollte ich auch so vorgehen, also bei den Turnierpaaren auf einen Tree-View umstellen. Im DCA-Record für tl_gw_turnierpaare habe ich also unter sort den mode auf 5 gestellt, und im DCA-Record für tl_gw_meldungen auf 6.

Dann straft mich TYPOlight aber mit der SQL-Fehlermeldung, dass es in der Tabelle tl_gw_turnierpaare kein Feld pid gäbe. Richtig, gibt es auch nicht. Da das die Parent-Tabelle ist, braucht die auch kein pid. Nun gut, offensichtlich erfordert die Logik das so, also erfülle ich den Wunsch und spendiere auch tl_gw_turnierpaare ein Feld pid.

Beim Betrachten im Backend fällt mir aber auf, dass das unpraktisch ist: Der Sportwart, der das im Backend pflegt, den interessiert nur die nach dem Turnierdatum sortierte Liste, neueste ganz oben. Der will gar nicht erst das Turnierpaar suchen, um dort eine Meldung einzugeben.

Ich entscheide mich, Turnierpaare und Meldungen im Backend getrennt zu verwalten, aber bei den Meldungen dann eine foreign-key-Beziehung über die pid zur Turnierpaartabelle zu haben. Wenn der Sportwart eine neue Meldung anlegt, soll er über ein Dropdown das Turnierpaar auswählen, zu dem diese Meldung gehört, die Liste selbst soll aber nach dem Datum absteigend sortiert sein.

Ich brauche also eine weitere Seite im Backend, und modifiziere /system/modules/gw_turnierpaare/config/config.php auf:

// Back end module 
$GLOBALS['BE_MOD']['content']['gw_turnierpaare'] = array 
( 
    'tables' => array('tl_gw_turnierpaare'), 
    'icon'   => 'system/modules/gw_turnierpaare/icons/turnierpaare.png' 
); 
$GLOBALS['BE_MOD']['content']['gw_meldungen'] = array 
( 
    'tables' => array('tl_gw_meldungen'), 
    'icon'   => 'system/modules/gw_turnierpaare/icons/meldeliste.png' 
);

Also zwei hier formal getrennte Tabellen mit getrennten Backendseiten und verschiedenen Icons (Das Icon hänge ich hier an, das soll ein Siegerpodest darstellen).

Dann gehts an DCA für die Meldungstabelle, in /system/modules/gw_turnierpaare/dca/tl_gw_meldungen.php:

/** 
 * Table tl_gw_meldungen  
 */ 
$GLOBALS['TL_DCA']['tl_gw_meldungen'] = array 
( 
    // Config 
    'config' => array 
    ( 
        'dataContainer'               => 'Table', 
        'enableVersioning'            => true, 
    ),

Hier keine Besonderheiten, es ist eine Tabelle mit Versionierung...

    // List 
    'list' => array 
    ( 
        'sorting' => array 
        ( 
            'mode'                    => 1, 
            'fields'                  => array('datum DESC', 'turnierort'), 
            'panelLayout'             => '', 
            'flag'                    => 8, 
        ),

Sortierung nach festem Feld, nämlich dem absteigenden Datum, und dann nach dem Turnierort alphabetisch. Das Panel für Sortieren, Filtern usw lasse ich erst mal weg (Das sorgte nämlich für eine kryptische Fehlermeldung - ich kümmere mich später darum). flag 8 ist das absteigende Sortieren nach dem Monat. Zu meinem Problem damit komme ich später.

        'label' => array 
        ( 
            'fields'                  => array('datum', 'turnierort', 'turnierart', 'startgruppe','startklasse','lat_std','pid'), 
            'format'                  => '<span style="font-weight: bold;">%s</span>, %s (%s), %s %s %s - %s' 
        ),

Hier bastele ich mir die Ausgabezeile, mit dem Datum in fett, dann dem Ort, der Turnierart, Startgruppe und Klasse und der Info, ob Standard oder Lateinamerikanisch. Dann müsste dort eigentlich noch der Name des Tanzpaares hin, aber der steht ja nicht (direkt) in der Tabelle, sondern nur die pid. Darum nehme ich erst mal die - besser als nichts. Ich vermute, ich muss/kann da mit einem Label-Callback arbeiten und die pid selbst in die Namen auflösen.

        'global_operations' => array 
        ( 
            'all' => array 
            ( 
                'label'               => &$GLOBALS['TL_LANG']['MSC']['all'], 
                'href'                => 'act=select', 
                'class'               => 'header_edit_all', 
                'attributes'          => 'onclick="Backend.getScrollOffset();"' 
            ) 
        ), 
        'operations' => array 
        ( 
            'edit' => array 
            ( 
                'label'               => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['edit'], 
                'href'                => 'act=edit', 
                'icon'                => 'edit.gif' 
            ), 
            'copy' => array 
            ( 
                'label'               => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['copy'], 
                'href'                => 'act=copy', 
                'icon'                => 'copy.gif' 
            ), 
            'delete' => array 
            ( 
                'label'               => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['delete'], 
                'href'                => 'act=delete', 
                'icon'                => 'delete.gif', 
                'attributes'          => 'onclick="if (!confirm(\'' . $GLOBALS['TL_LANG']['MSC']['deleteConfirm'] . '\')) return false; Backend.getScrollOffset();"' 
            ), 
            'show' => array 
            ( 
                'label'               => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['show'], 
                'href'                => 'act=show', 
                'icon'                => 'show.gif' 
            ) 
        ) 
    ),

Hier bleibt erst mal alles so, wie vom Extension-Creator vorgegeben.

    // Palettes 
    'palettes' => array 
    ( 
        '__selector__'                => array(''), 
        'default'                     => '{couple_legend},pid;{tournament_legend},datum,turnierort,turnierart,startgruppe,startklasse,lat_std;' 
                                    .'{result_legend},anzahlpaare,platz_von,platz_bis,bemerkung;' 
    ), 
    // Subpalettes 
    'subpalettes' => array 
    ( 
        ''                            => '' 
    ),

Auch hier nichts spannendes: Eine normale Palette für alle Felder.

    // Fields 
    'fields' => array 
    ( 
        'pid' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['pid'], 
            'inputType'               => 'select', 
            'foreignKey'              => 'tl_gw_turnierpaare.partnernachname', 
            'search'                  => true, 
            'sorting'                 => true, 
            'eval'                    => array('mandatory'=>true) 
        ),


pid soll ein Foreign Key in die Turnierpaare-Tabelle sein. Mit der foreignKey-Option wird das Dropdown-Feld mit den Partnernachnamen aus der Turnierpaar-Tabelle gefüllt. Zum ersten Testen ist das ganz OK, aber eigentlich stelle ich mir das anders vor: Es sollen dort nur AKTIVE Paare auswählbar sein, und ich hätte dort gerne die kompletten Namen des Turnierpaares stehen, nicht nur den Nachnamen des Herrn. Auch da wird wohl ein Callback her müssen - später.

        'datum' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['datum'], 
            'inputType'               => 'text', 
            'search'                  => true, 
            'sorting'                 => true, 
            'flag'                    => 11, 
            'eval'                    => array('mandatory'=>true, 'datepicker'=>$this->getDatePickerString(), 'tl_class'=>'w50 wizard', 'minlength' => 1, 'maxlength'=>64, 'rgxp' => 'date') 
        ),

Abgeguckt beim DCA-Record für Artikel: das Datumsfeld. Insbesondere den getDatePickerString() verstehe ich nicht - muss ich aber auch erst mal nicht. Kommt Zeit, kommt Erleuchtung.

        'turnierort' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['turnierort'], 
            'inputType'               => 'text', 
            'search'                  => true, 
            'sorting'                 => true, 
            'flag'                    => 1, 
            'eval'                    => array('mandatory'=>true, 'minlength' => 1, 'maxlength'=>128, 'tl_class' => 'w50') 
        ),

Nichts Besonderes hier...

        'turnierart' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['turnierart'], 
            'inputType'               => 'select', 
            'sorting'                 => false, 
            'options'                 => gwTurnierpaarliste::$TurnierArten, 
            'eval'                    => array('mandatory'=>false, 'includeBlankOption' => true, 'tl_class' => 'w50') 
        ),

Ähnlich wie bei den Startgruppen und Klassen lagere ich die Optionen für "Turnierart" in meine Frontendklasse aus. Gefällt mir besser so, und ich kann es "Re-usen".

        'startgruppe' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['startgruppe'], 
            'inputType'               => 'select', 
            'sorting'                 => true, 
            'flag'                    => 1, 
            'options'                 => gwTurnierpaarliste::$StartGruppen, 
            'eval'                    => array('mandatory'=>false, 'includeBlankOption' => true, 'tl_class' => 'w50') 
        ), 
        'startklasse' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['startklasse'], 
            'inputType'               => 'select', 
            'sorting'                 => false, 
            'options'                 => gwTurnierpaarliste::$StartKlassen, 
            'eval'                    => array('mandatory'=>true, 'tl_class' => 'w50') 
        ), 
        'lat_std' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['lat_std'], 
            'inputType'               => 'select', 
            'sorting'                 => false, 
            'options'                 => gwTurnierpaarliste::$TanzArten,
            'eval'                    => array('mandatory'=>true, 'tl_class' => 'w50') 
        ),

Wie zuvor, normale Dropdown-Felder, deren Optionen ich in der Frontendklasse gwTurnierpaarliste ablege, um sie von verschiedenen Bereichen aus nutzen zu können.

        'anzahlpaare' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['anzahlpaare'], 
            'inputType'               => 'text', 
            'eval'                    => array('mandatory'=>false, 'minlength' => 1, 'maxlength'=>4, 'rgxp' => 'digit') 
        ), 
        'platz_von' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['platz_von'], 
            'inputType'               => 'text', 
            'eval'                    => array('mandatory'=>false, 'minlength' => 1, 'maxlength'=>4, 'rgxp' => 'digit', 'tl_class' => 'w50') 
        ), 
        'platz_bis' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['platz_bis'], 
            'inputType'               => 'text', 
            'eval'                    => array('mandatory'=>false, 'minlength' => 1, 'maxlength'=>4, 'rgxp' => 'digit', 'tl_class' => 'w50') 
        ), 
        'bemerkung' => array 
        ( 
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['bemerkung'], 
            'inputType'               => 'textarea', 
            'eval'                    => array('mandatory'=>false, 'cols' => 80, 'rows' => 20, 'allowHtml' => false) 
        ), 
    ) 
);

Auch hier eigentlich "Hausmannskost": 3 Felder für Zahlen und ein Textfeld für die Bemerkung.

/system/modules/gw_turnierpaare/gwTurnierpaarliste.php (das Frontend-Modul) erweitere ich noch um die Optionslisten für Tanzart und Turnierart:

  public static $TurnierArten = array('-', 'OT','ET', 'LM', 'DM', 'EM', 'WM');    
  public static $TanzArten = array('-', 'Std','Lat');

Zum ersten Testen füge ich zwei Testdatensätze in die Meldungstabelle ein. Ergebnis:

Testdatensätze

Gut, die Tabellenheader sehen noch nicht so aus wie gewünscht, aber das ist Feinschliff. Die gewünschten Informationen (mit pid 7) werden angezeigt.

Wenn ich einen neuen Eintrag hinzufüge, sieht das so aus:

Neuer Datensatz

Durch das Fehlen der Language-Einträge natürlich noch sehr unschön, aber alle Felder sind da. Die Foreign-Key-Beziehung in die Turnierpaar-Tabelle klappt (rudimentär) auch.

Mich wundert der Eintrag "20.12.2000" als Default im Datumsfeld, aber ich habe auch keinen Default vorgegeben. Es wäre wohl praktisch, durch einen Load-Callback das aktuelle Datum dort als Default vorzugeben.

Ich gebe also mal Daten ein:

Dateneingabe

Und drücke auf Speichern- was sehe ich beim Datum:

Datum

30.11.1999? Das habe ich im Datepicker aber nicht ausgewählt....auch eine manuelle Eingabe sorgt für das selbe 1999er-Ergebnis. Und in der Übersichtstabelle dann das:

Übersicht

0000-00-00...hm.

Das ist alles nicht so ermutigend. Ich habe die Konfiguration für das Datumsfeld bei tl_article.php ab geschaut, da funktioniert ja auch alles.

Bevor noch mehr Leute da Zeit rein stecken: Das Problem bei meinem Datumsfeld ist einfach, dass ich instinktiv in MYSQL ein date-Feld angelegt habe. Es muss aber ein varchar(10) sein. Logisch ist das nicht. Also bitte keine weiteren Hinweise zur Fehlerbehebung, lindesbs war der Schnellste, danke :-).

Hätte ich mehr Zeit gehabt, hätte ich mir selbst mal die DB-Struktur von tl_article angeschaut, um den Unterschied zu finden, Aber Zeit ist gerade knapp, und ich wollte endlich die nächste "Folge" raus schicken. Im nächsten Schritt wird das Datumsfeld also voraussichtlich hervorragend funktionieren, indem wir es in ein varchar(10) verwandeln :-).

Diskussion aus dem Forum

Hinweis.png Hinweis: Die Wiedergabe folgt dem Forums-Thread, der verschiedene Thematiken aufwirft. Sie muss daher noch umgearbeitet werden.

user: deerwood

Abgeguckt beim DCA-Record für Artikel: Das Datumsfeld. Ich habe gerade mal schnell gecheckt: DB Datentyp DATE() wird in TL offenbar nirgendwo verwendet, alle Felder, die im DCA den DatePicker verwenden, haben in der DB den Datentyp VARCHAR(10) (bis auf tl_news.date, das ist merkwürdigerweise INT(10) ). Vielleicht ist das das Problem?

user: dl1ely

Ja, ich vermute sehr stark, dass das das Problem ist. Habe es einfach intuitiv (falsch) gemacht. Leider fehlte mir die Zeit, vorher "im Core" abzugucken. Eins habe ich sowieso schon gelernt: Das Einzige, auf was man sich in Sachen "TL-Entwickler-Doku" verlassen kann, ist der Core-Source ;-).

EDIT: habe es schnell geändert und das Feld "datum" auf varchar(10) umgestellt. Jetzt klappt der Datepicker. Aber jetzt wird das Feld mit einem Unix-Timestamp gefüllt. Gebe ich das Feld also in meinen Tabellenzeilen aus oder als Sortierheader, steht dort nur Zahlenwust statt eines Datums. Ich wusste schon, warum ich lieber "date" haben wollte ;-). Ich kriege graue Haare. Da muss ich mir also definitiv noch was einfallen lassen...

Gw turnierpaare 30.png

user: BugBuster

der Timestamp hat aber den Vorteil, das du diesen einfach wandeln kannst, genauer in die Form die der Nutzer im Backend (Einstellungen / Startseite) definiert hat.

Mein Modul hat z.B. solch eine Zeile:

$VisitorsStartDate = date($GLOBALS['TL_CONFIG']['dateFormat'],$objVisitors->visitors_startdate);

$objVisitors->visitors_startdate ist hier der Timestamp aus der DB.

user: dl1ely

Sicherlich richtig, aber wenn ich per DCA-Record im Backend damit arbeiten will, z.b. als Sortier-, bzw. Gruppierfeld, dann habe ich nicht die Möglichkeit, dort ein "date()" zu injecten. Aber ich schaue mal weiter, was mit Callbacks geht und wie ich meiner Anforderung näherkomme. :-)

TLight

Ich versuche nun, nach Deiner Vorlage eine Verwaltung für unseren Vereinsbekleidungs-Verleih zu programmieren. Ich habe den Extension-Creator, die Datenbank-Einrichtung und die DCA-Programmierung fürs Erste recht gut hinbekommen und alle kleinen Fehler ziemlich schnell lokalisieren und beheben können. Ich arbeite auf einer lokalen Installation und habe die Fehlermeldung eingeschaltet.

Wenn ich mich richtig erinnere, so kommt seitdem ich das language file "modules.php" angefasst habe, folgende Fehlermeldung:

Warning: Cannot modify header information - headers already sent by (output started at  
mein_pfad\system\modules\to_bekleidungsverleih\languages\de \modules.php:1) in  
mein_pfad\system\libraries\Template.php on line 174
#0 [internal function]: __error(2, 'Cannot modify h...', 'mein_pfad...', 174, Array)
#1 mein_pfad\system\libraries\Template.php(174): header('Content-Type: t...')
#2 mein_pfad\system\modules\backend\BackendTemplate.php(135): Template->output()
#3 mein_pfad\typolight\main.php(286): BackendTemplate->output()
#4 mein_pfad\typolight\main.php(102): Main->output()
#5 mein_pfad\typolight\main.php(295): Main->run()
#6 {main}

Leider bin ich nun mit meinem Latein am Ende... Weiß jemand Rat?

user: Toflar

Bei Dir ist irgend ein Zeichen vor der ersten php Anweisung Also wahrscheinlich " <?php" statt "<?php" oder sowas

user: TLight

Ich habe in modules.php nachgesehen - leider ist dort kein Freizeichen. Auch in keiner anderen der von mir angefassten Dateien (soweit ich mich erinnern kann). Zu allem Überfluss bemerke ich gerade, dass beim Laden der Startseite des Backends folgender Fehler 2x vor dem o. g. Fehler gelistet wird:

Warning: Illegal offset type in mein_pfad\typolight\main.php on line 183
#0 mein_pfad\typolight\main.php(183): __error(2, 'Illegal offset ...', 'mein_pfad...', 183, Array)
#1 mein_pfad\typolight\main.php(93): Main->welcomeScreen()
#2 mein_pfad\typolight\main.php(295): Main->run()
#3 {main}

user: xchs

 Zitat von TLight   
...leider ist dort kein Freizeichen. Auch in keiner anderen der von mir angefassten Dateien (soweit ich mich  
erinnern kann).

Das kann aber unter Umständen auch ein verstecktes Zeichen sein, je nachdem welchen Editor Du verwendest (UTF-8 vs. UTF-8 BOM usw.)

user: TLight

Nein, leider nichts zu finden. Auch im stinknormalen Editor ist da kein Zeichen. Ich verwende UTF-8-Codierung, aber auch da konnte ich nichts finden...

user: FloB

Schau alle Dateien durch. Mit welchem Editor bearbeitest du die Dateien? Schau mal da nach eine Option bezüglich des BOM. Einen BOM "siehst" du eigentlich auch nur in einem Hex-Editor.

user: dl1ely

Hmm, es muss aber definitiv was mit modules.php, Zeile 1 zu tun haben. Wenn du magst, kannst du mir dein File schicken (zip, damit beim Versenden nix passiert), per Private Mail.

user: Jürgen

Ich hatte heute auch das Problem mit diesem Fehler. Wollte zwei Ankreuzfelder ergänzen. Hab dann die Codierung von UTF-8 auf UTF-8 ohne BOM umgestellt und siehe, da seit dem klappt es. Benutze das Notepad++ unter Windows.

Wenn ich noch eine Frage stellen darf. Wenn ich calender_events um zwei Checkboxen erweitern möchte und das der Titel_legende zuweise wird ein Checkboxfeld verdoppelt und die Legende verschwindet. Erweitere ich aber z.B. die Publish_legende werden wie gewünscht nur zwei Felder angezeigt und auch die Legende bleibt erhalten.

user: dl1ely

Schick mir mal bitte deine /lang/de/modules.php Sprachdatei (Oder zeige sie uns hier, die ist ja nicht so lang).

Ich weiß ja nicht, ob du es genauso wie ich gemacht hast, aber ich bin über diesen Fehler auch gestolpert, aber das gehört zum nächsten Teil des Tagebuchs. Und bevor wir hier in die falsche Richtung rennen, würde ich gerne sehen, wie diese Datei aussieht. Falls es "mein" Fehler ist, kann ich dir dann sagen woran es liegt ;-).

Oder um es doch hier vorweg zu nehmen: Wenn du wie ich in der aktuellen Version dein(e) Backendmodul(e) unter eine eigene Obergruppe gesetzt hast (bei mir gw_paarverwaltung), dann darf der entsprechende Übersetzungseintrag $GLOBALS['TL_LANG']['MOD']['gw_paarverwaltung'] NICHT ein Array sein (erster Eintrag Text fürs Menü, zweiter Eintrag der Erklärungstext), sondern einfach nur ein String, der den Menüeintrag darstellt. Das ist anders als bei den Einträgen für die Module selbst. Bei meinem Modul ist das jetzt so:

/** 
 * Back end modules 
 */ 
$GLOBALS['TL_LANG']['MOD']['gw_turnierpaare'] = array('Turnierpaare', 'Verwaltung der Turnierpaare.'); 
$GLOBALS['TL_LANG']['MOD']['gw_meldungen'] = array('Meldungen', 'Verwaltung der Turniermeldungen (Meldeliste).'); 
$GLOBALS['TL_LANG']['MOD']['gw_paarverwaltung'] = 'Paarverwaltung';

Die letzte Zeil ist der Menüeintrag für die "Gruppe" im Backendmenü, die ersten beiden Einträge die Werte für meine beiden Backendmodule. Hatte auch für die "Gruppe" ein Array aus Menütext und Erklärungstext, und das brachte mir den von dir beschriebenen Fehler. Ist das dein Problem?


user: dl1ely

Mal ein Schuss ins Blaue: Macht dein str_replace für den Paletteneintrag wirklich das richtige? Check das lieber mal durch ein Debugging-Echo oder ähnlich. Beim richtigen str_replace() zur Modifikation der bestehenden Palette kann man sich böse vertun.

OK, hier Kommando zurück. Der von mir beschriebene Fehler kann erst zuschlagen, wenn man eine Modifikation der /config/config.php macht, die ich bisher hier noch gar nicht beschrieben habe, sondern die erst in der nächsten Tagebuchfolge erscheint. Wenn du also bisher alles so gemacht hast wie ich, kann es nicht dein Problem sein. Trotzdem hat das Problem definitiv mit falschen Einträgen in den Language-Dateien (und zwar modules.php) zu suchen. Entweder hast du irgendwo ein Array, wo ein String erwartet wird, oder umgekehrt.

Falls du es selbst nicht findest, bitte deine config/config.php und language/de/modules.php zu mir, dann schaue ich mir das an.

Sorry für die Verwirrung, das ist das Problem, wenn der eigentliche Code schon einen Schritt weiter ist als die aktuelle Tagebuchberichterstattung...

user: TLight

@dl1ely: wahrscheinlich habe ich genau den von Dir beschriebenen Fehler gemacht! /config/config.php:

$GLOBALS['BE_MOD']['to_bekleidungsverleih']['to_magazin'] = array 
( 
    'tables' => array('tl_to_bkvs_magazin'), 
    'icon'   => 'system/modules/to_bekleidungsverleih/icons/trikot.png' 
);  
$GLOBALS['BE_MOD']['to_bekleidungsverleih']['to_verleih'] = array 
( 
    'tables' => array('tl_to_bkvs_verleih'), 
    'icon'   => 'system/modules/to_bekleidungsverleih/icons/trikot.png' 
);

/languages/de/modules.php:

/** 
 * Back end modules 
 */ 
$GLOBALS['TL_LANG']['MOD']['to_bekleidungsverleih'] = array('Bekleidungsverleih', ''); 
$GLOBALS['TL_LANG']['MOD']['to_magazin']            = array('Magazin', ''); 
$GLOBALS['TL_LANG']['MOD']['to_verleih']            = array('Verleih', '');

Leider habe ich Deine Lösung nicht ganz verstanden. Aber ich warte einfach auf Deinen neuen Tagebucheintrag. Will Dir nicht noch mehr Arbeit machen als Du eh schon hast.

Wenn ich die /languages/de/modules wie folgt ändere:

/** 
 * Back end modules 
 */ 
$GLOBALS['TL_LANG']['MOD']['to_bekleidungsverleih'] ='Bekleidungsverleih'; 
$GLOBALS['TL_LANG']['MOD']['to_magazin']            = array('Magazin', ''); 
$GLOBALS['TL_LANG']['MOD']['to_verleih']            = array('Verleih', '');

verschwinden zwar die zwei Fehler der Startseite und das Modul wird in der Mittelspalte angezeigt:

Warning: Illegal offset type in mein_pfad\typolight\main.php on line 183
#0 mein_pfad\typolight\main.php(183): __error(2, 'Illegal offset ...', 'mein_pfad...', 183, Array)
#1 mein_pfad\typolight\main.php(93): Main->welcomeScreen()
#2 mein_pfad\typolight\main.php(295): Main->run()
#3 {main}

Der Ursprungsfehler bleibt aber:

Warning: Cannot modify header information - headers already sent by (output started at  
mein_pfad\system\modules\to_bekleidungsverleih\lan guages\de \modules.php:1) in  
mein_pfad\system\libraries\Template.php on line 174
#0 [internal function]: __error(2, 'Cannot modify h...', 'mein_pfad...', 174, Array)
#1 mein_pfad\system\libraries\Template.php(174): header('Content-Type: t...')
#2 mein_pfad\system\modules\backend\BackendTemplate.p hp(135): Template->output()
#3 mein_pfad\typolight\main.php(286): BackendTemplate->output()
#4 mein_pfad\typolight\main.php(102): Main->output()
#5 mein_pfad\typolight\main.php(295): Main->run()
#6 {main}
Angehängte Dateien 

o bekleidung.zip (5,9 KB, 3x aufgerufen)

--> gelöst!!! Bevor sich nun zu viele mit meinem Problem beschäftigen, hier die Lösung:

Habe meine Dateien in Notepad++ in UTF-8 ohne BOM konvertiert - und das Problem hat sich erledigt. Was zum T. ist BOM? Nun ja, vielen Dank für all Eure Hilfe. Toll, wie schnell das geklappt hat!

user: Jürgen

Zitat von dl1ely   

Mal ein Schuss ins Blaue: Macht dein str_replace für den Paletteneintrag wirklich das richtige? Check das lieber mal durch ein Debugging-Echo oder ähnlich. Beim richtigen str_replace() zur Modifikation der bestehenden Palette kann man sich böse vertun. Stefan

Zitat von TLight   

Bevor sich nun zu viele mit meinem Problem beschäftigen, hier die Lösung: Habe meine Dateien in Notepad++ in UTF-8 ohne BOM konvertiert - und das Problem hat sich erledigt. Was zum T. ist BOM? Nun ja, vielen Dank für all Eure Hilfe. Toll, wie schnell das geklappt hat! Gruß, Torsten @Torsten: Gerne. Ich war auch schon kurz vor dem verzweifeln mit dem BOM. @Stefan: Ich hab das Beispiel "CalenderFreeEntry" aus dem Wiki benutzt. Auch dort tritt das Problem auf. Genauer gesagt wird beim Hinzufügen von einer Checkbox die Legende nicht mehr angezeigt (nur bei Titel_legende). Wenn ich nun eine zweite Checkbox hinzufüge erscheint eine von diesen doppelt. Sobald ich es auf eine andere Legende lege funktioniert alles wie erwartet.

user: dl1ely

Naja, "Lösung nicht verstanden". Eine Lösung ist es eigentlich nicht, eher eine Erklärung. to_bekleidungsverleih ist die "Obergruppe" im Backend-Modul-Menü für deine beiden Backend-Module to_magazin und to_verleih. Und bei TL ist es nunmal so, dass dann in der Language-Datei bei der Obergruppe nur ein einzelner Übersetzungsstring stehen darf, während bei den Backendmodulen selbst ein Array bestehend aus Übersetzung des Menüeintrags und des Erklärungstextes stehen muss. Witzigerweise bist du in genau dasselbe Problem wie ich gelaufen, aber ich hätte erst in der nächsten Tagebuchausgabe davon berichtet. Jetzt ist ja alles geklärt.

user: dl1ely

Zitat von Jürgen   

@Stefan: Ich hab das Beispiel CalenderFreeEntry aus dem Wiki benutzt. Auch dort tritt das Problem auf. Genauer gesagt wird beim Hinzufügen von einer Checkbox die Legende nicht mehr angezeigt (nur bei Titel_legende). Wenn ich nun eine zweite Checkbox hinzufüge erscheint eine von diesen doppelt. Sobald ich es auf eine andere Legende lege funktioniert alles wie erwartet. Das versteh ich nicht.

Wenn es bei allen Legenden funktioniert und bei der Titel_legende nicht. Vielleicht liegt es daran das Titel_legende die erste beim Calendar_event ist?

Wie gesagt, der einzige Tip, den ich erstmal habe, wäre per echo o.ä. sich den String der Palettendefinition im DCA nach der Modifikation anzugucken. Ich vermute einfach, da läuft beim str_replace oder wie auch immer der bestehende String modifziert wird was schief. Ohne den String zu sehen ist das aber schwer zu sagen...

user: FloB

Zitat von TLight   

Was zum T. ist BOM?

Byte Order Mark

user: dl1ely

Zitat von FloB   

http://de.wikipedia.org/wiki/Byte_Order_Mark Übrigens, aus meiner persönlichen Sicht ist die mangelnde Kenntnis dieser Abkürzung keine Schande - ich kannte sie bis vor Kurzem auch noch nicht und habe sie erst in der Wikipedia kennengelernt. Und das obwohl ich mir eigentlich einbilde, in der Informatik-Welt schon umfangreiche Kenntnisse zu besitzen. Bei UTF habe ich aber wohl noch Lücken ;-)

user: klabog

Am Schluss sollte dabei allerdings ein HowTo herauskommen, das die Entwicklung Schritt für Schritt abbildet und auf die möglichen Fehler an entsprechender Stelle hinweist.

Das muss nicht notwendigerweise von Dir kommen, Du machst Dir schon genug Arbeit, sondern vielleicht von einem Team das Deine Vorlage redaktionell bearbeitet und zusammen mit Dir vielleicht eine Extension bastelt die vom speziellen Fall auf eine universelle Variante zielt.

user: dl1ely

Naja gut, schauen wir mal...Vielleicht kann man das in der Tat "am Ende" in ein "normales", leichter lesbares Tutorial umwandeln. Leider geht es momentan nicht voran, weil ich meine Prioritäten außerhalb von TL leider höher setzen muss. Der Tag hat nur 24 Stunden, und ich brauche momentan auch ohne das Tagebuch gefühlt mindestens 48h.

Ansichten
Meine Werkzeuge

Contao Community Documentation

Marc plant CFC für CCACSSCSR.

C-C-A
Navigation
Verstehen
Verwenden
Entwickeln
Verschiedenes
Werkzeuge