Meowsalot: Grafik einblenden

Hallo alle,

ich binde meine Dokumente so ein

<?php 
if($Dokumente > 0) { 
foreach($Dokumente as $array){ ?>
<a href="/upload/dokumente/<?php echo htmlspecialchars($array['datei']) ?>" target="_blank">
<?php echo htmlspecialchars($array['datei']) ?></a><br>
?php }} ?>

habe ich hier eine Möglichkeit nur über CSS ein Symbol vor dem Link einzublenden? Also bei einer PDF sollte es ein PDF Symbol sein, bei einer Excel Datei ein Excel Zeichen usw.. oder muss ich beim Upload erst die Endung auslesen und speichern und beim Ausgaben dann prüfen welche Endung ich habe?

EDIT: OK, ich habe es:

.files [href*='.jpg'] {
  padding-left: 1.5em;
  background: url('bild.png') no-repeat;
  background-size: contain;
}

Bis bald!
Meowsalot (Bernd)

  1. Tach!

    <?php 
    if($Dokumente > 0) { 
    foreach($Dokumente as $array){ ?>
    [...]
    <?php }} ?>
    

    Das if($Dokumente > 0) ist einerseits logisch falsch, denn wenn es ein Array sein soll, ist es kein Integer, und der Vergleich Array mit Integer ist nicht sinnvoll. Zum anderen erzeugt das foreach sowieso keine Ausgabe, wenn das Array $Dokumente leer ist, und die Prüfung vorher ist nutzlos. Allerdings braucht man sie, wenn vor und/oder nach der Schleife noch Dinge auszugeben sind. Es reicht dann aber if ($Dokumente), denn nur ein volles Array ergibt true im booleschen Kontext.

    dedlfix.

  2. Besser ist finfo( $strDateiname )

        $finfo = new finfo( FILEINFO_MIME );
        $mime = $finfo -> file( $file );
    

    Aussenden:

        header( 'Content-type: ' . $mime );
        header( 'Content-Disposition: attachment; filename="' . urlencode( basename( $file ) ) . '"' );
        readfile( $file );
    

    Für die Symbole habe ich einfach eine nette Sammlung aus meinem Linux "raubmordkopiert" (z.B. aus [/usr/share/icons/breeze/mimetypes/32/](file:///usr/share/icons/breeze/mimetypes/32/)). Ich musste nur wenige umbenennen, weil finfo und die Icons leider nicht in jedem Fall übereinstimmen.

    function getFilesymbol( $mime ) {
       $mime = str_replace ( '/', '-', $mime );
       if ( is_file( $_SERVER['DOCUMENT_ROOT'] . 'pics/mime/' . $mime . 'png' ) ) {
           return '/pics/mime/' . $mime . 'svg';
       } else {
           return '/pics/mime/unknown.svg';
       }
    }
    
  3. Hej Meowsalot,

    ich hier eine Möglichkeit nur über CSS ein Symbol vor dem Link einzublenden?

    EDIT: OK, ich habe es:

    .files [href*='.jpg'] {
      padding-left: 1.5em;
      background: url('bild.png') no-repeat;
      background-size: contain;
    }
    

    Besser so:

    .files [href$='.jpg']::before {
      content: 'JPEG-Grafik herunterladen';
      background: url('bild.png') no-repeat;
      […]
    }
    

    Man beachte das Dollar-Zeichen anstelle des Sternchens. Du erwartest ja dass die Dateiendung zuletzt kommt. Dein Selektor erlaubt auch so etwas wie bild.jpg.exe

    Aber den Ansatz, solche Fälle serverseitig zu unterscheiden und die Informationen ins HTML zu schreiben, finde ich besser. Die hier gezeigte Lösung ist sehr grenzwertig. Ist das jetzt noch Darstellung (wofür CSS gedacht ist) oder doch schon Inhalt (wofür HTML gedacht ist)?

    Ich tendiere zu letzterem, finde aber, man sollte hier nicht dogmatisch rangehen, weil immerhin Screenreader auch CSS-generierte Inhalte vorlesen.

    Bedenklicher finde ich, dass diese Lösung bei abgeschaltetem CSS weder für Sehende, noch für Hörer etwas ausgibt. Da ist die HTML-Lösung deutlich robuster (also ein Bild mit Alternativ-Text direkt ins HTML. Am besten ein SVG)…

    Marc

    1. grep -Pv '^[# ]|^$' /etc/mime.types | wc -l
      

      behauptet, dass es 789 Mime-Typen gibt. Davon ist für einige keine Endung spezifiziert, für sehr viele gleich mehrere. Linux benutzt die Endung nicht zwingend.

      Deshalb schließe ich mich dem hier an:

      Aber den Ansatz, solche Fälle serverseitig zu unterscheiden und die Informationen ins HTML zu schreiben, finde ich besser.

      Wie groß soll denn sonst die CSS-Datei werden?

      Antwort: Mindestens 789 * 130 Bytes = 102570 Bytes - das mag nach mancher Ansicht noch durchgehen, aber wer soll die schreiben - und wie lange soll es womöglich dauern, die auf einem Mobilgerät zu verarbeiten?

      1. Tach!

        grep -Pv '^[# ]|^$' /etc/mime.types | wc -l
        

        behauptet, dass es 789 Mime-Typen gibt.

        Wie groß soll denn sonst die CSS-Datei werden?

        Antwort: 789 * 130 = 102570 -

        Und sie ist sicher nicht richtig, weil der Probleminhaber vermutlich nicht vorhatte, alle Dateitypen auszuzeichnen, sondern nur ein paar wenige, die für seine Anwendung relevant sind.

        das mag nach mancher Ansicht noch durchgehen, aber wer soll die schreiben

        Die Frage stellte sich auch für das Schreiben des serverseitgen Codes. Und wenn du dafür eine Schleife vorgesehen hattest, die kann man auch für das Erzeugen der CSS-Ressource verwenden.

        dedlfix.

        1. Und wenn du dafür eine Schleife vorgesehen hattest,

          Gute Güte. Nein. Das gilt natürlich nur so weit wie die Verwendung eines Objektes der Klasse finfo nicht in den Tiefen des Kompilates zu einer Schleife greift.

          finfo liefert den Mimetyp und aus dem wird, ganz ohne Schleife, die URI der Datei gebaut.

          Selbst wenn ich finfo nicht verwenden würde, dann gäbe es wohl - einmalig aus /etc/mime.types erzeugt - einen assoziativen Array mit den Endungen als Key.

          Und wenn du dafür eine Schleife vorgesehen hattest, die kann man auch für das Erzeugen der CSS-Ressource verwenden.

          Ja. Das würde ich wohl tun. Aber die wird eben auch mindestens 100000 Bytes groß und hat verdammt viele Einträge im Stil von .files [href$='.jpg']::before {...} die - auf dem http-client - letztendlich wie ein Pattern oder gar ein Regex verarbeitet werden. Das wird clientseitig, im Hinblick auf die Laufzeit (Hier die Zeit zwischen Empfang und vollständiger Darstellung) - sicherlich "teuer".

          1. Hej Regina,

            Ja. Das würde ich wohl tun. Aber die wird eben auch mindestens 100000 Bytes groß [...]

            wie @dedlfix bereits sagte: man hat es nie mit 700+ Datei-Arten zu tun. Meist reicht es Bilder (jpeg, jpg, gif, png, svg), Office-Dokumente und PDFs zu unterscheiden und ein letztes, generisches Icon für alle anderen Downloads vorzuhalten. du willst ja nicht nur nicht 700+ Fälle abfangen; du willst ja auch nicht dem Nutzer 700+ verschiedene Icons anbieten.

            Wer soll die denn alle kennen? - Ein Icon-System soll immer vereinfachen, sonst ist es nur eine Belastung, statt eine Hilfe…

            Marc

              • man hat es nie mit 700+ Datei-Arten zu tun
              • du willst ja nicht nur nicht 700+ Fälle abfangen; du willst ja auch nicht dem Nutzer 700+ verschiedene Icons anbieten.

              Das kann man in vielen Fällen vorher nicht wissen.

              1. Hej Regina,

                • man hat es nie mit 700+ Datei-Arten zu tun
                • du willst ja nicht nur nicht 700+ Fälle abfangen; du willst ja auch nicht dem Nutzer 700+ verschiedene Icons anbieten.

                Das kann man in vielen Fällen vorher nicht wissen.

                Verstehe ich nicht. Du verlinkst das mit der Startseite deiner Webpräsenz.

                Zielst du darauf ab, dass sich da etwas am bestehenden ändern kann?

                Falls ja, verstehe ich es trotzdem nicht. Klar, wenn man später mal meint ausschließlich superschlaue Nutzer zu haben, die ausnahmslos in der Lage sind, die Bedeutung von 700+ Symbolen intuitiv zu erfassen, könnte man sich mal überlegen, ob man das zu diesem Zeitpunkt umsetzt.

                Sag mir Bescheid, wenn der Fall eintritt. Ich nehme an, das ist dann der Tag, an den skynet aktiviert worden sein wird… 🙃

                Marc

                  • du willst ja nicht nur nicht 700+ Fälle abfangen; du willst ja auch nicht dem Nutzer 700+ verschiedene Icons anbieten.

                  Das kann man in vielen Fällen vorher nicht wissen.

                  Verstehe ich nicht. Du verlinkst das mit der Startseite deiner Webpräsenz.

                  Da steht: "code.fastix.org" ist (m)eine Präsentation mit Programmierbeispielen.

                  Zielst du darauf ab, dass sich da etwas am bestehenden ändern kann?

                  Wie wäre es mit "Updates, immer mal was Neues, ..."?

                  Und vor allem führt "Präsentation mit Programmierbeispielen." aber bei genügend Überlegung zu dem Ergebnis, dass die Anzahl der relevanten Dateitypen größer ist als auf Webseiten mit Katzenbildern und dass einerseits die "Webseite" (ein Rudel PHP-Skripte und Einstellungsdateien für den Apache) existiert und anderseits die Programmierbeispiele. Für ein neues Beispiel wird also nur ein Folder angelegt, zwei kleine Meta-Dateien werden angelegt und die Quelltexte und übrigen Dateien hineingepackt. (Und wie bei einem richtigen CMS kannst Du davon nichts sehen.)

                  1. Hej Regina,

                    • du willst ja nicht nur nicht 700+ Fälle abfangen; du willst ja auch nicht dem Nutzer 700+ verschiedene Icons anbieten.

                    Das kann man in vielen Fällen vorher nicht wissen.

                    Verstehe ich nicht. Du verlinkst das mit der Startseite deiner Webpräsenz.

                    Da steht: "code.fastix.org" ist (m)eine Präsentation mit Programmierbeispielen.

                    Zielst du darauf ab, dass sich da etwas am bestehenden ändern kann?

                    Wie wäre es mit "Updates, immer mal was Neues, ..."?

                    Und vor allem führt "Präsentation mit Programmierbeispielen." aber bei genügend Überlegung zu dem Ergebnis, dass die Anzahl der relevanten Dateitypen größer ist als auf Webseiten mit Katzenbildern

                    Ja, schon — aber mal abgesehen davon, dass ich noch nie eine Website mit Katzenbildern gemacht habe — verstehe ich immer noch nicht. Also du hast eine Webseite, die du mit einem eigenen CMS betreibst.

                    Aber was ändert das daran, dass kein Mensch die Bedeutung von 700+ Icons lernen will, um (D)eine Seite zu verstehen?

                    Jedes CMS lässt sich doch mit beliebigen Dateien füllen. Die Kunst ist, aus dem vorhandenen eine verständliche Struktur zu machen.

                    Ein iconsystem - wenn es denn konsistent benutzt wird - wird während dem Besuch einer Seite intuitiv gelernt, weil immer dasselbe Symbol neben beispielsweise der Wortmarke drucken steht. Bei 700+ Symbolen, werden die meisten Symbole nur ein oder zwei mal verwendet werden und deren Bedeutung soll sich (bis zum nächsten Besuch) merken?

                    Halte ich für eine Überforderung von 99,9% Deiner Besucher.

                    Ab einer bestimmten Menge von unterschiedlichen Dateien helfen die Endungen mehr als 700+ Bilder.

                    Wenn man dann noch (lange) Listen nach Dateitypen sortieren kann, finde ich auch schnell die, die für mcih relevant sind. Aber einer bestimmten Detailtiefe helfen Symbole nciht mehr weiter. Es sei denn, das Schriftgrafiken, auf denen gif, jpeg, xls… gemalt wurde und deren alt-Text lautet identisch.

                    Aber wenn man dann doch wieder nur Buchstaben hat, wo ist dann der Sinn? Kann man dann doch gleich Text verwenden?!?

                    Marc

                    1. Aber was ändert das daran, dass kein Mensch die Bedeutung von 700+ Icons lernen will, um (D)eine Seite zu verstehen?

                      Wie jetzt? Macht man eine Webseite für einen einzelnen Besucher?

                      Der PHP-Fuzzi ägert sich, wenn PHP als "unknown" angezeicht wird, der ini-Tracker ärgert sich, wenn .ini als unknown (oder text) angezeigt wird, Python-Fans wollen ihre Sprache mit einem Icon gewürdigt sehen, dem Perlianer kommen Tränen in die Augen, wenn es für Perlskripte kein eigenes Icon gibt und die Buntmacher werden sich fürchterlich aufregen, wenn GIF, PNG und SVG nicht optisch, also anhand des Symbols zu unterscheiden sind.

                      Und so lange ich die Icons nur aus /usr/share/icons raubmordkopieren muss und für die Zuordnung der Mime-Typen zur richtigen Grafik nur ein wenig gezaubert werden muss sorge ich für insoweit glückliche Grafiker, Perlisten, Schlangenfreunde, Programm-Konfigurierer und auch programmierende "Hauptschüler".

                      Zum "Warum".

                      Natürlich auch um zu zeigen, dass ich es kann. Außerdem habe ich so überhaupt mal einen Grund, auf meinem textlastigen Zeug den werten Besuchern auch mal eine Grafik zu präsentieren. Das nennt sich, glaub ich, "Werbung".

                      1. Hej Regina,

                        Aber was ändert das daran, dass kein Mensch die Bedeutung von 700+ Icons lernen will, um (D)eine Seite zu verstehen?

                        Wie jetzt? Macht man eine Webseite für einen einzelnen Besucher?

                        Ich schrieb kein, nicht ein…

                        Im Idealfall macht man eine Website nicht für alle, sondern für jeden einzelnen — diesem Ideal versuchen wir uns ständig weiter anzunähern.

                        Denn wenn man etwas für alle macht, ist es wahrscheinlich, dass man es am Ende für keinen gemacht hat.

                        Der PHP-Fuzzi ägert sich, wenn PHP als "unknown" angezeicht wird, [usw…]

                        Das zeichne es doch als "Programm" aus statt als "unknown" und erhalte sichtbar die Endung.

                        Oder stelle die zusätzlich in Kapitälchen, fett und bunt auf einen Blick sofort erkennbar dar. - Es ist ja nicht so, als ob es keine grafischen Möglichkeiten mehr gibt, wenn man auf Icons verzichtet.

                        Da kannst du dann auch ein Farbsystem verwenden, was den Nutzer zusätzlich unterstützt, z.B. alle serverseitigen Skripte blau, alle Grafiken grün usw.

                        Aber jetzt mal Butter bei die Fische: die üblichen Logos lassen sich ja i.d.R. nicht vernünftig auf Icon-Größe verkleinern. Da erkennen viel zu viele Menschen nur noch einen bunten Fleck (gebe Gott, dass das PHP-Logo erkennbar bleibt, die scheinen ja ziemlich aggressiv zu sein 😉). Wie sollen denn Deiner Meinung nach 700+ unterscheidbare Icons aussehen?

                        Das ist doch erst einmal ein Problem, das man lösen muss, bevor man so einen Icon-Satz verwendet. Wie hast du das denn gelöst?

                        und die Buntmacher werden sich fürchterlich aufregen, wenn GIF, PNG und SVG nicht optisch, also anhand des Symbols zu unterscheiden sind.

                        Ui - noch so eine militante Gruppe. 😉

                        Was sollen denn die Buntmacher gegen farbige Schrift haben? Bunt ist bunt, oder nicht?

                        Und so lange ich die Icons nur aus /usr/share/icons raubmordkopieren muss und für die Zuordnung der Mime-Typen zur richtigen Grafik nur ein wenig gezaubert werden muss sorge ich für insoweit glückliche Grafiker, Perlisten, Schlangenfreunde, Programm-Konfigurierer und auch programmierende "Hauptschüler".

                        Vielleicht ist da was dran, aber ich habe ja auch nie vorgeschlagen, gar nicht auszuzeichnen. Ich halte hier nur die Masse der Icons für unerkennbar. Der PHPler Mus sein Icon ja dann auch erst mal unter vermutlich relativ vielen ähnlichen immer wieder neu finden.

                        Zum "Warum".

                        Natürlich auch um zu zeigen, dass ich es kann.

                        Wenn jeder alles auf seiner Webseite zeigen würde, was er kann, gäbe es keine bedienbaren Webseiten mehr. Die Kunst liegt in der Auswahl der richtigen Technik und meist im Verzicht auf alles, was den eigenen Bauch pinselt.

                        Außerdem habe ich so überhaupt mal einen Grund, auf meinem textlastigen Zeug den werten Besuchern auch mal eine Grafik zu präsentieren.

                        Ich mag Deine Webseite! - Sie repräsentiert genau das, was ich von jemandem erwarte, der mich bei serverseitigen Aufgaben unterstützen sollte.

                        Die Texte würde ich etwas überarbeiten. Unter Hilfe beispielsweise erwarte ich erst mal, wie ich Hilfe bekomme, statt die Aussage, keine (kostenlose) Hilfe leisten zu wollen. Das kann man freundlicher und einladender formulieren, bzw schlicht sagen, dass du gerne hilfst und die Kosten dafür benennst (Stundenssätze für die von dir angebotenen Dienstleistungen). Solche Dinge lassen sich auch sehr hübsch optisch aufbereiten.

                        Auch ansonsten sehe ich, dass du — wenn du es willst, wie gesagt gefällt es mir so — viele Möglichkeiten hättest, Schmuckgrafiken und inhaltlich relevante Grafiken unterzubringen.

                        Das nennt sich, glaub ich, "Werbung".

                        Nein, nennt es sich nicht. Werbung geht anders.

                        Marc

          2. Tach!

            Und wenn du dafür eine Schleife vorgesehen hattest, die kann man auch für das Erzeugen der CSS-Ressource verwenden.

            Ja. Das würde ich wohl tun. Aber die wird eben auch mindestens 100000 Bytes groß und hat verdammt viele Einträge im Stil von .files [href$='.jpg']::before {...} die - auf dem http-client - letztendlich wie ein Pattern oder gar ein Regex verarbeitet werden.

            Es kommt letztlich darauf an, was man für einen Fall vorliegen hat. Bei beispielsweise einer Handvoll Typen und 1000 Dateien sind 5 CSS-Einträge leichter zu erstellen und schneller übertragen als 1000 <img>. 5 Requests für die Icons bleiben es in jedem Fall. Oder man nimmt CSS-Sprites oder vergleichbares, da kann <img> soweit ich weiß nicht mithalten ohne zusätzliche CSS-Unterstützung.

            Ich finde auch, dass das Icon ein verzichtbarer Zusatz ist, der im Prinzip nur das Leben erleichtert. Es geht keine Information verloren, denn die Endung wird vermutlich weiterhin angezeigt werden. Insofern sehe ich auch CSS als den passenderen Ort.

            dedlfix.

  4. Hallo @Meowsalot,

    dieser Code kann doch gar nicht funkionieren, denn

    <?php 
    if($Dokumente > 0) { 
    foreach($Dokumente as $array){ ?>
    <a href="/upload/dokumente/<?php echo htmlspecialchars($array['datei']) ?>" target="_blank">
    <?php echo htmlspecialchars($array['datei']) ?></a><br>
    ?php }} ?>
    

    hier in der letzten Zeile fehlt eine spitze Klammer, <?php statt ?php.

    Unabhängig davon: Du kannst das Ergebnis von htmlspecialchars in einer Variablen speichern und brauchst die Funktion nicht doppelt aufzurufen. Zudem habe ich deine Liste als solche ausgezeichnet:

    <ul>
    <?php
    foreach($Dokumente as $array){
        $name = htmlspecialchars($array['datei']);
         ?><li><a href="/upload/dokumente/<?= $name ?>"><?= $name ?></a></li><?php
    }
    ?>
    </ul>
    

    Mit dem Tipp von Regina kannst du auch „typisierte Links“ erzeugen:

    <ul>
    <?php
    foreach($Dokumente as $array){
        $name = htmlspecialchars($array['datei']);
        $finfo = new finfo(FILEINFO_MIME);
        $mime = htmlspecialchars($finfo->file($file));
    
         ?><li><a href="/upload/dokumente/<?= $name ?>" type="<?= $mime ?>"><?= $name ?></a></li><?php
    }
    ?>
    </ul>
    

    Anstatt der Dateiendung (IMHO kein gutes Kriterium um den Inhalt zu kennzeichnen) kannst du den MIME-Type für die Icons heranziehen.

    Viele Grüße
    Robert

    1. @@Robert B.

      ?php }} ?>
      

      hier in der letzten Zeile fehlt eine spitze Klammer, <?php statt ?php.

      Unabhängig davon:

      Sowas wie <?php }} ?> sollte im Code überhaupt nicht vorkommen.

      Stattdessen: die alternative Syntax. Die Gründe sind dieser Diskussion zu entnehmen.

      Meowsalots Code sähe damit zunächst einmal so aus:

      <?php if ($Dokumente > 0): ?>
      	<?php foreach ($Dokumente as $array): ?>
      		<a href="/upload/dokumente/<?php echo htmlspecialchars($array['datei']); ?>" target="_blank">
      			<?php echo htmlspecialchars($array['datei']); ?>
      		</a><br>
      	<?php endforeach; ?>
      <?php endif; ?>
      

      Dazu kommen natürlich noch die genannten Berichtigungen von $Dokumente > 0 und <br>.

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    2. Kleiner Nachtrag:

      die Schleife mit finfo kann noch performanter werdern:

      $finfo = new finfo(FILEINFO_MIME);
      
      foreach($Dokumente as $array){
          $name = htmlspecialchars($array['datei']);
          $mime = htmlspecialchars($finfo->file($file));
      
          // …
      }
      
      1. Kleiner Nachtrag: ... noch performanter

        Oh. Es geht noch sehr viel besser.

        Sowohl in der HeaderName-Direktive (über einem Listing) als auch die ReadmeName Direktive (unter dem Listing) für mod_autoindex können PHP-Skripte angegeben werden. Steht nicht im Manual - geht aber.

        Will man andere Icons muss man das Alias-gesteuerte Verzeichnis eben manipulieren (am besten den Alias für /icons).

        Im verlinkten Manual stehen noch sehr viel mehr tolle Optionen - leider sind sich viele Betreiber darüber nicht im Klaren und verwenden eine Menge Kraft darauf, komplett eigene Listings zu produzieren - statt das mal eben mit ein paar Zeilen in der Konfiguration dem Apache aufzutragen - oder lassen die Directory-Listings einfach so traurig wie sie sind.