[Zope] Best Practice for including Javascript in Zope Applications

2008-01-01 Thread Matt Hollingsworth
Hello,

 

I'm new to developing for zope, and I have a quick question regarding some
best practices when using Javascript in zope applications.

 

I would like to use Ext JS (http://www.extjs.com/ ) in an application that I
am writing.  It is a fairly extensive library, so I didn't really want to
copy/paste every single file into a dtml method.  I looked all over the
place for some discussion on this subject, but only found things relating to
plone (which apparently has a javascript registry); however, I wish to stay
away from plone for this particular application. 

 

What should I do to use these libraries?  Is there a canned solution for
this sort of thing?

 

Thank you much!

 

-Matt

___
Zope maillist  -  Zope@zope.org
http://mail.zope.org/mailman/listinfo/zope
**   No cross posts or HTML encoding!  **
(Related lists - 
 http://mail.zope.org/mailman/listinfo/zope-announce
 http://mail.zope.org/mailman/listinfo/zope-dev )


RE: [Zope] Re: Best Practice for including Javascript inZope Applications

2008-01-02 Thread Matt Hollingsworth
Andreas Jung wrote:
 
...
 Larger JS frameworks like Dojo tend to be split across several files and
 directories. The fun starts when such frameworks load/reload stuff
 using relative URLs. A co-worker using Dojo intensively had to invest
 some time in order to integrate such a JS monster properly. As far as I
 remember Extjs also uses multiple files (but not as much as Dojo
 does)..so please check in advance.

 Another point: consider using CMF and putting your library files into a
 directory system view on the filesystem. This makes your life much
easier.

Or just upload via WEBDAV.
One of the biggest advantages of Zope is the isolation from physical
file system.

Regards
Tino

Hello,

Thanks to everyone for your help.  I thought about Tres's solution and
quickly discovered that I would be doing a *lot* of clicking/typing if I
wanted to upload all of the files necessary to make the ExtJS framework
available.   I'll look into the WebDAV idea; I didn't think of that until
you mentioned it.

However, I came up with another possible solution that may be generally
useful after some (a lot actually) of coaxing.  I threw this together in the
time between my new year's festivities :) : it's incredibly sloppy at the
moment, but before I worried about cleaning it up, I wanted to get some
feedback from you guys about it (pardon the annoying formatting problems):

def package_home(gdict):
Returns the location of the file that calls the function.  You 
must pass it globals() as the argument for it to work right.  

:Parameters:
gdict : dict
A dictionary containing all of the global definitions for the
module.  This is accessible via the python built-in function
globals()

:return: The fully qualified path for the directory in which the calling
module is residing
:rtype: string



filename = gdict[__file__] 
return os.path.dirname(filename)


class FileSystemResource(Implicit,Item):
FileSystemResource is meant to make it easy to access file system
objects
through Zope.  It works by taking over the object traversal process to
recursively return resources, simulating a directory structure, until
it finally reaches the end (__call__()), when it accesses the file
and returns it.

If you do 

js = FileSystemResource()

in the class that you are publishing, then 

http://www.domain.com/yourId/js/all.js

would return the contents of all.js.

:Authors: - Matt
:Date: 2007-1-1


def
__init__(self,path,name,cache=True,persist=False,sync=True,rootdir=package_h
ome(globals())):
Create a FileSystemResource with the specified name
self.path = path
self.name= name
self.cache = cache
self.persist = persist
self.sync = sync
self.rootdir = rootdir

if cache:
self._cache = {}
#   
# Hooks #
#

def __before_publishing_traverse__(self,obj,REQUEST):
Just print the request path so I can debug easier
#print REQUEST.path:  + str(REQUEST.path)
print REQUEST.path:  + str(REQUEST.path)


def __bobo_traverse__(self, request, key):
Takes the key, meshes it with the request, and
generates the object from that

full_path = os.path.join(self.path,key)

if self.cache:
if self._cache.has_key(key):
o = self._cache[key]
fsr = o[0]
mod_time = o[1]
file_size = o[4]
#If modtime isn't the same, refresh the resource

latest_access_time = time.localtime()
num_accesses = o[3] + 1

new_entry =
(fsr,mod_time,latest_access_time,num_accesses,file_size)


self._cache[key] = new_entry
return new_entry[0]
else:
o = FileSystemResource(full_path,name=None)
#Set the modification time
mod_time = time #TODO: Implement
latest_access_time = time.localtime()
num_accesses = 1
file_size = 0 #TODO: Implement
self._cache[key] =
(o,mod_time,latest_access_time,num_accesses,file_size)
return o

o = FileSystemResource(full_path)
print Returning object  + str(o)
return o

###
# ! End Hooks #
###

def cleanCache(self):
#TODO: Not implemented (placeholder vars so I'll remember what's in
the tuples)
for key,value in self._cache.items():
file_location = key
file_obj = value[0]
mod_time = value[1]
latest_access_time = value[2]
num_accesses = value[3]
file_size = value[4]
 

RE: [Zope] Best Practice for including Javascript in Zope Applications

2008-01-02 Thread Matt Hollingsworth
Yep!  I have had very good luck with it so far; my little hack that I posted
works like a (klutzy) charm and ExtJS is great with zope.  The ExtJS folks
are very well organized, and the library is quite powerful.  It's working
great.  However, my application doesn't have quite the segregation that
yours does; ExtJS and zope (DTML in particular) are much more intermingled,
and can't be easily separated.  This application is actually a frontend for
a Java library that controls instruments at CERN (a research lab I work
for), and I love the solution that it has presented.  It works like a charm.
(in case you're curious, it makes use of a wonderful python library I ran
across called JPype (http://jpype.sourceforge.net) to execute the Java code)

I am going to be accessing Zope through apache with the VHM, but there are
multiple reasons why I don't want to serve the js through apache.  This same
principle is the reason that I don't want to upload things through FTP or
WebDAV.  I'm making a product, and I would like to keep it atomic, i.e., I
want the only install procedure to be copy product folder to
instance/Products.  Uploading via WebDAV, or hosting the javascript using
separate software, defeats that purpose.  

The solution that Tom proposed (LocalFS) seems to be what I want, but the
problem is that I think it is way too out of date; it crashed my zope server
(2.10.5) when I installed it.  It says nothing can be found after I add an
instance through the ZMI, and this is after I fixed a deprecated import (
from OFS.content_types import find_binary - from zope.app.content_types
import find binary).  I had to completely remove the product to get my Zope
instance to work again.  

I'm getting the feeling that there isn't really a (recent) canned solution
for accessing file system content, which is... strange at best, considering
all the power that zope has at its disposal.  You would think that accessing
the file system would be present just because it is so simple to do.  I'm
not complaining, as I'm *very* happy with zope, I'm just surprised :).  I
realize that zope's principle is to store everything in the database, but
this is unacceptable for content such as video files, right?  I mean the
ZODB file would be absolutely humongous (and slow?  I don't know for sure
how it's implemented).

If there isn't already a working solution, I would be happy to come up with
one; I could just hack out the parts of LocalFS that work, add a few
features, and repackage it into a new product.  It's not difficult to do (my
little trivial solution already would work fine if I did a non-dumb
implementation of the file-serving logic), and as much as I would like to
use it for other projects, it would be worth my time.  For example, I want
to make a little video/music server as a personal project unrelated to my
current one, and I really don't want to store things in the ZODB if I can
help it... 1 video = +1 gig ZODB? :S

I don't know much about zope obviously, so if I get some vehement objections
to this route, I'll pick another :)

Thanks!

-Matt 

-Original Message-
From: Tim Nash [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, January 02, 2008 2:03 PM
To: Tom Von Lahndorff
Cc: Matt Hollingsworth; zope@zope.org
Subject: Re: [Zope] Best Practice for including Javascript in Zope
Applications

I am writing an application that uses extjs as the front end and zope
on the back and they work together really well.
I am using a webserver to server the extjs library and everything else
comes out of zope.  So far I have had no trouble with relative links
or files broken up in different locations. It may be because I have
fully committed to having an extjs front end. I typically serve a page
out of zope, it calls the extjs library as well as custom JavaScript
files. The web2.0 style page then makes multiple xhr calls back to
zope to load smaller html and json fragments. Works like a charm and
has the additional benefit of letting me cache the majority of the
front end in the webserver and in the users browser.

Have fun because you have just come across a wonderful
combination...extjs and zope!
Tim


On Jan 2, 2008 6:38 AM, Tom Von Lahndorff [EMAIL PROTECTED] wrote:

 On Jan 1, 2008, at 7:20 PM, Matt Hollingsworth wrote:

  Hello,
 
  I'm new to developing for zope, and I have a quick question
  regarding some best practices when using Javascript in zope
  applications.
 
  I would like to use Ext JS (http://www.extjs.com/ ) in an
  application that I am writing.  It is a fairly extensive library, so
  I didn't really want to copy/paste every single file into a dtml
  method.  I looked all over the place for some discussion on this
  subject, but only found things relating to plone (which apparently
  has a javascript registry); however, I wish to stay away from plone
  for this particular application.
 
  What should I do to use these libraries?  Is there a canned solution
  for this sort of thing?
 
  Thank you much!
 
  -Matt

RE: [Zope] Best Practice for including Javascript in Zope Applications

2008-01-04 Thread Matt Hollingsworth
Hello,

Ok, I came up with a solution that I like; today I spent a little while
making it so I don't have to load things into memory before they are served.
Now it works quite nicely for serving out js/css/gui pics.  I won't post
what I did right now, as I haven't really cleaned it up and I'm ashamed of
how it looks at the moment,  but I'll post the usage of it to see if anyone
would like to use it after I clean it up:

...
from util import FileSystemResource #it's just in a utility module for my
current project at the moment
...

MyZopeObject(Implicit,Item,Whatever):

#js and css are paths that are considered relative to my package
directory (not the cwd for zope).  It can be absolute too, if desired.
js = FileSystemResource(js,Javascript Repository) 
css = FileSystemResource(css,CSS Repository)

Now, say that there is ext-all.js in a directory called
/path/to/zope/Products/MyProduct/js/.  You could then link to the java
script file by going to http://domain.com:8080/myZopeObject/js/ext-all.js.
In particular, in dtml, I have a standard_html_header that looks something
like this:

==standard_html_header.dtml==

html
head

!--Set the title--
titledtml-var title/title

dtml-commentscript src=dtml-absolute_url;/js/navbar.js/!--GUTS
navbar--/dtml-comment


link rel=stylesheet type=text/css
href=dtml-absolute_url;/js/resources/css/ext-all.css

!--Source in local_js unless the variable isn't defined--
dtml-try 
dtml-in expr=local_js
script src=dtml-absolute_url;/js/dtml-sequence-item;/
/dtml-in
dtml-except!--Do nothing--
/dtml-try

/head

!--Start the body--
body class=dtml-id;-body id=dtml-id;-body

!--Set basic pre-nav header--
dtml-unless NO_HEADER
h1 id=main-titleThis is a title./h1
/dtml-unless

==!End standard_html_header.dtml==

Then in MyZopeObject, I wrap up my DTML in a method like so:

..other class stuff...

_main = DTMLFile(dtml/main,globals())
def main(self):
main_js=[ext-all.js,main.js]

return _main(self.REQUEST,local_js = main_js)


I did the whole local_js thing so I could control what JS got dropped into
what pages without having to write a different header for each one.  I will
probably also do the same thing for the css just in case I want
page-specific css files.

This is what I'm doing at the moment, and it's working great.  If this would
be useful to someone else, I'll give it more than an hour and a half of
thought, rewrite it more intelligently, and make it available.  Otherwise,
thanks to everyone for their comments!

-Matt

-Original Message-
From: Tim Nash [mailto:[EMAIL PROTECTED] 
Sent: Thursday, January 03, 2008 12:38 PM
To: Matt Hollingsworth
Cc: zope@zope.org
Subject: Re: [Zope] Best Practice for including Javascript in Zope
Applications

Matt,
  Please keep us updated on your strategy for serving extjs. I am also
considering making my application a product for distribution but I was
thinking along the lines of an install script for macs that would set
up the apache webserver. I also like your approach.

BTW, I haven't done it, but couldn't you just store an object in zodb
that has a pointer to  your video on the filesystem and access the
video via a zope product? But maybe that is what LocalFS does, I
haven't checked.

see ya in the extjs forum. Just do a search for zope
Tim


On 1/2/08, Matt Hollingsworth [EMAIL PROTECTED] wrote:
 Yep!  I have had very good luck with it so far; my little hack that I
posted
 works like a (klutzy) charm and ExtJS is great with zope.  The ExtJS folks
 are very well organized, and the library is quite powerful.  It's working
 great.  However, my application doesn't have quite the segregation that
 yours does; ExtJS and zope (DTML in particular) are much more
intermingled,
 and can't be easily separated.  This application is actually a frontend
for
 a Java library that controls instruments at CERN (a research lab I work
 for), and I love the solution that it has presented.  It works like a
charm.
 (in case you're curious, it makes use of a wonderful python library I ran
 across called JPype (http://jpype.sourceforge.net) to execute the Java
code)

 I am going to be accessing Zope through apache with the VHM, but there are
 multiple reasons why I don't want to serve the js through apache.  This
same
 principle is the reason that I don't want to upload things through FTP or
 WebDAV.  I'm making a product, and I would like to keep it atomic, i.e., I
 want the only install procedure to be copy product folder to
 instance/Products.  Uploading via WebDAV, or hosting the javascript using
 separate software, defeats that purpose.

 The solution that Tom proposed (LocalFS) seems to be what I want, but the
 problem is that I think it is way too out of date; it crashed my zope
server
 (2.10.5) when I installed it.  It says nothing can be found after I add an
 instance through the ZMI, and this is after I fixed a deprecated import (
 from OFS.content_types import find_binary

RE: [Zope] Re: The best way

2008-01-11 Thread Matt Hollingsworth
Thanks!  That solves my problem as well :).

-Matt

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Tres
Seaver
Sent: Friday, January 11, 2008 2:04 PM
To: zope@zope.org
Subject: [Zope] Re: The best way

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Garito wrote:
 Hi, all!
 If you have download the ZSM product you could see I put on it a zexp
 file with prototype and some other js file and a css file plus images
 
 This was only a prototype solution to bring you the chance to see how
 my ideas are but I think this is not a definitive solution
 
 Now my question:
 
 Which is the best zope way to serve this kind of files trying to avoid
 any other product dependence?
 
 Thanks a lot!

In the context of Five / Zope3, the static content items are
resources.  One strategy would be to create a Zope2 product with those
files in a subdirectory, e.g.::

  $ mkdir Products/garito
  $ cd Products/garito
  $ echo # ZSM product  __init__.py
  $ mkdir static
  $ cat  static/garito.css
  body {
background: #FF;
  }
  ^D

And then register that directory as a resource directory via ZCML::

  $ cat  configure.zcml
  configure xmlns:browser=http://namespaces.zope.org/browser;
browser:resourceDirectory
name=garito
directory=static
/
  /configure
  ^D

Now, when you start Zope2, you can pull in your static resources via
special URLs, like http://localhost:8080/++resource++garito/garito.css::

  $ cd ../..
  $ bin/zopectl start
  . daemon process started, pid=25240
  $ telnet localhost 8080
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  GET /++resource++garito/garito.css HTTP/1.0

  HTTP/1.0 200 OK
  Server: Zope/(unreleased version, python 2.4.4, linux2) ZServer/1.1
  Date: Fri, 11 Jan 2008 18:53:11 GMT
  Content-Length: 32
  Last-Modified: Fri, 11 Jan 2008 18:44:47 GMT
  Connection: close
  Cache-Control: public,max-age=86400
  Content-Type: text/css; charset=iso-8859-15

  body {
background: #FF;
  }
  Connection closed by foreign host.

In that product, you could also register a template / browser view which
includes your resources, e.g::

  $ cd Products/garito
  $ cat  garito.pt
  html
  head
   link rel=stylesheet type=text/css
 href=/++resource++garito/garito.css/
  /head
  body
  h1 Garito's view /h1
  /body
  /html
  ^D
  $ cat  configure.zcml
  configure xmlns:browser=http://namespaces.zope.org/browser;
browser:page
  for=*
  name=garito.html
  template=garito.pt
  permission=zope2.View
  /
browser:resourceDirectory
  name=garito
  directory=static
  /
  /configure
  ^D
  $ cd ../..
  $ bin/zopectl restart
  $ telnet localhost 8080
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  GET /garito.html HTTP/1.0

  HTTP/1.0 200 OK
  Server: Zope/(unreleased version, python 2.4.4, linux2) ZServer/1.1
  Date: Fri, 11 Jan 2008 19:02:05 GMT
  Content-Length: 151
  Content-Type: text/html; charset=iso-8859-15
  Connection: close

  html
  head
   link rel=stylesheet type=text/css
 href=/++resource++garito/garito.css /
  /head
  body
  h1 Garito's view /h1
  /body
  /html
  Connection closed by foreign host.

Which pulls in your static resources.



Tres.
- --
===
Tres Seaver  +1 540-429-0999  [EMAIL PROTECTED]
Palladion Software   Excellence by Designhttp://palladion.com
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHh72H+gerLs4ltQ4RAgwwAKDSJPrGAuwo++ShjWjZzyn06IDz1QCeK69s
+CIbgsCJkbRV5Tdh9XWEY9k=
=Du8x
-END PGP SIGNATURE-

___
Zope maillist  -  Zope@zope.org
http://mail.zope.org/mailman/listinfo/zope
**   No cross posts or HTML encoding!  **
(Related lists - 
 http://mail.zope.org/mailman/listinfo/zope-announce
 http://mail.zope.org/mailman/listinfo/zope-dev )

___
Zope maillist  -  Zope@zope.org
http://mail.zope.org/mailman/listinfo/zope
**   No cross posts or HTML encoding!  **
(Related lists - 
 http://mail.zope.org/mailman/listinfo/zope-announce
 http://mail.zope.org/mailman/listinfo/zope-dev )