VRaptor 3 + Template

12 respostas
Vendramini87

Boa tarde,

Como eu “centralizo” as requisições HTTP para o VRaptor e as envie para um template? Nesse template, vou utilizar Velocity e gostaria de fazer o seguinte:

getTemplate(header);

getTemplate(variavel);

getTemaplte(footer);

Onde variavel seria o método resgatado por esse controller genérico.

E vcs têm algum conselho ou algum modo melhor de trabalhar dessa forma? Com templates e controller genérico?

Muito obrigado!

12 Respostas

Lucas_Cavalcanti

o jeito melhor de fazer isso é criar a classe:

@Component
public class VelocityPathResolver extends DefaultPathResolver {
    //delegate constructor

    @Override
    protected String getPrefix() {
         return "/WEB-INF/velocity";
    }

    @Override
    protected String getExtension() {
        return "vm";
    }
}

e então é só criar os templates seguindo a convenção do vraptor, substituindo jsp por vm:

IndexControler.home() ==> /WEB-INF/velocity/index/home.vm

E então é só configurar a servlet do Velocity para *.vm

Vendramini87

Ola, Lucas!

Eu tinha conseguido chegar nesse resultado ontem a noite, sim! Mas não tive tempo de atualizar o post aqui. Obrigado pela resposta :wink:

Outra coisa que eu fiz foi sobrescrever o método pathFor(); e redirecionar todas requisições para default.vm, onde terei o seguinte:

Se eu vou chamar, por exemplo, OrcamentoController.novo(), ele vai executar a lógica e redirecionar as requisições para default.vm, onde irei alterar o conteúdo dinâmicamente e o menu (pois o menu é diferente, dependendo do tipo de usuário). A minha dúvida é: onde irei instanciar o Template e o Context do Velocity? Na OrcamentoController.novo()? Pois ele irá renderizar a default.vm, mas antes precisa dar o merge com os dados, certo?

Na minha cabeça, faria o seguinte:

getTemplate(“default.vm”);

dentro do default.vm:

#parse(“header.vm”);

#parse(variavel.vm);

#parse(“footer.vm”);

Aí, o resultado disso seria exibido… mas como exibir esse resultado se automaticamente ele irá renderizar a default.vm? Eu posso até colocar isso dentro do método OrcamentoController.novo(), porém como inserir esse resultado todo na view? Será que deu pra entender?

abs!
André Vendramini

Lucas_Cavalcanti

vc não precisa do getTemplate, nem do context do Velocity… basta criar a classe que eu falei, registrar o Servlet do Velocity no web.xml e o vraptor vai redirecionar a requisição para o template do velocity…

o próprio servlet do velocity vai conseguir gerar o template e mostrar na tela, vc só precisa que os arquivos sigam a convenção que eu falei acima:

para o resultado do OrcamentoController.novo() vc vai criar o template /WEB-INF/velocity/orcamento/novo.vm

Vendramini87

<servlet> <servlet-name>velocity</servlet-name> <servlet-class>org.apache.velocity.tools.view.VelocityViewServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping>\

Está registrado antes do filtro do VRaptor mas não está renderizando .vm

#foreach($i in [1…5]) $i #end esse código não funciona, aparece na tela como texto.

Outra coisa… se eu quero criar um default.vm, e dentro dele conter header/conteúdo/footer, eu não deeria eviar todas as requisições para este vm ao invés de cada função do controller renderizar sua view? Pq dessa forma, teria que inserir na mão em todas as .vm. Entendeu?

Cara, valeu mesmo pela atenção :wink:

abs.
André Vendramini

Lucas_Cavalcanti

eu consegui fazer funcionar desse jeito… ou algo parecido com isso… qdo eu chegar em casa eu te mando o código que funcionou

qto ao header e footer, como vc vai precisar alterar dinamicamente o menu, vc pode usar o sitemesh:
http://www.opensymphony.com/sitemesh/velocity-decorators.html

ele é bem mais poderoso do que só header e footer, vc pode decorar páginas/urls específicas, vale a pena dar uma olhada…

Lucas_Cavalcanti

configurações que funcionaram:

web.xml:

<servlet>
		<servlet-name>velocity</servlet-name>
		<servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>velocity</servlet-name>
		<url-pattern>*.vm</url-pattern>
	</servlet-mapping>

PathResolver:

@Component
public class VelocityPathResolver extends DefaultPathResolver {

	public VelocityPathResolver(HttpServletRequest request,
			AcceptHeaderToFormat acceptHeaderToFormat) {
		super(request, acceptHeaderToFormat);
	}

	@Override
	protected String getPrefix() {
		return "/WEB-INF/velocity/";
	}

	@Override
	protected String getExtension() {
		return "vm";
	}

}

e templates em /WEB-INF/velocity//.vm

Vendramini87

Olá!

Velocity está funcionando!

Agora estou tentando colocar o sitemesh, mas devo estar errando alguma coisa boba.

Meu web.xml:

<servlet>
		<servlet-name>sitemesh-velocity</servlet-name>
		<servlet-class>com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>sitemesh-velocity</servlet-name>
		<url-pattern>*.vm</url-pattern>
	</servlet-mapping>
	
	<filter>
	    <filter-name>sitemesh</filter-name>
	    <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
	</filter>
	<filter-mapping>
	    <filter-name>sitemesh</filter-name>
	    <url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<servlet>
    	<servlet-name>velocity</servlet-name>
    	<servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
	</servlet>
	<servlet-mapping>
    	<servlet-name>velocity</servlet-name>
    	<url-pattern>*.vm</url-pattern>
	</servlet-mapping>

	<context-param>
        <param-name>br.com.caelum.vraptor.packages</param-name>
        <!-- Change this parameter to your app base package -->
        <param-value>sigo</param-value>
    </context-param>
    
	<filter>
		<filter-name>vraptor</filter-name>
		<filter-class>br.com.caelum.vraptor.VRaptor</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>vraptor</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>REQUEST</dispatcher>
	</filter-mapping>

	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>

Meu decorators.xml:

<?xml version="1.0" encoding="UTF-8"?>
<decorators defaultdir="/WEB-INF/decorators/">
    <decorator name="main" page="main.vm">
        <pattern>/WEB-INF/velocity/*</pattern>
    </decorator>
</decorators>

Em defaultdir já tentei tirar a última / mas tb nao deu certo.

Não está dando nenhum erro, porém, o template /decorators/main.vm não é aplicado as páginas.
O .jar do sitemesh está em /lib

abs.!

Lucas_Cavalcanti

tenta colocar

FORWARD

dentro do filtro do sitemesh… se não funcionar, é pq o sitemesh só tá pegando as urls que vc digita no browser… e os templates são chamados pelo vraptor, via request dispatcher.forward… mas acredico que colocando a linha acima deva funcionar

Vendramini87

Agora ele está passando pelo main.vm mas parece que não está chegando até as outras páginas… “para” nele.

main.vm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test - $title</title>
$head
</head>
<body>
<div id="content">
	$body
</div>
</body>
</html>

/velocity/orcamento/novo.vm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>novo teste</title>
</head>
<body>
xcvxvxdd
#set ($a = "teste")
$a
</body>
</html>
Vendramini87

Consegui!

Apenas retirei essa parte do web.xml:

<servlet>
    	<servlet-name>velocity</servlet-name>
    	<servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
	</servlet>
	<servlet-mapping>
    	<servlet-name>velocity</servlet-name>
    	<url-pattern>*.vm</url-pattern>
	</servlet-mapping>

Agora, gostaria de saber o por que. rsrs

Outra coisa… tem como criar arquivos .vm pelo menu do eclipse? Instalei o Velocity Web Edit, mas para criar os arquivos, ainda preciso criar .HTML e renomear para .vm

Grato pela atenção! :slight_smile:

Lucas_Cavalcanti

o que funcionou aqui:
web.xml: (não coloque a servlet do Velocity! só essa do sitemesh)

<servlet>
		<servlet-name>sitemesh-velocity</servlet-name>
		<servlet-class>com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>sitemesh-velocity</servlet-name>
		<url-pattern>*.vm</url-pattern>
	</servlet-mapping>

	<filter>
		<filter-name>sitemesh</filter-name>
		<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>sitemesh</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>FORWARD</dispatcher>
	</filter-mapping>

decorators.xml:

<decorators defaultdir="/decorators">
	<decorator name="main" page="main.vm">
		<pattern>*.vm</pattern>
	</decorator>
</decorators>

main.vm:

<html>

<head>
	<title>AAAAAA</title>
</head>

<body>
aaaaaaaaa<br/>

$body

bbbbbbb
</body>
</html>

/WEB-INF/velocity/mundo/boasVindas.vm: (resultado do olá mundo da apostila)

<html>

<body>
   Hello $string
</body>
</html>

resultado da requisição ao olá mundo:

<html>

<head>
	<title>AAAAAA</title>
</head>

<body>
aaaaaaaaa<br/>


   Hello olá mundo!


bbbbbbb
</body>
</html>

exatamente o esperado…

Lucas_Cavalcanti

Vendramini87:
Consegui!

Apenas retirei essa parte do web.xml:

<servlet>
    	<servlet-name>velocity</servlet-name>
    	<servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
	</servlet>
	<servlet-mapping>
    	<servlet-name>velocity</servlet-name>
    	<url-pattern>*.vm</url-pattern>
	</servlet-mapping>

Agora, gostaria de saber o por que. rsrs

Outra coisa… tem como criar arquivos .vm pelo menu do eclipse? Instalei o Velocity Web Edit, mas para criar os arquivos, ainda preciso criar .HTML e renomear para .vm

Grato pela atenção! :)


O pq de não funcionar eh que o outro servlet do sitemesh já faz a mesma coisa que o do velocity, então dava conflito…

pra criar arquivos .vm: new >>> File >> meuArquivo.vm =)
nunca mexi em nenhum plugin pro velocity, mas acredito que vc consiga configurar isso direto no plugin

Criado 21 de janeiro de 2010
Ultima resposta 24 de jan. de 2010
Respostas 12
Participantes 2