Skip to content

mxm, IT's mad science

Personal tools
You are here: Home » Products » Open Source » mxmCounter package for Zope
You can download mxm products here.

Due to it's technical and international nature, this section is in english.

Max M Has a blog too.

og er glad for mad


mxmCounter - A Simple Zope Hit Counter

A simple filesystem based hit counter for Zope, CMF & Plone, for multiple pages.

Current Version



You should install this product as usual. Unpack the archive with all contained directory information into your Zope products directory /lib/python/Products or /Products. Restart Zope.

Create an instance in the root of your zope server through the zmi. It will automatically get the id "mxm_counter".


On any page where you want a hit counter you should insert a few lines of code.

The most simple ZPT version is:

        <span tal:replace="python:here.mxm_counter.count(here)"/>

A more involved, but more graphically pleasing version could be:

        <span style="font-family: courier; 
                     border: 1px solid black; 
                     background-color: lightgray;
                     padding: 0px 4px;"
              tal:define="count python:here.mxm_counter.count(here)"
              tal:content="python:'%06i' % count">

In dtml it can look like:

        <dtml-var "mxm_counter.count(this())">

In rare situations you might want to show the count while not increasing it. Then you can write:

        <span tal:replace="python:here.mxm_counter.get_count(here)"/>

You should notice that you can insert the counter code in something like a footer script, and the counter will work automatically on all files that uses the footer.


Properties screenshot


Well, what can I say ....


List of ip adresses to ignore. Meaning that they don't increase the counter when they visit a page.

Examples of valid patterns:



When this is checked it only counts a browser once for each browser session. It stores a cookie in the browser that expires when the browser is restarted. There is not really any right way to do this. This was just the way I choosed to do it.


The counter saves the hits in memory when the number of uncomitted hits reaches the save_interval. Any hits that are not saved when zope is closed down, are lost. With the default setting of 100, it means that it saves the hits to disk once every 100 hits.

It also means that you can loose up to 100 registered hits when zope is shut down.

On the positive side it is a fast approach that doesn't grow the zodb.

The counters are stored in the var directory in a file called: counters.dict

If not loosing hits is very important to you, you can set the value to 1. But then you will write the counter.dict for every page count.

This should be fine for small sites with few hits.

The interval is overall for the site. Not pr. page. You don't need 100 hits on one page before it saves the counters, but 100 hits on any of the counted pages combined.

counter management/overview page

Counter management/overview

The view tab in the zmi will show a very simple page, with paths and counts. Sorted by number of hits in reverse order. You can use this if you don't want visible counters on the pages.

You can avoid showing the count on a page by using this code:

        <span tal:define="count python:here.mxm_counter.count(here)"/>

It will still increase the page count, but it will not be visible. You can then see it in the view tab of mxm_counter.

You can also set the count of a page to any value. If you set the count to 0, the page is deleted from the counter, until someone visits it again.

Tips: When you press "Set" the counts are saved to disk. So if you want to shut down your site, and don't want to risk loosing any counts, you can select a page and give it that same count as it allready has.


You can call the following methods on the tool:

            def count(self, obj, REQUEST=None):
                Increases The count For The Object. It will loose count 
                if object is moved.
                Returns the new count for that page.

            def get_count(self, obj, REQUEST=None):
                "returns the count without incrementing"

            def total_hits(self):
                "Returns the total number of hits on all counted pages"

Important notice

There can be only one!

Notice that only one instance if this product can be installed on a zope server!!!! Trying to install more than one instance will silently fail.

If you install the instance in a subfolder, you cannot later install it in the root folder. So install it there to begin with.

If you accidently install it in a subfolder, and has counts you don't want to loose, you can do it by first renaming the counters.dict in the var directory. Deleting the mxm_counter instance, rename the counters.dict back to the original name, and create a new mxmCounter instance in the root folder. It will then use the old counters.dict.

Probably this product should be made placeless. Well that is for another version.

There might be issues with (multiple) ZEO clients

I don't know. I have not tested it in this setup yet. Please try it and give me feedback.

License: GPL

Full license text here


You can get it here: mxmCounter.1.1.0.tar.gz

Created by maxm
Last modified 2004-03-18 09:17 AM


Posted by Anonymous User at 2004-02-26 10:39 AM
I will try it right now.

Have you thought of using UIDs instead of paths? Since we probably will all move to AT based objects, all objects will have a UID. It will keep the count when an object is moved, which is better imho.

(danny dot bloemendaal at companion dot nl)

No counters.dict

Posted by Anonymous User at 2004-03-07 03:39 PM
First of all: nice product. Very useful, at least to me. But i have a little problem:

On our server there's no "counters.dict" created. So after every restart, the counters are lost. We use the following configuration:

Zope Version
(Zope 2.6.4 (source release, python 2.1, linux2), python 2.2.3, linux2)
Python Version
2.2.3+ (#1, Jan 16 2004, 08:08:58) [GCC 3.3.3 20040110 (prerelease) (Debian)]

I installed mxmCounter in the zope root.
On a system with the same database but under W2k it works fine.

two tiny observations

Posted by Anonymous User at 2004-03-09 08:28 PM
1. Having the save interval set to 100, you will loose many hits(up to 99 :), if you stop the server. So when the site is under development, it's better to keep that interval low.
2. I've inserted the code to Archetypes objects, which basically can have at least three urls: MYOBJECT and MYOBJECT/view and MYOBJECT/myobject_custom_view (and then the edit views...) Would be nice to think about some acquisition settings or something, otherwise these hits won't be computed...

Anyway, thanks for the nice product!

Jároli József (jaroli at foek dot hu)

use Virtual Host

Posted by Anonymous User at 2004-04-23 04:00 AM
I have two domains.
"/"(root) is "".
"/test" is "".

I set dtml tags in "/index_html " and "/test/index_html".
Access, I get counts's.
Though in "set counters" tab shows 2 pages.

Additional method for 'proxy' objects?

Posted by Anonymous User at 2004-06-28 03:51 PM
I am using PloneLocalFolderNG (PLFNG) to proxy local filesystem files through Plone, and need to keep count of the hits on those files, too. The proxy'd files don't exist as real Zope objects, so they dont play well with the count() method.

Here is a method for the mxmCounter class that I use to expose increase_count() so I can call it from PLFNG:

def proxyObject_increase_count(self,url_path):
return increase_count(url_path, self.save_interval)

Would you consider adding something like this to the mxmCounter baseline? If so, I would eagerly add the hooks in PLFNG (which I am the current maintainer of) to utilize the method. thx!

Problems at inappropriate Zope restart

Posted by Anonymous User at 2004-07-26 02:57 PM
Recently my website has some exceptions.MemoryError, which causes Zope to restart itself. It is usually not transparent to users, but sometimes it raises an exception on restart, which prevents Zope from loading the whole mxmCounter product. This causes attribute error in pages where the template calls mxmCounter. Is there any way to make this product more robust, so as to resist these unexpected restarts?

Thx> yo @@@

2004-07-26T09:33:51 ERROR(200) Zope Could not import Products.mxmCounter
Traceback (most recent call last):
File "/usr/local/Zope-2.7.0/lib/python/OFS/", line 654, in import_product
product=__import__(pname, global_dict, global_dict, silly)
File "/usr/local/", line 1, in ?
import mxmCounter
File "/usr/local/", line 52, in ?
counters = get_from_file()
File "/usr/local/", line 43, in get_from_file
c = cPickle.load(f)


Posted by Anonymous User at 2004-08-03 03:15 PM
I have installed the product.It works correctly but I would like to use the metodos that there are defined in this page.How I can do it?
Thanks you

Counter of visits on footer

Posted by Anonymous User at 2004-08-04 09:51 AM
Hi all!

I would like put on the counter on footer. I have modified the footer adding to
him '<span tal:replace="python:here.mxm_counter.count(here)"/>' but this one
does not appear in the foot of the page. Somebody knows that I must do?

Note: I want to put the counter of my page just as the counter of this page, that is to say, a counter in the foot for each page.

Allowing arbitrary keys

Posted by Anonymous User at 2005-02-18 03:55 PM
It would be useful to have a couple of methods in mxmCounter which allow arbitrary keys for the counters rather than just the current URL, e.g.:

def count_for_key(self, key):
"Variant on mxmCounter.count which allows us to use an arbitrary key."
req = self.REQUEST
... continue as mxmCounter replacing 'url_path' with 'key' ...

def get_count_for_key(self, key):
"Variant on mxmCounter.get_count which allows us to use an arbitrary key."
return get_count(key)

(obviously count() and get_ccount() could then be recoded to use these)

This would make it easy for a user to use UIDs for Archetypes or whatever they wish. For example, I use a key which is a combination of the object's UID and an action name such as 'view'.

getting error

Posted by Anonymous User at 2005-02-28 07:30 AM
sorry if this not the right place to trouble shoot a problems, please let me know the right place
i installed mxm_counter in zope, the folder name is mxm_counter, that is the product name displayed in the zmi, its title under properties is "Installed product mxm_counter (1.1.0)" so that looked ok
i then added the "more graphically pleasing version" code to a custom version of 'document_byline' to get a count on all my pages. but get an error:

This site encountered an error trying to fulfill your request. The errors were:
Error Type
Error Value

the documentation seemed so straight forward i'm embarrassed to have such a basic problem, if anybody can offer some help i would greatly appreciate it.

can't seem to get installed

Posted by Anonymous User at 2005-03-11 06:22 PM
first let me say if that was you, max m., answering my last post in the plone user group, thanks
but still trying to install mxmCounter
i have tried this now on 2 separate plone installations on 2 different pc's with same result. i would give up except this product is ideal for me and need to understand the product install process for future reference as well
what i have done:
1. create and populate C:\Program Files\Plone 2\Zope\lib\python\products\mxm_counter\ folder with product files
2. restart plone, it appears i have a 'good install' i say this because mxmcounter shows up in the zope/control panel/products, and i can get properties, (version 1.1.0) and the readme has the readme.txt contents.
3. go to my plone site 'root' and go to add mxmCounter by selecting it from the drop down box, here's the strange part, after clicking mxmcounter, the screen flashes and just goes back to the starting point, the mxmcounter doesn't stay high lighted allowing me to select/click the 'add' button so i can complete the process??
i was expecting something similar to the add process for the fsCounter product where after you select/click the product in the dropdown box, it stays highlighted, then you select/click the add button, and you get a new screen where there are some id's/start counts/etc to answer, and then the installed product shows up with all the other current plone site objects?

did i miss some intermediate step after the 'zope' install and then adding to my plone site??

sorry this is dragging on, would appreciate very much help on this.

trouble shoot mxmcounter install

Posted by Anonymous User at 2005-04-07 11:19 PM
the problem is when trying to add mxmcounter to a plone site from the drop down list, after selecting mxmcounter in the list, the screen just kind of flashes and it doesn't stay selected to complete the add. its possible to have a corrupted counters.dict file in the data/var directory. to fix, stop zope, delete the file and restart zope.

ips_to_ignore not working for me

Posted by Anonymous User at 2005-06-02 05:24 PM
Thanks for creating this great product. The one problem I am having is that the ips_to_ignore setting does not appear to be working for me. After I enter my IP address in the ips_to_ignore list, mxmCounter continues to count hits from my machine. The server I am using is running Plone 2.0.5 on Zope 2.7.4-0 with Apache, and there are multiple Zope instances on it.

I would appreciate any suggestions.

Another great product

Posted by Anonymous User at 2005-11-11 11:56 PM

To restrict the viewing of the counter to reviewers/managers add:

tal:condition="python:'Reviewer' in member.getRolesInContext(here) or 'Manager' in member.getRoles()"


Counter is not incrementing

Posted by Anonymous User at 2006-06-21 08:36 AM
i have extracted the mxmcounter files to my root zope products.I have created an instance mxmcounter through ZMI and the id mxm_counter is also getting.I have inserted the graphical counter code which is given in the link to my page.The hits:0000001 is displaying like this and it is not incrementing when visits again.I have'nt set any counter property.
Please help me.

Top 5 Sites in a Portlet

Posted by Anonymous User at 2007-01-24 12:30 PM

i miss the function, that i can display the Top 5 (visited Sites)in a portlet with direct link or something. Does Anybody knows how it goes?

So Greets


Posted by Anonymous User at 2008-04-01 11:40 PM
What happens when we have 999999 hits?

A problem with zeo client

Posted by Anonymous User at 2008-12-23 07:54 AM
I fix all zeo client use one counter.dict but each zeo client has diffirent the number of object. It will the same number when you restart client. How can i fix it?

Counters.dict file need replacement regularly

Posted by Anonymous User at 2010-04-20 01:02 PM
I am using mxmcounter from past 2 years in my site, now that the hits on my site are increasing day to day, I am facing one problem frequently. The site crashes and the only thing resolves the problem is the counters.dict file should be replaced with the one I have in my backup. This would work for another 1 week or so and again the site crashes. This exercise is repeated regularly. What could be the reason. Please provide me solution for this if available

Setcounter does not work on Plone 4.2.1

Posted by Anonymous User at 2012-10-03 06:17 PM
I installed mxm counter my Plone 4.2.1 site.
Unfortunatelly, SetCounter does not work and stopped.
The following messages are shown.
How can I use SetCounter menu?

Site Error

An error was encountered while publishing this resource.

Error Type: KeyError
Error Value: standard_html_header

Troubleshooting Suggestions

* This resource may be trying to reference a nonexistent object or variable standard_html_header.
* The URL may be incorrect.
* The parameters passed to this resource may be incorrect.
* A resource that this resource relies on may be encountering an error.

For more detailed information about the error, please refer to the error log.

If the error persists please contact the site maintainer. Thank you for your patience.