Twitter Bootstrap is a relief to programmers like me who were never good at web-designing. It has a nice javascript library and there are already modules to integrate twitter-bootstrap with tapestry. There are a lot of good add ons coming up for bootstrap and one of my favourites is the Editable for Bootstrap. Every time I see such a library I wait for a oppurtunity to integrate it with Tapestry.
Continue reading
Tapestry and ‘Editable for Bootstrap’
Scrolling pages : tapestry5 & onScrollBeyond
This blog is about adding pagination in Tapestry 5 using jQuery based onScrollBeyond(). It might sound difficult but as always tapestry makes it so easy that you wonder whether it is worth blogging about :).
Continue reading
Tapestry source code viewer
A simple implementation of a SourceCodeViewer
would be to have a service for adding and listing the source code and a component to display it.
Continue reading
Tapestry: Using ComponentRequestFilter
This example is similar to Securing Tapestry pages with Annotations, Part 1. My use case is to redirect a user to the starting page of a multiple step wizard in case a request is directly made to an intermediate step and the session has not been properly setup. One way to solve this problem (the ugly way) is to add a condition to every entry point in the page
public class MyPage { @SessionState(create = false) private ShoppingCart shoppingCart; @OnEvent(EventConstants.ACTIVATE) Object activate() { if(shoppingCart == null) { return Index.class; } return null; } @OnEvent(EventConstants.SUCCESS) Object doSomething() { if(shoppingCart == null { return Index.class; } ..... }
The problem with this code is that you have to check this condition for all event-handlers(Form, EventLink etc). A more elegant solution would be to use annotation secured by a ComponentRequestFilter.
Continue reading
Tapestry Linkedin
Continuing from the Tweeting post and Facebook post, lets us extend the OAuth Service to enable us to update status on Linkedin. We start by creating LinkedinService
Continue reading
Tapestry : Using reCaptcha
There is already Captcha support build-in for Tapestry5 but doing something from scratch is always fun in Tapestry. So in this post we are going to use reCaptcha with Tapestry5. There are two ways of integrating reCaptcha in your website. One way is to add it statically and other using Ajax. We are going to use the former case.
Continue reading
Tapestry 5.3+ New Features : Part 2
AjaxResponseRender
This is one of the most useful feature of Tapestry 5.3. There is already a concept of Zone
in Tapestry for Ajax but now it is complimented by AjaxResponseRenderer
. This fills a lot of gaps at least for people coming from Wicket. It is a bit similar to AjaxRequestTarget
but empowered with Zones and JSON. I have compiled a small example demonstrating most of the features.
Continue reading
Tapestry 5.3+ : New Features
Tapestry 5.3 is ready for a beta release and there are many exciting features. You can read about them here. The intention of this post and the one following it is to provide some running examples to get you started
Continue reading
Tapestry Facebook Integration
Continuing from the Tweeting post, lets us extend the OAuth Service to enable us to post on a user’s wall. As all the hard work has already been done, we just have to tweak things a little.
Continue reading
Tweeting with Tapestry
For tweeting in java, there are not many options like there are in other languages especially ruby. The best solution I have found is scribe-java. Interfacing with this library is very easy but you waste a lot of time trying to find what to do when.
Continue reading
Tapestry JFreeChart integration
I just finished integrating JFreeChart
with Tapestry
. Each time you integrate a library with Tapestry
you are full of praise for the framework. This is something you can seldom say about other web frameworks.
I had two usages in mind.
- As a return value from an event handler.
- As a component which can be used to display
JFreeChart
and a corresponding imagemap
Tapestry & AjaxFormLoop
Tapestry mailing list has a constant flow of newbie questions related to AjaxFormLoop
component. This is a very powerful component but with some limitations that must be understood before using it.
AjaxFormLoop
allows, in a limited way, dynamic addition of components to a form. These components are laid out inside the AjaxFormLoop
. Each time the ‘Add New’ link is clicked, addRow
event is triggered. This event requires the event handler to return a new ‘value’ bean. A new row is added to the loop with the given set of components and these components if form fields are bound to the newly instantiated bean.
A Tooltip component for Tapestry
I was thinking of adding tooltips
using prototip but found a very good free solution in Opentip. This is a very nice library and very easy to integrate. I was able to integrate it with only a single modification to the script and that was to replace the default ajax support with the Tapestry’s own ajax support. Continue reading
A Tab-panel for Tapestry
Tab panels are used so often in component based web design that many frameworks provide an out-of-box implementation. ChenilleKit has one for Tapestry. Let us try another one.
The tab panel will require two components.
- A TabPanel component to manage the tabs and tab links.
- A Tab component representing a tab
A Modal Dialog For Tapestry
As Tapestry does not provide a Dialog Box, let us see how difficult(or easy) it is to create one on our own. We will use ModalBox as it has an MIT license and it is written in prototype (Soon this won’t be a criteria for choosing a script as Tapestry is going to be prototype independent). The ModalBox
script is very easy to use. There is a ModalBox.show()
method which displays a dialog box. It takes a dom element and configuration options as parameters. If you want to create a wizard just keep on using the same method inside the dialog box. There is also a ModalBox.hide()
method to hide the dialog. Continue reading
A Periodic Zone Refresh Mixin for Tapestry
Tapestry uses a concept of Zones
for Ajax based updates. Zones
are components which are used to identify/mark a portion of a component/page for Ajax updates. Usually zones are connected to client events of other components e.g. click
of EventLink
or ActionLink
component, change event of Select
component or submit
event of Form
component. But what if we just want a zone which refreshes itself with its own contents.This is what we are going to do. Continue reading
Ajax Upload for Tapestry
Tapestry has an excellent support for JavaScript and Ajax. It strikes a perfect balance between how much a framework should assist and how much the developer should do. Most component-based frameworks, rather than assisting, supervise and most action-based frameworks leave even the integration to the developer. Tapestry provides you with events which you can easily connect to your JavaScript events/functions and all the rest is, as I keep on saying, magic.
In this post, I will talk about integrating an Ajax based upload library, file-uploader with Tapestry.
Continue reading
A Simpler Select for Tapestry
After writing my last post, Howard came up with a better idea. Why to stick to only one implementation of Select
? If we need a simpler Select, why not create a simpler one. So, I came with a simple implementation!! Continue reading
Tapestry Magic #14: Easy Selection
Tapestry’s select component is very flexible and this flexibility comes at a small cost. One has to pass a SelectModel
and a ValueEncoder
as parameters to the Select
component. This seems too much work for simple use cases. With the help of class transformations, we can always find shortcuts. In this post, I will mix some of the useful techniques mentioned in the Wiki to make using Select
component easier. Continue reading
Meeting Plastic V: A Method Shadow Builder
There are two shadow builders in tapestry, PropertyShadowBuilder
(tapestry-ioc) and EnvironmentalShadowBuilder
(tapestry-core) . PropertyShadowBuilder
is used to create a service from a property of an object(source). It create a proxy for the service interface and then delegates all method calls of that service to the getter method of the source. In this post we will create a more generic shadow builder which will take a source, a method name and a set of parameters and in return create a service that will delegate all method calls to the given source method.
Continue reading
Meeting Plastic IV: Replacing interfaces
One of the most common use of class transformation is replacing interfaces by annotations. Earlier j2ee frameworks used to put restrictions on your classes by forcing you to implement a particular interface. Nowadays, modern frameworks just ask you to put an annotation here and there and the rest is handled by the framework. This gives you the freedom of working with pojos. Continue reading
Integrating Tapestry with Gravatar
Integration with Gravatar‘s avatar is all about embedding an img
tag into your page. To create a gravatar image link, the steps involved are :
- Create a hash from email id
- Append a type to get image in a particular format. e.g .jpg, .png etc
- Set query parameters. The currently supported are s(size), d(default), f(force default), r(rating)
Tapestry Magic #12 : Tapestry IOC aware JSR-303 Custom Validators
In JSR-303, adding a custom field validator is a two step process.
- Create an annotation which will be placed on a field to be validated
- Create a validator which implements
ConstraintValidator
and link it to the above annotation
Tapestry Magic #11: Integration with Jasypt for encrypting URLs
Jasypt is an Java encryption library which can be used for encrypting text, passwords, numbers, binaries etc. We, in this post, will use this library for encrypting Tapestry URLs. Now, why would you want to hide those beautiful tapestry URLs. Imagine a banking website where sensitive information like account numbers are passed as parameters to pages. Won’t it be dangerous to show this information in the browser’s address bar. By encrypting URLs you can hide this information and make your website more secure. Continue reading
Tapestry Magic #9: Integrating with hibernate and multiple database support
Tapestry5 already has a module for integration with hibernate. This module is restricted to only one database. In this post I will create a small module which can support multiple databases. I am not going to provide all the facilities that tapestry-hibernate module already provides but just enough to solve the multiple database access problem. Continue reading
Tapestry Magic #4: Integrating Guice
Tapestry Magic #3: Plugin Blocks
Blocks in Tapestry are tools which can be used to overcome the limitations of a static structure. One of the best usage of Blocks is the BeanBlockSource. I have used it in a similar way to create plug-n-play plug-in. I will try to demonstrate it with an example. Continue reading
Using ValueEncoders with Resteasy
The power of Tapestry’s ValueEncoder can be used with RestEasy by implementing javax.ws.rs.ext.ParamConverterProvider
import org.apache.tapestry5.ValueEncoder; import org.apache.tapestry5.services.ValueEncoderSource; import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; import java.lang.annotation.Annotation; import java.lang.reflect.Type; @Provider public class ValueEncodersProvider implements ParamConverterProvider { private final ValueEncoderSource valueEncoderSource; public ValueEncodersProvider(ValueEncoderSource valueEncoderSource) { this.valueEncoderSource = valueEncoderSource; } @Override public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) { final ValueEncoder<T> encoder = valueEncoderSource.getValueEncoder(rawType); if (encoder == null) { return null; } return new ParamConverter<T>() { @Override public T fromString(String value) { return encoder.toValue(value); } @Override public String toString(T value) { return encoder.toClient(value); } }; } }
Changing locale based on domain
Happy New Year to everybody!!.
With Tapestry one of the advantages is that you can override almost everything but then there are always some parts which are less overridable. One such place is setting locale based on some custom criteria. The locale logic is embedded a bit deeper than you expect into the request processing cycle and that might give you an impression that you won’t be able to override it. Continue reading
Spock @RunJetty
Working with Geb is fun especially when integrated with Spock. In order to write tests for a tapestry app, I wanted to have something on the lines of SeleniumTestCase which will automatically start and stop a jetty server. So I ended up writing a spock plugin for running jetty.
Continue reading