"""
User-defined renderers.
"""

#c Copyright 2008-2025, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL.  See the
#c COPYING file in the source distribution.


from gavo import svcs
from gavo.web import grend


class CustomRenderer(grend.ServiceBasedPage):
	"""A renderer defined in a python module.
	
	To define a custom renderer write a python module and define a
	class MainPage inheriting from gavo.web.ServiceBasedPage.

	This class basically is a gavo.formal.nevowc TemplatedPage, i.e., you
	can define loader, getChild, render, and so on.

	To use it, you have to define a service with the resdir-relative path
	to the module in the customPage attribute and probably a nullCore.  You
	also have to allow the custom renderer (but you may have other renderers,
	e.g., static).

	If the custom page is for display in web browsers, define a
	class method isBrowseable(cls, service) returning true.  This is
	for the generation of links like "use this service from your browser"
	only; it does not change the service's behaviour with your renderer.

	In general, avoid custom renderers.  If you can't, see the upstream
	twisted documentation on twisted.web.resource for how to write them.
	"""
	name = "custom"

	def __init__(self, request, service):
		grend.ServiceBasedPage.__init__(self, request, service)
		if not service.customPage:
			raise svcs.UnknownURI("No custom page defined for this service.")
		pageClass, self.reloadInfo = service.customPageCode
		self.realPage = pageClass(request, service)

	@classmethod
	def isBrowseable(self, service):
		return getattr(service, "customPageCode", None
			) and service.customPageCode[0].isBrowseable(service)

	def render(self, request):
		return self.realPage.render(request)
	
	def getChild(self, name, request):
		return self.realPage.getChild(name, request)
