Velocity Template?

Hi!

hier sind meine Deps:

JSON:
dependencies {
    testImplementation "org.junit.jupiter:junit-jupiter-api:5.8.1"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.1"
    implementation "com.sparkjava:spark-core:2.9.4"
    implementation "com.sparkjava:spark-template-velocity:2.7.1"
    implementation "org.xerial:sqlite-jdbc:3.42.0.0"
}

Hier ist meine org/example/Main.java (Server):

Java:
package org.example;

import static spark.Spark.*;

import java.util.HashMap;
import java.util.Map;
import spark.ModelAndView;
import spark.template.velocity.VelocityTemplateEngine;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        get(
                "/",
                (req, res) -> {
                    Map<String, Object> model = new HashMap<>();
                    model.put(
                            "daten",
                            new Integer[][] {
                                {9, 8},
                                {7, 6},
                            });
                    return render(model, "index.vm");
                });
    }

    // declare this in a util-class
    public static String render(Map<String, Object> model, String templatePath) {
        return new VelocityTemplateEngine().render(new ModelAndView(model, templatePath));
    }
}

Hier ist meine resources/index.vm (Velocity-Template):

HTML:
<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />

    <script
        src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"
        integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw=="
        crossorigin="anonymous"
        referrerpolicy="no-referrer"
    ></script>
    <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" />
    <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>

    <body>
        <div class="">
            <h3>This is a Heading</h3>
            <table id="myTable" class="display">
                <thead>
                    <tr>
                        <th>Column 1</th>
                        <th>Column 2</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Row 1 Data 1</td>
                        <td>Row 1 Data 2</td>
                    </tr>
                    <tr>
                        <td>Row 2 Data 1</td>
                        <td>Row 2 Data 2</td>
                    </tr>
                </tbody>
            </table>
        </div>
        <script type="module">
            $(document).ready(function () {
                let table = new DataTable("#myTable", {
                    responsive: true,
                });
            });
        </script>
    </body>
</html>

Wie kriege ich denn jetzt 9 und 7 als Daten in Column 1 und 8 und 6 in Column 2?

Vielen Dank vorab.
 

KonradN

Super-Moderator
Mitarbeiter
Hast Du einmal nach Einführungen (Tutorial) zu velocity gesucht? Denn Du hast da ja noch keinerlei Grundlagen verwendet.

Eine Übersicht / minimale Einführung gibt Dir:
Introduction to Apache Velocity | Baeldung

Der Aufbau ist wie bei Script-Sprachen. Das Erste, das du brauchst, ist eine Schleife über die Daten. Also im tbody hast Du dann das, was in dem gegebenen Link beschrieben wurde als
loops#foreach directive allows looping over a collection of objects
(Und bei dem Beispiel hast Du dann statt dem li tag das tr tag)
Die Anweisung könnte dann sein:
#foreach( $row in $data )

Dann gibst Du die row ... Zugiff auf einzelne Elemente solltest Du per .get(index) Aufruf bekommen. Damit dürfte das Template an der Stelle so aussehen:
Code:
            #foreach( $row in $data )
            <tr>
                <td>$row.get(0)</td>
                <td>$row.get(1)</td>
            </tr>
            #end

Das ist aber alles ungetestet und hier im Forum geschrieben.
 
Hast Du einmal nach Einführungen (Tutorial) zu velocity gesucht?
Nö.

Dann gibst Du die row ... Zugiff auf einzelne Elemente solltest Du per .get(index) Aufruf bekommen. Damit dürfte das Template an der Stelle so aussehen:
Code:
Code:
            #foreach( $row in $data )
            <tr>
                <td>$row.get(0)</td>
                <td>$row.get(1)</td>
            </tr>
            #end

Das ist aber alles ungetestet und hier im Forum geschrieben

Jup, das funktioniert zwar, wenn man anstatt data daten verwendet (wieso machst du es eigentlich nicht gleich richtig?):

1691743215999.png

Aber mit mehr als 2 Columns funktioniert es nicht mehr.

Könntest du vielleicht ein richtiges Beispiel bringen? Würd mir helfen.
 
Damit funktioniert es jetzt zwar:

HTML:
<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />

    <script
        src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"
        integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw=="
        crossorigin="anonymous"
        referrerpolicy="no-referrer"
    ></script>
    <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" />
    <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>

    <body>
        <div class="">
            <h3>This is a Heading</h3>
            <table id="myTable" class="display">
                <thead>
                    <tr>
                        <th>Column 1</th>
                        <th>Column 2</th>
                    </tr>
                </thead>
                <tbody>
                    #foreach($row in $daten)
                    <tr>
                        #foreach($col in $row)
                        <td>$col</td>
                        #end
                    </tr>
                    #end
                </tbody>
            </table>
        </div>
        <script type="module">
            $(document).ready(function () {
                let table = new DataTable("#myTable", {
                    responsive: true,
                });
            });
        </script>
    </body>
</html>

Allerdings ist der Source falsch eingerückt:

1691743955678.png

Wie macht man das vernünftig?
 

KonradN

Super-Moderator
Mitarbeiter
Dann solltest Du es evtl. einmal machen. Zumal es Dir ersparen würde, dass jemand auf die Schnelle im Forum antwortet und dann z.B. gewohnheitsmäßig englische Bezeichner verwendet statt deutsche. Sowas scheint Dich ja massiv zu stören, was dann zu Kommentaren wie
wieso machst du es eigentlich nicht gleich richtig?
führt. Was etwas unglücklich ist, wenn man Hilfe erwartet. Hier im Forum wird es besonders kritisch, da dies bei einem neuen Account als Anzeichen für einen neuen Account von unserem "Tobias" gewertet werden kann.

Aber mit mehr als 2 Columns funktioniert es nicht mehr.
Doch natürlich funktioniert es auch mit mehreren Columns.
  • Wenn das Template nicht angepasst wird, dann werden die zusätzlichen Columns einfach nicht angezeigt.
  • Du kannst das Template anpassen und 3, 4 oder welche Anzahl Columns Du brauchst azeigen.

Wenn Deine Anforderung ist, dass Du eine beliebige Anzahl Spalten anzeigen können willst, dann kannst Du Dir das #foreach anschauen, das ich bereits gebracht habe um auf ein Array zuzugreifen (Da war es der Zugriff auf ein 2D Array um die 1D Array zu bekommen). Das würde 1:1 auch mit dem 1D Array funktionieren um die Werte zu bekommen.
 

KonradN

Super-Moderator
Mitarbeiter
Wie macht man das vernünftig?
Wer achtet auf die genaue Formatierung vom HTML eines Generators?

Ich würde erst einmal vermuten, dass dies an einem Mix an Tabs / Leerzeichen liegt und die Formatierung daher so ist. Wenn Du also Dein Template bereinigst, dann sollte das Ergebnis auch stimmig sein.

Ansonsten könnte man - wenn einem dies wichtig ist - noch eine HTML Formatierung durchlaufen lassen. Dies könnte man z.B. mittels JSOUP durchführen.

Wenn für dich funktional ist, dass die Hälfte der Tabelle nicht zu sehen ist, dann hab ich eine andere Definition von "richtig". :)
Wie Du jetzt selbst erkannt hast, ist es eine Frage des Spezifikation. Da Du aber keinerlei Spezifikation gegeben hast, ist es unsinnig, von richtig / falsch zu sprechen.
 
Dieser Thread wird doch eh nicht stehenbleiben ... => Konrad kritisiert.

Für mich ist auch die Formatierung wichtig, die von einem HTML-Generator generiert wird ... vielleicht bin ich da etwas (zu) penibel.

Leerzeichen und Tabs habe ich überprüft, aber vielleicht liegts am Encoding.
 
Hab es nun hinbekommen. Hattest recht, die einzelnen Spaltenwerte explizit aufzurufen (die Anzahl ist ja fest...), ist vielleicht besser, und auf die Einrückung im generierten HTML kommt's auch nicht an. Sehr schön.

Nur die angelegte .jar mit allen Abhängigkeiten ist inzwischen ~ 20 MB groß. 😅 Spark ist als Microframework aber super!
 

Ähnliche Java Themen

Neue Themen


Oben