Message Boards

Adapting opengraph-hook to add Twitter specific meta tags

thumbnail
David Yari Podio Casares, modified 9 Years ago.

Adapting opengraph-hook to add Twitter specific meta tags

Junior Member Posts: 36 Join Date: 3/24/11 Recent Posts
Hi guys,

I've been trying to adapt the "opengraph-hook" to allow the user to add Twitter-specific meta tags also. I've downloaded the hook code from Github and tried to use it and I succeeded in the major part, except for a little problem with the filter that adds the namespaces to the HEAD tag.
In the class "com.fb.filter.OpenGraphFilter" there is this import:


import com.liferay.portal.kernel.servlet.BufferCacheServletResponse;


I've not been able to find this class in any jar of my Liferay (I'm using Liferay 6.1 EE), searching the web I've seen it exists in the 6.2 version.

So, the first question is, there's an equivalent class for Liferay 6.1 EE, and if so where is it?

Then I browsed the history of the class and I saw that before the "Manual upgrade of the hook to 6.2" commit, there was a code like this:


	@Override
	protected void processFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws Exception {

    (...)

		StringServletResponse stringServletResponse = new StringServletResponse(response);
		Thread currentThread = Thread.currentThread();
		ClassLoader contextClassLoader = currentThread.getContextClassLoader();
		currentThread.setContextClassLoader(PortalClassLoaderUtil.getClassLoader());
		try {
			processFilter(OpenGraphFilter.class, request, stringServletResponse, filterChain);
		} finally {
			currentThread.setContextClassLoader(contextClassLoader);
		}
		String contentType = response.getContentType();
		if ((contentType != null)&&(contentType.startsWith(ContentTypes.TEXT_HTML))) {
			String content = getContent(request, stringServletResponse.getString());
			System.out.println(content);
			ServletResponseUtil.write(response, content);
		} else {ServletResponseUtil.write(response, stringServletResponse);}
		
  }


I tried this code but it doesn't seems to work because the pages became corrupted and the explorer couldn't open them (the "content" var that I print always has a lot of strange characters so maybe it's encoded in some way)
Also, I don't get why the change of class loader for the current thread (I've tested the same code without the class loader change and it seems to work the same way)

Has anybody any advices or knowledge as to how to solve this problem?

Thank you!
thumbnail
Julio Camarero, modified 9 Years ago.

RE: Adapting opengraph-hook to add Twitter specific meta tags

Liferay Legend Posts: 1668 Join Date: 7/15/08 Recent Posts
Hi Yari,

I would be very happy to accept your contributions to the project. If you send me pull requests I will review them and merge them into the project.

Regarding that class, it is new in 6.2. I would be ok with having a branch in the project for 6.1 too.

In 6.1 we can do something similar using other classes. Have a look at ValidHtmlFilter.java which does the same thing but using the classes available in 6.1

cheers!
thumbnail
David Yari Podio Casares, modified 9 Years ago.

RE: Adapting opengraph-hook to add Twitter specific meta tags

Junior Member Posts: 36 Join Date: 3/24/11 Recent Posts
Julio Camarero:
Hi Yari,

I would be very happy to accept your contributions to the project. If you send me pull requests I will review them and merge them into the project.

Regarding that class, it is new in 6.2. I would be ok with having a branch in the project for 6.1 too.

In 6.1 we can do something similar using other classes. Have a look at ValidHtmlFilter.java which does the same thing but using the classes available in 6.1

cheers!


Hi Julio,

I have no problem sharing the code, but I don't know if a branch would be the optimal way. Your app is heavily focused in Facebook and has a lot of functionality I don't need so I've stripped it from the code (i.e. Facebook properties for communities, Facebook auto-login, Facebook widgets portlets), then added the Twitter-specific meta tags in the page properties (for Google+ it wasn't necessary as it uses the generic og:* metas). So it will not be a "6.1" version of your Facebook project but more like a "generic-social-media-opengraph-integration-LITE".

In any case I will be glad to hear your advice as to how can I share the code relating it to your project (I'm pretty new to GitHub ;-)

Cheers!
thumbnail
Julio Camarero, modified 9 Years ago.

RE: Adapting opengraph-hook to add Twitter specific meta tags

Liferay Legend Posts: 1668 Join Date: 7/15/08 Recent Posts
Even though the original scope of the project was facebook, I don't have any problem of adding twitter or google+ too.

The app for this feature can have a generic name too once it is uploaded to the marketplace.

If you can make your changes and then send me a pull request in github I can merge the parts that make sense for 6.2 and adapt them.

It should be easy following this steps from github. Specially the section "Pull Requests".

Thanks a lot!
thumbnail
David Yari Podio Casares, modified 9 Years ago.

RE: Adapting opengraph-hook to add Twitter specific meta tags

Junior Member Posts: 36 Join Date: 3/24/11 Recent Posts
Julio Camarero:
Even though the original scope of the project was facebook, I don't have any problem of adding twitter or google+ too.

The app for this feature can have a generic name too once it is uploaded to the marketplace.

If you can make your changes and then send me a pull request in github I can merge the parts that make sense for 6.2 and adapt them.

It should be easy following this steps from github. Specially the section "Pull Requests".

Thanks a lot!


Ok, I will check the project to remove any client-related info (project name, package names, etc) and try to share it when I'm done.

Cheers!
thumbnail
David Yari Podio Casares, modified 9 Years ago.

RE: Adapting opengraph-hook to add Twitter specific meta tags

Junior Member Posts: 36 Join Date: 3/24/11 Recent Posts
Well I already made it work.

The problem was that, for some reason, the server was sending the response with Content-Encoding: gzip. So when the html code was retrieved, it was gzip-compressed, and obviously trying to search/add text to that code made the compressed code corrupted.

I've solved it checking the Content-Encoding header, if it's gzip, I decompress the code, do the changes, and then compress it again before sending it.

The code would be something like that:



	@Override
	protected void processFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws Exception {

		(...)

		StringServletResponse stringServletResponse = new StringServletResponse(response);
		Thread currentThread = Thread.currentThread();
		ClassLoader contextClassLoader = currentThread.getContextClassLoader();
		currentThread.setContextClassLoader(PortalClassLoaderUtil.getClassLoader());
		try {
			processFilter(OpenGraphFilter.class, request, stringServletResponse, filterChain);
		} finally {
			currentThread.setContextClassLoader(contextClassLoader);
		}
		String contentType = response.getContentType();
		String contentEncoding = stringServletResponse.getHeader(HttpHeaders.CONTENT_ENCODING);
		boolean isGZIP = ((contentEncoding != null)&&(contentEncoding.toLowerCase().equals("gzip")));
		if ((contentType != null)&&(contentType.startsWith(ContentTypes.TEXT_HTML))) {
			String content;
			if (isGZIP) {
				content = decompress(stringServletResponse.getUnsyncByteArrayOutputStream().toByteArray(), response.getCharacterEncoding());
			} else {
				content = stringServletResponse.getString();
			}
			content = getContent(request, content);
			if (isGZIP) {ServletResponseUtil.write(response, compress(content, response.getCharacterEncoding()));}
			else {ServletResponseUtil.write(response, content);}
		} else {
			ServletResponseUtil.write(response, stringServletResponse);
		}
		
	}

    public static byte[] compress(String str, String encoding) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		GZIPOutputStream gos = new GZIPOutputStream(baos);
		gos.write(str.getBytes(encoding));
		gos.close();
		return baos.toByteArray();
    }

    public static String decompress(byte[] source, String encoding) throws Exception {
		GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(source));
		BufferedReader br = new BufferedReader(new InputStreamReader(gis, encoding));
		StringBuffer out = new StringBuffer();
		String line;
		while ((line = br.readLine()) != null) {out.append(line);}
		return out.toString();
    }



I still don't know the reason behind the loader class change for the current thread, If someone can explaint it I will be glad to hear it.