Playing with PyLucid and bitching about Plone
After being extremely frustrated with trying to follow instructions and get tinyMCE working with the Django-CMS (equivalent to Plone's kupu-integration), I decided to call it quits for now. Maybe Django-CMS is the best thing since sliced bread, but if I can't get something basic like this to work, then it has to mature a bit more.
So I went in search after another Python-based CMS and found PyLucid. Simple installation, with its own Django and tinyMCE integrated from start! A bit confusing to jump around the different admin screens to get something done, but it worked (ugly like hell, in default styles) and had some templates and a plugin architecture. Unfortunately, the plugin-architecture that looked good on paper was sadly undocumented, there was some confusion about what were Django functionality and what was PyLucid functionality (reminded me of Zope/Plone, but without documentation). Also, nothing that could even come close to compare with the Plone contenttypes and archetypes were present, so after some days of experimenting and searching for external plugins, I decided to let PyLucid be for the moment and continue searching for yet-another-CMS (Java and PHP based stuff is out, as I programmed in these abonimations of languages, and after Python, it is hard to go backwards in the evolutionary chanin :-))
So why am I looking for another CMS, when I have Plone (and have previously ditched Drupal)? Because Plone itself works like a charm, gives me and my visitors a reasonable user experience (for the most part). But the performance of Archetype-based types when editing is abysmal (I'm talking 120 secs to load a page, another 100 secs to save). And most of that are happening somewhere deep down in Zope, that I can't even track with profiling, as it happens before the profiling starts (all profiled functions goes fast). And the standard solution to cache, is not working (all pages are made on the fly, some 10,000 of them) and I have a memory problem, as Zope decides to cache everything in ZODB to memory (making my process go to 200MB within minutes of restarting).
Enough complaining. I consider moving to Plone 3 (and pray that works), re-generate my Archetypes-based content-types with ArchGenXML (if that would help). But having some 10.000+ pages and a lot of references between them (and some dependencies on Archetypes addons), it feels like a daunting task to migrate (especially as I can't run two Plones in parallel, due to memory restrictions). Time will tell.
Oh, and what do I want from a CMS? JS-based editing, Lucene-like search, TTW-administration (both CMS and User-content based, even if I could skip the CMS-part if something good shows itself), extensible plugin-system, CSS and XHTML-compatibility, lots of JS functionality (as I like the Web 2.0 concepts). And this is only for starters :-)
- Category(s)
- Personally Roland
Experimenting with Django-CMS....
... and understanding why I like Plone so much (even if I sometimes find it inexplicable). Install Zope, install plone, add a plone site in zope and voila, you have a working site, including a number of advanced types and JavaScript integration and editing. And all this without even having to edit a number of config-files and understand why the examples doesn't work or hacking the HTTP-server to death or struggling to understand why you need something for development and something else for production.
With that said, I can't say that I in any way dislike Django-CMS, just that it is pretty hard to set-up when you're not into the "Django-mindset" (modifying Zope/Plone is equally frustrating, but at another point in the learning cycle).
Well, perserverance wins, or so they claim :-)
- Category(s)
- Personally Roland
MS IE Works again (sorta...)
Well, all it took was updating a Plone-component (qPloneTabs) to make it IE7 compatible (which affected some IE6 as well). There are still some design issues when using the MS IE, that are not present in Konqueror, Safari or Firefox usage, which I'll look into as soon as I have some spare time, but at least it work now (if not, please contact me directly).
- Category(s)
- Personally Roland
Internet Explorer problems!
It has been brought to my attention that certain versions of MS Internet Explorer can't view my pages. Unfortunately, the version I have access to, manage it, but it has been proven to be a problem. Investigations are on-going on the root-cause and what to do about it.
Sorry for the inconveniance.
- Category(s)
- Personally Roland
Non-affordable customers...
For a service-company, like an un-named Outsourcing company, it is, in my opinion, paramount that the service-company and the customer stops treating each other as supplier-customer, and instead goes into partnership with each other. If the "customer" decides that the "supplier" must be challenged all the time and pressed for a better price, it makes the customer very unattractive and forces the supplier to abandon the customer (it may earn the customer a few dollars/euros in the short run, but will be detrimental in the long run).
On the other hand, if the "supplier" decides that the "customer" is only a cost and refuses to be flexible and only points to the contract, it will force the customer away (thereby making the supplier loose money).
From this, learn that the "customer is always right" is pure bullshit, as a supplier can't survive with such customers. And that the contract doesn't specify the relationship with the customer, but only defines the core around which it circles.
Unfortunately, if one part starts to exhibit such behavior, the other part will soon respond with the other, thereby going down a slippery slope fast.
No party can afford to squeeze the last dollar/euro from the other party, as it needs to be a partnership (with its ups and downs, as all partnerships) where profit-sharing has to be fairly equally divided (especially in todays marketplace, where switching costs goes down and new markets opens up all the time).
Just a thought, that has no relation to any current or former customers/employers... (as that would show intelligence, which is pretty rare).
- Category(s)
- Personally Roland
Too funny to miss!
Let's start with a warning: you need to be a serious programmer to appreciate this humour, but if you are, you'll risk splitting a vein laughing....
Oh, I am not the original author, I just found it on a blog, and signed at the bottom.
The Evolution of a Programmer
High School/Jr.High
10 PRINT "HELLO WORLD" 20 END
First year in College
program Hello(input, output)
begin
writeln('Hello World')
end.
Senior year in College
(defun hello
(print
(cons 'Hello (list 'World))))
New professional
#include <stdio.h>
void main(void)
{
char *message[] = {"Hello ", "World"};
int i;
for(i = 0; i < 2; ++i)
printf("%s", message[i]);
printf("\n");
}
Seasoned professional
#include <iostream.h>
#include <string.h>
class string
{
private:
int size;
char *ptr;
string() : size(0), ptr(new char[1]) { ptr[0] = 0; }
string(const string &s) : size(s.size)
{
ptr = new char[size + 1];
strcpy(ptr, s.ptr);
}
~string()
{
delete [] ptr;
}
friend ostream &operator <<(ostream &, const string &);
string &operator=(const char *);
};
ostream &operator<<(ostream &stream, const string &s)
{
return(stream << s.ptr);
}
string &string::operator=(const char *chrs)
{
if (this != &chrs)
{
delete [] ptr;
size = strlen(chrs);
ptr = new char[size + 1];
strcpy(ptr, chrs);
}
return(*this);
}
int main()
{
string str;
str = "Hello World";
cout << str << endl;
return(0);
}
Master Programmer
[
uuid(2573F8F4-CFEE-101A-9A9F-00AA00342820)
]
library LHello
{
// bring in the master library
importlib("actimp.tlb");
importlib("actexp.tlb");
// bring in my interfaces
#include "pshlo.idl"
[
uuid(2573F8F5-CFEE-101A-9A9F-00AA00342820)
]
cotype THello
{
interface IHello;
interface IPersistFile;
};
};
[
exe,
uuid(2573F890-CFEE-101A-9A9F-00AA00342820)
]
module CHelloLib
{
// some code related header files
importheader(<windows.h>);
importheader(<ole2.h>);
importheader(<except.hxx>);
importheader("pshlo.h");
importheader("shlo.hxx");
importheader("mycls.hxx");
// needed typelibs
importlib("actimp.tlb");
importlib("actexp.tlb");
importlib("thlo.tlb");
[
uuid(2573F891-CFEE-101A-9A9F-00AA00342820),
aggregatable
]
coclass CHello
{
cotype THello;
};
};
#include "ipfix.hxx"
extern HANDLE hEvent;
class CHello : public CHelloBase
{
public:
IPFIX(CLSID_CHello);
CHello(IUnknown *pUnk);
~CHello();
HRESULT __stdcall PrintSz(LPWSTR pwszString);
private:
static int cObjRef;
};
#include <windows.h>
#include <ole2.h>
#include <stdio.h>
#include <stdlib.h>
#include "thlo.h"
#include "pshlo.h"
#include "shlo.hxx"
#include "mycls.hxx"
int CHello::cObjRef = 0;
CHello::CHello(IUnknown *pUnk) : CHelloBase(pUnk)
{
cObjRef++;
return;
}
HRESULT __stdcall CHello::PrintSz(LPWSTR pwszString)
{
printf("%ws
", pwszString);
return(ResultFromScode(S_OK));
}
CHello::~CHello(void)
{
// when the object count goes to zero, stop the server
cObjRef--;
if( cObjRef == 0 )
PulseEvent(hEvent);
return;
}
#include <windows.h>
#include <ole2.h>
#include "pshlo.h"
#include "shlo.hxx"
#include "mycls.hxx"
HANDLE hEvent;
int _cdecl main(
int argc,
char * argv[]
) {
ULONG ulRef;
DWORD dwRegistration;
CHelloCF *pCF = new CHelloCF();
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// Initialize the OLE libraries
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoRegisterClassObject(CLSID_CHello, pCF, CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE, &dwRegistration);
// wait on an event to stop
WaitForSingleObject(hEvent, INFINITE);
// revoke and release the class object
CoRevokeClassObject(dwRegistration);
ulRef = pCF->Release();
// Tell OLE we are going away.
CoUninitialize();
return(0); }
extern CLSID CLSID_CHello;
extern UUID LIBID_CHelloLib;
CLSID CLSID_CHello = { /* 2573F891-CFEE-101A-9A9F-00AA00342820 */
0x2573F891,
0xCFEE,
0x101A,
{ 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
};
UUID LIBID_CHelloLib = { /* 2573F890-CFEE-101A-9A9F-00AA00342820 */
0x2573F890,
0xCFEE,
0x101A,
{ 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
};
#include <windows.h>
#include <ole2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pshlo.h"
#include "shlo.hxx"
#include "clsid.h"
int _cdecl main(
int argc,
char * argv[]
) {
HRESULT hRslt;
IHello *pHello;
ULONG ulCnt;
IMoniker * pmk;
WCHAR wcsT[_MAX_PATH];
WCHAR wcsPath[2 * _MAX_PATH];
// get object path
wcsPath[0] = '\0';
wcsT[0] = '\0';
if( argc > 1) {
mbstowcs(wcsPath, argv[1], strlen(argv[1]) + 1);
wcsupr(wcsPath);
}
else {
fprintf(stderr, "Object path must be specified\n");
return(1);
}
// get print string
if(argc > 2)
mbstowcs(wcsT, argv[2], strlen(argv[2]) + 1);
else
wcscpy(wcsT, L"Hello World");
printf("Linking to object %ws\n", wcsPath);
printf("Text String %ws\n", wcsT);
// Initialize the OLE libraries
hRslt = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(SUCCEEDED(hRslt)) {
hRslt = CreateFileMoniker(wcsPath, &pmk);
if(SUCCEEDED(hRslt))
hRslt = BindMoniker(pmk, 0, IID_IHello, (void **)&pHello);
if(SUCCEEDED(hRslt)) {
// print a string out
pHello->PrintSz(wcsT);
Sleep(2000);
ulCnt = pHello->Release();
}
else
printf("Failure to connect, status: %lx", hRslt);
// Tell OLE we are going away.
CoUninitialize();
}
return(0);
}
Apprentice Hacker
#!/usr/local/bin/perl
$msg="Hello, world.\n";
if ($#ARGV >= 0) {
while(defined($arg=shift(@ARGV))) {
$outfilename = $arg;
open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n";
print (FILE $msg);
close(FILE) || die "Can't close $arg: $!\n";
}
} else {
print ($msg);
}
1;
Experienced Hacker
#include <stdio.h>
#define S "Hello, World\n"
main(){exit(printf(S) == strlen(S) ? 0 : 1);}
Seasoned Hacker
% cc -o a.out ~/src/misc/hw/hw.c % a.out
Guru Hacker
% echo "Hello, world."
New Manager
10 PRINT "HELLO WORLD" 20 END
Middle Manager
mail -s "Hello, world." bob@b12 Bob, could you please write me a program that prints "Hello, world."? I need it by tomorrow. ^D
Senior Manager
% zmail jim I need a "Hello, world." program by this afternoon.
Chief Executive
% letter letter: Command not found. % mail To: ^X ^F ^C % help mail help: Command not found. % damn! !: Event unrecognized % logout
Anonymous
- Category(s)
- Personally Roland