2010-02-17 7 views
8

Ich habe mich umgeschaut, konnte aber keine Möglichkeit finden, * .html-Dateien einfach in Grails einzubinden oder zu rendern. Meine Anwendung benötigt g.render oder <g:render> Vorlagen, die als HTML-Dateien geliefert werden. Dazu müssen, wie wir wissen, HTML-Dateien in _foo.gsp Dateien konvertiert werden, um gerendert zu werden. Ich bin total überrascht, warum gibt es keine direkte Unterstützung für HTML oder gibt es eine?Rendern von HTML-Dateien in Grails

Danke!

Antwort

20

Eine offensichtliche Möglichkeit besteht darin, einfach Ihre HTML-Dateien von foo.html zu _foo.gsp umzubenennen und dann <render template="foo"> zu verwenden. Aber das ist so offensichtlich, dass ich mir sicher bin, dass du schon darüber nachgedacht hast.

Wenn Sie wollen einfach nur eine HTML-Datei machen, aus einem Controller Sie den text Parameter des renderController-Methode

def htmlContent = new File('/bar/foo.html').text 
render text: htmlContent, contentType:"text/html", encoding:"UTF-8" 

Wenn Sie innerhalb eines .gsp das Gleiche tun wollen nutzen können Du könntest ein Tag schreiben. So etwas wie die folgende (nicht getestet) funktionieren sollte:

import org.springframework.web.context.request.RequestContextHolder 

class HtmlTagLib { 

    static namespace = 'html' 

    def render = {attrs -> 

    def filePath = attrs.file 

    if (!file) { 
     throwTagError("'file' attribute must be provided") 
    } 

    def htmlContent = new File(filePath).text 
    out << htmlContent 
    } 
} 

Sie rufen können diesen Tag von einem GSP

<html:render file="/bar/foo.html"/> 
+0

Danke Don! Das sieht so aus (der zweite Teil also). Ich werde es versuchen und meine Ergebnisse hier aktualisieren. – sector7

+0

Don - weiß nicht, ob du das sehen wirst, hoffe ich. Ich habe den von Ihnen geposteten Code ausprobiert, aber es scheint, als müsste ich eine Datei relativ zu meinem Computer-Root-Verzeichnis angeben, z. "C: /grails2.0/..." Wie mache ich es relativ zu meinem Webroot-Verzeichnis arbeiten, wie die Render-Ansicht derzeit funktioniert, nach Dateien im entsprechenden View-Ordner suchen? – Ray

+1

@Ray Wenn Sie die HTML-Dateien unter Web-App, sollten Sie in der Lage sein, sie mit 'g.resource' –

3

mit Was ist es, Sie versuchen zu erreichen?

  1. Rendern von HTML von einem Controller? In diesem Fall müssen Sie nur den Benutzer zu einer Datei von Ihrem Steuerelement umleiten.

    redirect(uri:"/html/my.html")

  2. Benutze HTML-Dateien anstelle von gsp Template-Dateien? Die Sache ist, Grails ist eine "Convention over Configuration" -Plattform und das bedeutet, dass Sie einige Dinge "den Grails Weg" tun müssen. Die Dateien benötigen die _ und die .gsp, aber der Name kann sein, was auch immer Sie mögen, auch wenn es einfacher ist, wenn Sie den gleichen Namen wie der Controller verwenden. Was Sie daraus gewinnen, ist das Wissen, dass jeder Entwickler, der weiß, was in Ihrem Projekt steckt und wie er sie versteht, versteht, wie die Dinge miteinander verbunden sind und was ihnen den Einstieg erleichtert.

+0

abrufen In einem realen Szenario, könnte ich sagen, Dinge funktionieren nicht nach starren Konventionen. Ein Framework sollte zumindest das Arbeiten mit seinen grundlegendsten Elementen unterstützen - HTML in diesem Fall. Bei der Beantwortung Ihrer Frage haben wir eine einzige GSP-Seite, auf der mehrere Anzeigen gerendert werden. Jede dieser Anzeigen ist reine _GSP_ Vorlagen, aber ab und zu müssen sie HTML-Dateien direkt rendern, die in einen bestimmten Ordner abgelegt werden /some_folder/*.html In der TAGLIB, die ich erstellt habe, müssen wir zwischen Rendering von wechseln GSP-Vorlagen oder HTML-Dateien. Entschuldigung dafür, das zuerst nicht zu klären. – sector7

+0

Vielen Dank für das Aufräumen. Dons Antwort scheint eine gute Wahl für dich zu sein und ehrlich gesagt ist dein Bedürfnis spezifisch genug, um seine eigene benutzerdefinierte Taglib zu rechtfertigen. – xlson

1

Wenig Bit-Fest dem Beispiel des Don, funktioniert gut für mich

Import org.apache.commons.io.IOUtils

class HtmlTagLib { 

    static namespace = 'html' 

    def render = {attrs -> 

     def filePath = attrs.file 

     if (!filePath) { 
      throwTagError("'file' attribute must be provided") 
     } 
     IOUtils.copy(request.servletContext.getResourceAsStream(filePath), out); 
    } 
} 
0
Closure include = { attr -> 
     out << Holders.getServletContext().getResource(attr.file).getContent(); 
    } 

Es ist in Bezug auf die Web-App Ordner von Ihrem Grails Hauptanwendung

+0

Ich habe Ihren Ansatz geändert, um die Einbindung externer Dateien für das Rendering-Plug-in grails zuzulassen, wo Netzwerkpfade in höheren Umgebungen verpfuscht werden - mine endete wie folgt: 'def includeFile = {attr -> URL resource = Holders.getServletContext() .getResource (attr.file) InputStream content = resource.getContent() Zeichenfolge text = Inhalt? .text log.info "includeFile ($ attr) - Ressource: $ resource, content.text.size(): $ { Text? .size()} " aus << Text }' –

1

Ich wollte statische HTML/Ajax-Seiten in Grails App (v2.4.4 gehostet) schreiben, aber den Controller für verwenden die URL neu schreiben. Ich war in der Lage, dies zu erreichen, indem Sie die Datei auf dem Web-app/(für eine einfache Referenz) zu bewegen, und einfach den Render() -Methode mit ‚Datei‘ und ‚content‘ params, wie zum Beispiel:

// My controller action 
def tmp() { 
    render file: 'web-app/tmp.html', contentType: 'text/html' 
} 

Hinweis: Ich habe das nur mit run-app probiert und habe noch keinen Krieg gepackt und auf tomcat deployed.

Doc: http://grails.github.io/grails-doc/2.4.4/ref/Controllers/render.html

0

konnte ich @ momo Ansatz zur Verwendung von externen Dateien für Grails-Rendering-Plugin zu ermöglichen, in dem Netzwerkpfad würde in höheren Umgebungen verpfuschten bekommen - Mine endete wie:

def includeFile = { attr -> 
    URL resource = Holders.getServletContext().getResource(attr.file) 
    InputStream content = resource.getContent() 
    String text = content?.text 
    log.info "includeFile($attr) - resource: $resource, content.text.size(): ${text?.size()}" 
    out << text 
}