Problem mit "assets"

Hallo,

ich muss primär sagen, dass es eher ein allgemeines Problem ist, sodass man sich nicht von der Verwendung der folgenden Extension abschrecken lassen sollte.

Und zwar verwende ich den TinyMCE-Editor für mein CMS und habe diese Extension hier im Einsatz: http://www.yiiframew…ension/tinymce/

Nun ist es so, dass an sich alles ganz gut klappt, bis auf die Tatsache, dass wenn ich was am Code des Editors, vor Allem dessen Einstellungen, ändere, dann schlägt sich das nicht auf den Editor im Browser selbst nieder! Das Problem dabei ist dieser assets-Ordner, in dem ja irgendwie alles gecached wird und die darin enthaltenen Daten ausgeliefert werden.

Nun meine Fragen:

  • Wozu ist das Ding überhaupt da?
  • Wieso werden meine Änderungen nicht in die Unterordner des assets-Ordner übernommen?
  • Kann man diese Erweiterung irgendwie als Ausnahme deklarieren, d.h. dass es nicht in den assets-Ordner übernommen wird?

Für jede Hilfe bin ich dankbar!

mfg

Armin

Quote

  • Wozu ist das Ding überhaupt da?
  • Wieso werden meine Änderungen nicht in die Unterordner des assets-Ordner übernommen?
  • Kann man diese Erweiterung irgendwie als Ausnahme deklarieren, d.h. dass es nicht in den assets-Ordner übernommen wird?
  1. Dank Assets kann man Dateien einer Komponente außerhalb des Webordners ablegen, selbst wenn diese Dateien (Javascript, CSS, …) beinhalten, die vom Web aus zugänglich sein müssen. Das erhöht die Wiederverwendbarkeit enorm und macht es einfacher, Komponenten als Paket zu veröffentlichen. Egal, wo die Dateien ursprünglich lagen: Der AssetManager sorgt dafür, dass sie von außen zugänglich sind. So kann man große Teile des Frameworks oder auch Extensions z.B. in den globalen Include-Pfad von PHP legen und mehrfach in verschiedenen Anwendungen auf einem Server einsetzen.

  2. Das sollte eigentlich schon der Fall sein. CAssetManager::publish() vergleicht die beiden Zeitstempel der Originaldatei und der veröffentlichten Asset-Datei. Evtl. ein Browsercache-Problem?

  3. Nein, dann würde die Komponente ja nicht mehr funktionieren.

Siehe auch den Abschnitt "Widget" auf dieser Handbuchseite:

http://www.yiiframew…xtension.create

Hi,

naja, so wie ich das sehe, wird der Zeitstempel nur abgeglichen, wenn man eine einzelne Datei publiziert. Wird jedoch ein gesamter Order an den AssetManager übergeben, prüft dieser nur, ob er bereits existiert oder nicht.

Kommentar aus der Doku (CAssetManager::publish()):

Quote

    * If the asset is a file, its file modification time will be checked to avoid unnecessary file copying;

    * If the asset is a directory, all files and subdirectories under it will be published recursively. Note, in this case the method only checks the existence of the target directory to avoid repetitive copying.

Da hilft es dann wohl erstmal nur den betreffenden Asset-Ordner zu löschen, damit Änderungen an darunter liegenden Dateien automatisch übernommen werden…

Gruß

Ahjo, das dürfte wohl die Ursache sein. Man sollte daher an den Files, die man mit dem AssetManager veröffentlichen will, nicht rumfummeln müssen. Wenn das der Fall ist, wurde das Widget “suboptimal” entwickelt ;)

Nun stellt sich mir die Frage, was ich an dem Widget drehen muss, dass das wieder passt?

So direkt fällt mir da auch nicht viel ein, aber vielleicht sollte man vorschlagen, dass ein gesetztes YII_DEBUG-Define dafür sorgt, dass die Asset-Verzeichnisse immer überschrieben werden oder sowas.

Als Quick-Fix für die Entwicklung (wenn es dir wirklich so auf den Keks geht das Asset-Verzeichnis von Hand zu löschen) könntest du es evtl. in der Init() des Widgets löschen, bevor dort publish() aufgerufen wird. Den Pfad bekommst du mit getPublishedPath() raus und dann müsstest du dir selber (etwas unschön) eine rekursive Löschfunktion basteln oder so eine nehmen: http://lixlpixel.org…rectory_delete/ um den Assetfolder vollständig zu löschen.

Gruß

ich hab mir mal den code des widgets angeschaut und ich glaube nicht, dass es sich dabei um ein programmierfehler handelt. hier mal zunächst der code, is zur interessanten stelle (letzte zeile):

<?php





public function init()


	{


		list($name, $id) = $this->resolveNameID();





		if ($this->useCookies) {


			if (isset($_COOKIE[$id . self::COOKIE_SUFFIX]) && in_array($_COOKIE[$id . self::


				COOKIE_SUFFIX], array('text', 'html'))) {


				$this->setMode($_COOKIE[$id . self::COOKIE_SUFFIX]);


			}


		}





		$baseDir = dirname(__file__);


		$tinymce = Yii::app()->getAssetManager()->publish($baseDir . DIRECTORY_SEPARATOR .


			'tinymce');


?>

in der letzten zeile wird doch das verzeichnis, welches als parameter von pusblish übergeben wird komplett nach neuene dateien durchforstet, oder? das ist allerdings aus irgendwelchen gründen nicht der fall! wenn ich darin änderungen an dateien vornehme (meist *.js-dateien), dann werden diese nicht kopiert, trotz dieses aufrufs.

Update:

hab gerade änderungen an einer *.txt und einer *.php-datei gemacht und die seite neu geladen, fazit: beide wurden nicht in den assets-ordner übernommen.

Wiegesagt: Ein Widget sollte so gemacht sein, dass man Assetdateien niemals ändern muss! Dafür sollte der Autor sorgen, weil sonst der Sinn der Assets untergraben wird. Wenn irgendwas konfigurierbar sein soll, muss das Widget das in seinen Konfigurationsparametern vorsehen.

Wenn das sauber eingehalten wird, ist die Option mit dem YII_DEBUG nicht nötig. Glaube auch nicht, dass Qiang sich davon überzeugen ließe. (Ich spreche da aus Erfahrung ;) ).

Ich verstehe dann wohl immer noch nicht so recht, was es mit den Assets so auf sich hat?!  ???

Das von mir verwendete Widget hat ja mehrere Dateien, die es zum Laufen benötigt, eben alle *.js-Dateien, css, etc. Diese Dateien werden in den assets-Ordner kopiert, um darauf zugreifen zu können, da das Widget ja nicht zwangsweise an einem "öffentlichen" Ort liegen muss und somit auch für mehrere Projekte verwendbar ist. Soweit hab ich das verstanden.

Nun ist es aber doch so, dass ich an dem Quellcode des Editors, also den Assets Änderungen vornehmen kann, sodass sich Parameter, Bilder oder andere Dinge ändern. Diese Änderungen müsste der AssetManager doch dann erkennen und entsprechend im assets-Ordner anpassen, oder? Das wird doch per mit der Methode publish erreicht. Habe ich das richtig verstanden?

Wenn dem nicht so ist, dann frage ich mich, wie sich sonst Änderungen in den asset-Ordner auswirken sollen? Ich würde dann ja immer auf alten Versionen arbeiten. Und das manuelle löschen wäre ja auch nicht gerade toll.

Welche Änderungen möchtest du denn genau vornehmen? Den Quellcode von TinyMCE sollte man nie ändern, sonst ärgert man sich bei späteren Updates zu Tode. Alles was man an TinyMCE konfigurieren kann, sollte "von außen" machbar sein. Sprich über ein Konfig-Objekt, das man an init() übergibt, ohne den Quelltext zu ändern.

Wenn dann müsste man also da ansetzen und das Widget so erweitern, dass es die erforderliche Option kennt.

Mike hat natürlich vollkommen recht, wenn etwas konfigurierbar ist, müsste es durch das Widget auch konfiguriert werden können oder es müssten zumindest eigene Dateipfade z.B. für CSS Dateien (wie beim Yii Pager) angegeben werden können.

Allerdings teile ich nicht die Meinung oder besser gesagt sehe im moment nicht den Sinn darin, warum Assets nicht mehr verändert werden sollten…

Es macht doch durchaus Sinn, dass ein Assetfolder aktualisiert werden muss.

  1. Angefangen dabei, das ein Widget aktualisiert wird und z.B. weitere Assets verwendet <- die Bezeichnung bleibt schließlich die Gleiche, aber der Inhalt ändert sich. Jetzt wo ich das schreibe überlege ich gerade, ob es nicht sinnvoll wäre eine Versionsnummer an die Verzeichnisnamen anzuhängen oder sowas… muss nochmal überlegen.

  2. Wenn es nicht vorkommen sollte, warum wird dann bei einzelnen Assetdateien der Aufwand betrieben die Filetime abzugleichen, wenn man doch auch nur auf das Vorhandensein prüfen könnte?

Natürlich können Assetdateien verändert werden. Ich wollte nur klarmachen, dass das nur der Autor selbst machen sollte :)

Der Grund, warum die Zeitprüfung bei Verzeichnissen nicht passiert: Bei jeder Verwendung des Widgets müssten alle Dateien im Verzeichnis geprüft werden und Dateioperationen sind teuer. Das wurde daher aus Performancegründen nicht einbaut.

Daraus kann man schließen: Wenn man eine Komponente entwickelt, sollte man vermeiden, ganze Verzeichnisse zu publishen, sondern immer einzelne Dateien. Sonst ist derjenige, der die Komponente verwendet, gezwungen, seinen assets Ordner zu löschen, wenn die Komponente geupdated wird.

nur so btw: langsam verstehe ich auch. warum die änderungen am fckeditor teilweise nicht funtkioniert haben. ich habe diesesn editor auch schon mal eingebunden gehabt, aber bin daran gescheitert ihn richtig einzurichten.

diese editoren (fckeditor oder tinymce) basieren eben darauf, dass eine php oder javascript-datei als konfigurationsdatei herhält. der programmierer für den editor kann ja nicht riechen, was yii alles so für sachen damit vor hat =) somit scheint mir, dass ich immer wieder den ordner assets leeren darf, bei jeder neuen konfiguration, da die konfigurationsdatei ja eine assets-datei ist.

oder kann ich yii anweisen, diese datei zu publishen?! da dann ja das datum der datei geprüft wird?! wird die datei selbst dann auch im passenden unterverzeichnis abgelegt?

Klar kannst du auch selber Dateien publishen. Wenn du also wirklich nicht ohne js-Datei auskommst, könntest du sie z.B. nach /protected/js legen. Dann machst du:

<?php


$jsfile=Yii::app()->getPathOfAlias('application.js').DIRECTORY_SEPARATOR.'deinJs.js';


$jsurl=Yii::app()->assetManager->publish($jsfile);


// Jetzt ist die js datei in assets verfügbar und die URL dazu in $jsurl...


// Die kannst du jetzt in der Konfiguration von TinyMCE verwenden