[1.14] Link-Generierung

Dieser Bereich dient dazu, neue Features zu diskutieren und für die Entwicklung zu dokumentieren. // This area is dedicated to new features including proposals and documentation.
Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

[1.14] Link-Generierung

Beitrag von dr.e. » 04.04.2011, 20:58:14

Hallo zusammen,

ich bin im Rahmen der FilterChain-Entwicklung und dem Artikel http://wiki.adventure-php-framework.org ... RL-Layouts auf eine Sache gestoßen, die im APF noch nicht so rund ist: Link-Generierung. Diese ist zwar relativ gut über den LinkHandler und FrontControllerLinkHandler zentralisiert, aber es ist zusammen mit einem eigenen URL-Layout über Filter nicht möglich, bestehende Anwendungen darauf zu migrieren - zumindest nicht ohne Code-Anpassung oder Quickhacks per Umschreiben der REQUEST_URI.

Ich bin daher gerade dabei, das konzeptionell über LinkSchemes zu lösen, die einem LinkGenerator zugewiesen werden und für die Generierung von URLs sorgen. Hinsichtlich des LinkHandler würde das wie eine Delegation der Aufgabe aussehen. Hierzu habe ich folgende Code-Struktur als POC vorgesehen:

Code: Alles auswählen

final class Url {
   const HTTP_PORT = '80';
   const HTTPS_PORT = '443';

   private $scheme;
   private $host;
   private $port;
   private $path;
   private $query = array();

   public function __construct($scheme, $host, $port, $path, array $query = array()) {
      $this->scheme = $scheme;
      $this->host = $host;
      $this->port = $port;
      $this->path = $path;
      $this->query = $query;
   }

   ...

   public static function fromString($url) {
      $parts = parse_url($url);

      // resolve missing parameters
      if (!isset($parts['scheme'])) {
         $parts['scheme'] = null;
      }
      if (!isset($parts['host'])) {
         $parts['host'] = null;
      }
      if (!isset($parts['port'])) {
         $parts['port'] = null;
      }
      if (!isset($parts['path'])) {
         $parts['path'] = null;
      }

      return new Url($parts['scheme'], $parts['host'], $parts['port'], $parts['path'], self::getQueryParams($parts['query']));
   }

   ...
}

interface LinkScheme {
   function formatLink(Url $basis = null, Url $update = null);
}

final class LinkGenerator {

   private static $LINK_SCHEME;

   private function __construct() {
   }

   public static function setLinkScheme(LinkScheme $linkScheme) {
      self::$LINK_SCHEME = $linkScheme;
   }

   public static function generate(Url $basis, array $params = array()) {
      return self::$LINK_SCHEME->formatLink($basis, new Url(null, null, null, null, $params));
   }

}

class DefaultLinkScheme implements LinkScheme {

   public function formatLink(Url $basis = null, Url $update = null) {
      ...
   }

}

LinkGenerator::setLinkScheme(new DefaultLinkScheme()); 
Die Anwendung gestaltet sich dann sehr einfach:

Code: Alles auswählen

LinkGenerator::generate(Url::fromString($_SERVER['REQUEST_URI']), array('foo' => 'bar')); 
Die Frage, die ich mir dabei aber stelle ist, welche Signatur für

Code: Alles auswählen

LinkGenerator: public static function generate(Url $basis, array $params = array()) 
und

Code: Alles auswählen

LinkScheme: public function formatLink(Url $basis = null, Url $update = null) 
wirklich sinnvoll ist. Die Klasse Url dient zunächst als Abstraktion einer wie auch immer gearteten URL, jedoch ist die erste Signatur des LinkGenerator nicht in der Lage, eine Änderung des Hosts zu verwirklichen und die Signatur des LinkScheme scheint auf den ersten Blick recht kompliziert. Letzteres ist aber generisch genug um alle Anwendungsfälle abzubilden.

Nun ist die Frage, in welcher Form die Signatur gewählt werden sollte um größte Flexibilität zu bieten, aber trotzdem einfache Anwendung zu generieren...

Welche Anwendungsfälle habt ihr bei der Linkgenerierung?
Viele Grüße,
Christian

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 05.04.2011, 19:37:57

Hallo zusammen,

ich bin inzwischen etwas weiter gekommen. Allerdings würde mich noch eine Sache interessieren um den POC abzuschließen:
  • Wie oft verwendet ihr die Parameter $urlRewriting und $encodeAmpersands in LinkHandler::generateLink()
  • Wie oft verwendet ihr die Parameter $urlRewriting und $encodeAmpersands in FrontcontrollerLinkHandler::generateLink()
Falls die Zahl > 0 ist, würde mich noch interessieren, was für ein Anwendungsfall das ist.

Danke für eure Hilfe!
Viele Grüße,
Christian

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [1.14] Link-Generierung

Beitrag von Screeze » 05.04.2011, 19:47:35

Hi,
die Idee an sich finde ich gut, aber die Anwendung würde ich als alles andere als "einfach" bezeichnen in dieser Form:

Code: Alles auswählen

LinkGenerator::generate(Url::fromString($_SERVER['REQUEST_URI']), array('foo' => 'bar')); 
Momentan hab ich noch keine großen Anwendungsfälle, abgesehen von dem standart htacces Mapping.

Den Paramater $encodeAmpersands find ich schon sinnvoll, wenn Links ins html eingebettet werden sollen müssen die schließlich kodiert werden, um valides html zu erzeugen.

$urlRewriting hat auch seine daseinsberechtigung. Ich bin mir nicht sicher ob ich das momentan bei mir schon einsetze, aber ich werds wohl demnächst brauch, und zwar in folgendem Fall:
Ich habe ein System was aus 3 einzelsystemen besteht (Hauptsystem, Gameserver, Static-server)
Hauptsystem und Gameserver nutzen rewriting, der static server nicht. Allerdings brauch ich trotzdem an manchen Stellen Links zu z.B. Bildern oder zum jsCssPackager, die ich ohne URL-rewriting generieren muss, auf den 2 anderen Systemen.

Was ich mir aber vorstellen könnte, ist in Zukunft für Hauptsystem und Gameserver 2 unterschiedliche URL-layouts zu haben, da die Anforderungen ziemlich unterschiedlich sind (erstere sollte möglichst kurz und Prägnant sein + SEO optimiert, letztere braucht sich nicht um SEO scheren, da hier aber alles mit AJAX und FC-Actions gemacht wird, wäre ein darauf angepasstes Schema teilweise schöner)
Das wäre vermutlich dann mit der neuen Umsetzung Möglich, korrekt?

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 05.04.2011, 23:32:48

Hallo Ralf,

danke für deine Rückmeldung. Ich habe die API nochmals redesigned, nachdem einige Dinge nicht so schön waren, wie ich sie gerne gehabt hätte. Die Anwendung gestaltet sich nun wie folgt:

Code: Alles auswählen

$url = Url::fromString($_SERVER['REQUEST_URI']);
$url->setHost('localhost');
$url->setScheme('http');
$url->mergeQuery(array('foo' => 'bar', 'baz' => '4', 'blubber' => null));
echo LinkGenerator::generate($url);

$url = Url::fromCurrent(true)->mergeQuery(array('gbview' => 'display', 'entryid' => null, 'foo' => null, 'bar' => null));
echo LinkGenerator::generate($url);

$url = Url::fromCurrent(true)
                ->setQueryParameter('gbview', 'display')
                ->setQueryParameter('entryid', null)
                ->setQueryParameter('foo', null)
                ->setQueryParameter('bar', null);
echo LinkGenerator::generate($url);

echo LinkGenerator::generate(new Url(null, null, null, '/foo/1/bar/2/blubber/3', array('foo' => '2'))); 
Hinzugekommen ist sowohl das fluent interface als auch eine neue Signatur, die nur eine URL-Abstraktion (Klasse Url) erwartet, die man sich entsprechend hinkonfigurieren kann. Der Einfachheit wegen hat die Klasse Url noch einige Factory-Methoden um eine solche aus einem String oder der aktuellen URL zu generieren.

Weiterhin kannst du auch ein explizites LinkScheme mitgeben, das dann zur Generierung genutzt wird. Das deckt die jeweiligen Ausnahmefälle in deiner Applikation ab. Grundsätzlich wird jedoch ein globales LinkScheme konfiguriert, das die jeweilige Funktion von LinkHandler und FrontcontrollerLinkHandler inkludiert und beispielsweise per

Code: Alles auswählen

LinkGenerator::setLinkScheme(new RewriteLinkScheme()); 
konfiguriert werden kann. Die LinkScheme-Instanz kann dann wie auch die ConfigurationProvider ein jeweils unterschiedliches Verhalten adaptieren (z.B. Rewrite-URLs).

Nun zu deinen Punkten:
Den Paramater $encodeAmpersands find ich schon sinnvoll, wenn Links ins html eingebettet werden sollen müssen die schließlich kodiert werden, um valides html zu erzeugen.
Das würde ich als Standard-Verhalten des DefaultLinkScheme sehen. Sofern das nicht gewünscht ist, kann es manuell durch Konfiguration des Schema angepasst werden. Zum Test habe ich den LinkHandler wie folgt angepasst, was auch den Anwendungsfall wiederspiegelt:

Code: Alles auswählen

$url = Url::fromString($url);
$url->mergeQuery($parameter);

$current = LinkGenerator::getLinkScheme();
$scheme = clone $current;

$scheme->setEncodeAmpersands($encodeAmpersands);

$link = LinkGenerator::generate($url, $scheme); 
$urlRewriting hat auch seine daseinsberechtigung. Ich bin mir nicht sicher ob ich das momentan bei mir schon einsetze, aber ich werds wohl demnächst brauch, und zwar in folgendem Fall:
Ich habe ein System was aus 3 einzelsystemen besteht (Hauptsystem, Gameserver, Static-server)
Hauptsystem und Gameserver nutzen rewriting, der static server nicht. Allerdings brauch ich trotzdem an manchen Stellen Links zu z.B. Bildern oder zum jsCssPackager, die ich ohne URL-rewriting generieren muss, auf den 2 anderen Systemen.
Korrekt, dafür soll es ja auch einen Anwendungsfall bzw. eine Möglichkeit geben. Ich stelle mir da folgendes vor:

Code: Alles auswählen

echo LinkGenerator::generate($url, new DefaultLinkScheme()); 
Damit generierst du einen Link ohne Rewriting. Genauso kannst du dich im umgekehrten Fall über ein nicht aktiviertes URL-Rewriting hinwegsetzen:

Code: Alles auswählen

echo LinkGenerator::generate($url, new RewriteLinkScheme()); 
Was ich mir aber vorstellen könnte, ist in Zukunft für Hauptsystem und Gameserver 2 unterschiedliche URL-layouts zu haben, da die Anforderungen ziemlich unterschiedlich sind (erstere sollte möglichst kurz und Prägnant sein + SEO optimiert, letztere braucht sich nicht um SEO scheren, da hier aber alles mit AJAX und FC-Actions gemacht wird, wäre ein darauf angepasstes Schema teilweise schöner)
Das wäre vermutlich dann mit der neuen Umsetzung Möglich, korrekt?
Das ist genau der benefit der Umsetzung. Du schreibst dir einfach einen Input-Filter und ein LinkScheme, registrierst beide und hast ohne Anpassung deiner Applikation ein neues URL-Layout. Aktuell ist das noch nicht ganz fertig, aber das ist zumindestens der Plan der Umsetzung. Um das zu gewährleisten, werde ich die API von LinkHandler und FrontcontrollerLinkHandler beibehalten, intern jedoch durch die jeweilien Link-Schemen ersetzen.

Hinsichtlich der Schemen hatte ich mir überlegt, entweder ein oder zwei unterschiedliche Schemen anzubieten, die alles beherrschen (Rewriting, FC-Actions, ...). Alles weitere kann man sich recht schnell selbst bauen. Das normale Link-Schema hat aktuell 20 Zeilen. Das ist nicht viel.
Viele Grüße,
Christian

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 10.04.2011, 16:51:54

Hallo zusammen,

ich habe inzwischen das Thema Link-Generierung für Actions durch eine weitere Methode im LinkScheme abgebildet: generateActionUrl(). Hinweise zur Migration gibt's schon mal unter http://wiki.adventure-php-framework.org ... enerierung, die Doku schreibe ich grade.

Da ich kein weiteres Feedback erhalten habe, bin ich meine privaten Webseiten-Projekte durchgegangen und habe die Implementierung dagegen validiert. Bis jetzt gab es keinen Fall, der nicht abbildbar gewesen wäre. Gibt es bei euch irgendwelche Spezial-Anwendungsfälle der Link-Geneierung? Vielleicht auch solche, die ihr bisher manuell baut? Falls ja, dann immer her damit. Genau solche suche ich! :)
Viele Grüße,
Christian

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 15.04.2011, 14:32:28

Hallo zusammen,

nachdem ich bei meinen Projekten keine weiteren Stolperfallen gesehen hatte gehe ich davon aus, dass die Implementierung passt. :ugeek: Die Anpassungen sind nun in den 1.14er Branch eingecheckt und Rückwärtskompatibel gehalten. LinkHandler und FrontcontrollerLinkHandler bestehen weiterhin, intern wurde die Funktionalität durch den LinkGenerator und die jeweiligen LinkScheme-Implementierungen ersetzt.

Sollte es Fehler geben, bitte einfach melden.
Viele Grüße,
Christian

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 20.04.2011, 23:46:03

Hallo zusammen,

nachdem die Implementierung nun abgeschlossen ist, habe ich auch die Doku fertig gestellt. Diese kann nun unter http://adventure-php-framework.org/Seite/138-Links eingesehen werden. Fragen und Anregungen immer gerne! :) Die englische Übersetzung folgt.
Viele Grüße,
Christian

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: [1.14] Link-Generierung

Beitrag von dave » 14.05.2011, 19:36:46

Hi,

nach längerer Abwesenheit (Urlaub war toll, super entspannt und sehr alkoholisch :ugeek:) bin ich endlich wieder bei meiner zweitliebsten Beschäftigung:

Bin beim Aktualisieren auf 1.14 bin ich auf gaaanz viele neue Error-Meldungen gestossen. Die Beta-Tester werden erstmal wieder doof aus der Wäsche gucken und viele Posts erstellen :roll:.

Ich bin dabei, die Link-Generierung umzubauen. Wird es den LinkHandler weiterhin geben oder fliegt der in Version 1.15 oder 1.16 komplett raus, sodass nur noch der LinkGenerator verwendet werden kann?

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 14.05.2011, 19:42:48

Hallo dave,

schön, dass du wieder da bist. :)
Bin beim Aktualisieren auf 1.14 bin ich auf gaaanz viele neue Error-Meldungen gestossen. Die Beta-Tester werden erstmal wieder doof aus der Wäsche gucken und viele Posts erstellen :roll:.
Jep, das Risiko muss man eingehen um eine schnelle Migration sicher zu stellen. ;)
Ich bin dabei, die Link-Generierung umzubauen. Wird es den LinkHandler weiterhin geben oder fliegt der in Version 1.15 oder 1.16 komplett raus, sodass nur noch der LinkGenerator verwendet werden kann?
LinkHandler und FrontcontrollerLinkHandler sind schon jetzt nur noch Skelette und verwenden intern den LinkGenerator. Hinweise zur Migration findest du unter http://wiki.adventure-php-framework.org ... enerierung.

Ich würde schon jetzt auf den LinkGenerator setzen, denn dieser ist konzeptionell deutlich flexibler. Solltest du Fragen haben, die durch die neue Doku noch nicht abgedeckt sind, immer gerne!
Viele Grüße,
Christian

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: [1.14] Link-Generierung

Beitrag von dave » 14.05.2011, 20:54:46

Ok, das habe ich mir schon gedacht. Bin schon dabei, auf den LinkGenerator umzubauen. Aber die neuen Features diedieser bietet sind schon genial! Respekt!

Wollte ja eig. die Umlaute und Sonderzeichen-Problematik angehen und Feedback zu den neuen Funktionen geben. Muss aber erstmal alle LinkHandler in LinkGeneratoren umbauen etc. ;)

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 14.05.2011, 21:51:43

Danke für die Blumen! :oops: Das Konzept schwebte mir schon etwas länger vor, aber ich habe die entscheidende Zielsetzung erst zusammen mit den neuen Filtern so umsetzen können, wie ich mir das vorgestellt hatte. Hintergrund siehe http://wiki.adventure-php-framework.org ... RL-Layouts.

Sollte dir beim Umbau etwas auffallen, was ich in der Doku oder dem Migrations-Artikel noch nicht beschrieben habe, melde dich einfach, dann kann ich die Doku dahingehend verbessern. Sollte es einen Fall geben, der (noch) nicht abgebildet werden kann, helfe ich natürlich sofort weiter.
Wollte ja eig. die Umlaute und Sonderzeichen-Problematik angehen und Feedback zu den neuen Funktionen geben. Muss aber erstmal alle LinkHandler in LinkGeneratoren umbauen etc. ;)
Das sollte nun auch einfacher funktionieren, da das APF nun einen globalen Zeichensatz kennt und die Filter-Ausdrücke per Attribut beeinflusst werden können. Solltest du Fragen haben, meld dich einfach.
Viele Grüße,
Christian

Coach83
Beiträge: 271
Registriert: 13.05.2010, 17:33:12
Kontaktdaten:

Re: [1.14] Link-Generierung

Beitrag von Coach83 » 25.05.2011, 12:48:00

Hallo Christian,

ich baue mir momentan meine Links für mein Backend so zusammen:

Code: Alles auswählen

protected function generateLink($linkParams){
     return LinkGenerator::generateUrl(Url::fromCurrent()->mergeQuery($linkParams));
}
Jetzt schleppe ich aber einen Haufen an nicht benötigten Parameter/Wert Paaren mit mir rum - weil die aus der aktuellen halt auch genommen werden.
Ist es möglich, dass ich nur die Werte, die ich neu definiere, in dem Link ausgebe?


** ich glaub ich habs grad selbst gefunden ***

Code: Alles auswählen

      
      protected function generateLink($linkParams){
          $url = Url::fromString($_SERVER['SCRIPT_NAME']);
          return LinkGenerator::generateUrl($url->mergeQuery($linkParams));
      }

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 25.05.2011, 13:03:06

Hallo Coach,

schön dich mal wieder zu hören! :)
Ist es möglich, dass ich nur die Werte, die ich neu definiere, in dem Link ausgebe?
Klar. Deine aktuelle Vorgehensweise generiert eine Url einfach aus der aktuellen. Sofern du eine eigene oder leere Url benötigts geht das so:

Code: Alles auswählen

$url = new Url(...);
$url = Url::fromString('/foo/bar'); 
Siehe auch http://adventure-php-framework.org/Seit ... entationen. Dieser kannst du dann deine eigenen Parameter mitgeben oder nicht mehr benötigte Parameter entfernen:

Code: Alles auswählen

// einfaches Hinzufügen
$url->mergeQuery($linkParams);

// Hinzufügen und entfernen nicht mehr benötigter Parameter
$url->setQueryParameter('foo', null);
$url->setQueryParameter('bar', null);

return LinkGenerator::generateUrl($url); 
Siehe auch http://adventure-php-framework.org/Seit ... chen-Links.

Mit der neuen Art der Link-Generierung ist also alles möglich, was sich fachlich für deine Anwendung umgesetzt werden soll. Du musst dir einfach überlegen, was die Instanz von Url enthalten soll und kannst sie dementsprechend konfigurieren.

Beantwortet das deine Frage?
Viele Grüße,
Christian

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: [1.14] Link-Generierung

Beitrag von dr.e. » 25.05.2011, 13:08:21

Hallo Coach,

hab' dein Edit offensichtlich zeitlich verpasst. :) Genau so kannst du das machen.
Viele Grüße,
Christian

Coach83
Beiträge: 271
Registriert: 13.05.2010, 17:33:12
Kontaktdaten:

Re: [1.14] Link-Generierung

Beitrag von Coach83 » 25.05.2011, 13:19:19

Danke Dir trotzdem für die ausführliche Antwort ;-)

Gesperrt

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast