Bundestagswahl 2009: Piratenpartei
Ohne zu sehr Politblogging zu betreiben... die Piraten sind ja eine Geschichte für sich. Wenn man einmal vom Namen absieht, denke ich, dass die relativ starke Konzentration auf wenige Themenkomplexe eine gute Sache ist und diese Themen theoretisch alle Bevölkerungsschichten ansprechen könnten bzw. sollten.
Die Wahrung des Grundgesetzes belegt dabei sicher den höchsten Stellenwert und fordert von den Piraten auch eine intensive Beschäftigung mit Themen außerhalb der IT, woran eine junge Partei ja nur wachsen kann.
Um jetzt nicht zu sehr abzuschweifen: Die Generation 40+ ist dabei wohl relativ schwierig zu erreichen und Spots, wie der folgende (der eindrucksvoll die Macht der Hintergrundmusik demonstriert), sind dazu ein Schritt in die richtige Richtung.
Bei der Bundestagswahl wird es den Sachsen allerdings nicht vergönnt sein, die Piratenpartei zu wählen (Infos dazu hier). Auch wenn Studentenregionen, wie Leipzig/Dresden/Chemnitz sicher noch ein paar Stimmen gebracht hätten. Mein Problem ist eher, dass die Kandidaten für die Landtagswahl keinen wirklich positiven Eindruck bei mir hinterlassen (jaja, bin halt ein oberflächlicher Mensch).
Jemand schon eine Ahnung, was zur Bundestagswahl gewählt wird? Links? Grün? Oder doch die BWLer Partei Deutschlands (BWLPD)? Ein ermäßigter Umsatzsteuersatz auf Haargel käme sicher vielen zu gute ;-)
*update*
Die Landtagswahlen sind ja nun vorbei (hoffe ihr wart alle fleißig wählen und habt meine fehlende Stimme ausgeglichen...)
Das Ergebnis ist nicht berauschend, aber dafür, dass die Piraten das erste mal angetreten sind, auch nicht schlecht. 1,9% sind es geworden. sie sind der Tierschutzpartei dicht auf den Fersen ;-)
Aber mal im Ernst: Wie kann nur jeder Zweite in diesem Land so verblendet sein und die Pseudochristen oder die SPD wählen. Von der NPD mit 5,6% brauch ich gar nicht erst anfangen...
Sei's drum. Ich lass' mir jetzt erstmal n schönes Steak im Garten schmecken :-)
*update2*
Eigentlich wollte ich noch ein paar Posts zu CDU, SPD, Grünen, ... diesem hier nachschieben. Aber mir liegt im Moment doch recht wenig an einer Politisierung dieses Blogs. Das ist eine recht mühselige Angelegenheit und nach dem Lesen meines letzten Comments hatte ich das Gefühl ein paar Mal aufspringen zu müssen und "BULLSHITBINGO!" zu rufen.
Den nachfolgenden Spot fand ich dennoch interessant und irgendwie erinnert er daran, wie weit sich die heutige SPD doch von ihren ursprünglichen Idealen entfernt hat. "Sozialismus" ist im aktuellen Sprachgebrauch ja zumindest etwas Extremes, was nur Radikale fordern können und eine rot-rote Koalition völlig undenkbar.
Und genau darum müsst ihr nun alle nach Hause laufen und euren Eltern sagen, dass sie gefälligst nicht die schwarze Pest wählen dürfen ;-)
*update3*
Die Wahl ist ja nun schon einige Tage her, aber ich möchte den Post nicht unabgeschlossen lassen und Ergebnisse anhängen. Ich war ja wieder mal nicht in der Lage meine stimme abzugeben, weil ich relativ spontan einen Kurzurlaub unternommen habe. Hätte am unschönen Wahlausgang aber wohl nichts geändert. Schwarz-Gelb (mit 33,8%/14,6%). Die nächsten 4 Jahre. Der Bundeswahlleiter hat auch noch ein paar interessante Grafiken zur Sache. Zum Beispiel über das Ost-West-Gefälle bei der Wahlbeteiligung oder die Verteilung der CDU-Wähler und die der LINKE-Wähler.
Ich wünsche uns allen natürlich viel Glück, dass der konservativ-liberale Mix nicht noch die Reste unseres Sozialsystems und Rechtsstaates abbaut und wir auch in ein oder zwei Jahren noch ein Fitzelchen Privatsphäre übrig haben.
Dynamically loading SyntaxHighlighter modules
If you're into publishing code on web pages, chances are that you might already know SyntaxHighlighter by Alex Gorbatchev. The idea of highlighting code at the client really is a good one. But until today I felt that adding even more JavaScript to this site might just be too much considering that I wouldn't need the syntax highlighting on every page and much less for every programming language. So why not load it dynamically?
My approach at this was to use jQuery and a regular expression to detect if syntax highlighting is needed and which programming languages are used. It supports SyntaxHighlighter 2.0's feature of embedded XML in other languages and loads the XML brush accordingly.
All you have to do is to adjust the path to the SyntaxHighlighter scripts und include it in your page. Stylesheets are NOT loaded automatically. It wouldn't be a problem, though. Perhaps in a future version. *update*: No sooner said than done! Stylesheets will now be loaded asynchronously, too. So, no need to include them in your page headers anymore!
/* simbaba.net */ jQuery(function() { var shRoot='/html/js/syntaxhighlighter/'; var theme="shThemeSimbaba.css"; var brushes=[]; jQuery("pre").each(function() { brushName=/brush:\s?(\w+);?/i.exec(this.className); if(brushName==null) { return true; } else { if(/html-script:\s?true;?/i.test(this.className) && jQuery.inArray("xml",brushes)<0) brushes[brushes.length]="xml"; brushName=brushName[1]; if(jQuery.inArray(brushName,brushes)<0) brushes[brushes.length]=brushName; } }); brusheslen=brushes.length; if(brusheslen>0) { jQuery.each(["shCore.css", theme], function() { jQuery.get(shRoot+"styles/"+String(this), function(c) { jQuery("head").append(""); }); }); jQuery.getScript(shRoot+'scripts/shCore.js', function() { sh=SyntaxHighlighter; SyntaxHighlighter.config.clipboardSwf = shRoot+'scripts/clipboard.swf'; jQuery.each(brushes, function() { file=null; switch(String(this)) { case "xml": case "xhtml": file='shBrushXml.js'; break; case 'actionscript3': case 'as3': file='shBrushAS3.js'; break; case 'bash': case 'shell': file='shBrushBash.js'; break; case 'c#': case 'c-sharp': case 'csharp': file='shBrushCSharp.js'; break; case 'css': file='shBrushCss.js'; break; case 'delphi': case 'pascal': file='shBrushDelphi.js'; break; case 'diff': case 'patch': file='shBrushDiff.js'; break; case 'groovy': file='shBrushGroovy.js'; break; case 'js': case 'jscript': case 'javascript': file='shBrushJScript.js'; break; case 'java': file='shBrushJava.js'; break; case 'jfx': case 'javafx': file='shBrushJavaFX.js'; break; case 'perl': case 'Perl': case 'pl': file='shBrushPerl.js'; break; case 'php': file='shBrushPhp.js'; break; case 'powershell': case 'ps': file='shBrushPowerShell.js'; break; case 'py': case 'python': file='shBrushPython.js'; break; case 'ruby': case 'rails': case 'ror': file='shBrushRuby.js'; break; case 'scala': file='shBrushScala.js'; break; case 'sql': file='shBrushSql.js'; break; case 'vb': case 'vbnet': file='shBrushVb.js'; break; default: brusheslen--; } if(file!=null) jQuery.getScript(shRoot+"scripts/"+file, function() { brusheslen--; if(brusheslen==0) SyntaxHighlighter.highlight({ 'wrap-lines':false, 'smart-tabs':false }); }); }); }); } });
Feel free to use this script in any way you want, but I'd be really happy if you would drop me a line if it was of any help :-)
Liferay 5.2 and anonymous blog comments
Liferay doesn't support comments by the guest user off the shelf. Let's see how we can change that...
We'll begin with changing the code in com.liferay.portlet.messageboards.service.impl.MBMessageServiceImpl to prevent it from throwing unwanted exceptions. We just need to edit one method:
public MBMessage addDiscussionMessage( String className, long classPK, long threadId, long parentMessageId, String subject, String body, ServiceContext serviceContext) throws PortalException, SystemException { User user; try { user = getUser(); } catch (PrincipalException pe) { user = UserLocalServiceUtil.getDefaultUser(CompanyThreadLocal.getCompanyId()); } MBDiscussionPermission.check( getPermissionChecker(), user.getCompanyId(), serviceContext.getScopeGroupId(), className, classPK, user.getUserId(), ActionKeys.ADD_DISCUSSION); return mbMessageLocalService.addDiscussionMessage( getGuestOrUserId(), null, className, classPK, threadId, parentMessageId, subject, body, serviceContext); }
Be sure to allow permissions to be given to the guest user by modifying ext-impl/src/resource-actions/blogs.xml:
<resource-action-mapping> <!-- ... --> <model-resource> <!-- ... --> <guest-defaults> <action-key>VIEW</action-key> <action-key>ADD_DISCUSSION</action-key> </guest-defaults> <guest-unsupported> <action-key>DELETE</action-key> <action-key>DELETE_DISCUSSION</action-key> <action-key>PERMISSIONS</action-key> <action-key>UPDATE</action-key> <action-key>UPDATE_DISCUSSION</action-key> </guest-unsupported> </model-resource> </resource-action-mapping>
When building the ext environment check that the XMLs within the resource-actions directory actually get copied.
There you go! Now we have just one more litte problem: spammers. To circumenvent them we'll use the Captcha tag and a few lines of code. Look at ext-web/docroot/html/taglib/ui/discussion/page.jsp. You'll notice 2 places where the user is supposed to enter his comment. Each one of them has a textarea with the following declaration:
<textarea id="<%= namespace %>postReplyBody<%= i %>" name="<%= namespace %>postReplyBody<%= i %>" style="height: <%= ModelHintsConstants.TEXTAREA_DISPLAY_HEIGHT %>px; width: <%= ModelHintsConstants.TEXTAREA_DISPLAY_WIDTH %>px;" wrap="soft" onKeyUp="document.<%= formName %>.<%= namespace %>postReplyButton<%= i %>.disabled = (this.value == '');"></textarea>
Directly below them add these lines:
<c:if test="<%= PortalUtil.getUser(request)==null %>"> <liferay-ui:captcha url="" /> </c:if>
This will make sure that logged in users won't be bothered by the Captcha. The empty URL attribute is a workaround for a problem one of my readers pointed out. If you want to know, why I do the hack with the invisible image, see here. Additionally you'll want to show an error message in case the user enters the wrong number. Add this line directly below the starting <form> tag:
<liferay-ui:error exception="<%= CaptchaTextException.class %>" message="text-verification-failed" /> <portlet:actionURL var="captchaURL" windowState="<%= LiferayWindowState.EXCLUSIVE.toString() %>"><portlet:param name="struts_action" value="/message_boards/captcha" /></portlet:actionURL> <div style="display: none;"><img src="<%= captchaURL %>" onload="<%= namespace %>initCaptcha(this.src);"/></div> <input name="<%= namespace %>captchaText" type="hidden" value="" />
Complement com.liferay.portlet.messageboards.action.EditDiscussionAction with the actual check of the Captcha. Search for the "Add message" comment and replace it with
// Add message User user = PortalUtil.getUser(actionRequest); if(user==null) CaptchaUtil.check(actionRequest);
Redirect the CaptchaException to the actual page by replacing line 97 with
else if (e instanceof CaptchaTextException || e instanceof FileNameException ||
If you have a better solution or questions about this one, don't hesitate to ask.
*update*
It turned out that the first version had a major flaw when it came to posting a reply to previously left comments (thanks for pointing that out!)
Therefore I modified the original post (especially the part with the Captcha tag). It's an ugly workaround but I didn't want to modify a whole lot from the original Liferay code.
Additonally you have to insert a little more JavaScript (which is fine because blog comments won't work without it, anyway).
The code will assure that every Captcha input field has a unique name attribute. After that the postReply function should look like this:
function <%= namespace %>postReply(i) { eval("var parentMessageId = document.<%= formName %>.<%= namespace %>parentMessageId" + i + ".value;"); eval("var body = document.<%= formName %>.<%= namespace %>postReplyBody" + i + ".value;"); eval("var captcha = document.<%= formName %>.<%= namespace %>captchaText" + i + ";"); document.<%= formName %>.<%= namespace %><%= Constants.CMD %>.value = "<%= Constants.ADD %>"; document.<%= formName %>.<%= namespace %>parentMessageId.value = parentMessageId; document.<%= formName %>.<%= namespace %>body.value = body; document.<%= formName %>.<%= namespace %>captchaText.value = captcha==null?"":captcha.value; submitForm(document.<%= formName %>); }
Hope that helps.
*update2*
I hate Microsoft browsers. Especially if their version number is lower than 7. Nobody should ever be forced to develop for them and if you are: tell your cleints you want extra money for it.
I edited the original post and the first update. Sorry for that but it was easier than describing what exactly I changed. Additionally, beneath the postReply function add this:
function <%= namespace %>initCaptcha(src) { if(!window.captchaImgSrc || src) { if(src) window.captchaImgSrc=src; else setTimeout("<%= namespace %>initCaptcha()", 250); return; } jQuery("form[name=<%= formName %>] .captcha").attr("src", window.captchaImgSrc); jQuery("form[name=<%= formName %>] .taglib-captcha input[name=<%= namespace %>captchaText]") .each(function(i) { jQuery(this) .attr("name",this.name+i).keypress(function(e) {if(e.which==13) {<%= namespace %>postReply(i);}}); if(Liferay.Browser.isIe() && Liferay.Browser.getMajorVersion()<7) jQuery(this).replaceWith(jQuery('<input name="'+this.name+'"/>').replaceWith(jQuery(this).clone())); }); }
If you want to know why I used the IE<7 statement, head over here. And directly before the very last </c:if> statement (last line in file) add this:
<script type="text/javascript"> <%= namespace %>initCaptcha(); </script>
You'll wonder why I didn't just use jQuery(document).ready(). The answer is that IE6 doesn't like it. Don't ask why - I don't know the reason. The only thing I know is that I wasted hours on this one.
I tested it on IE6/8, Firefox, Opera and Safari. For me it worked but I would be really happy if you would drop me a line if there are still problems. Sorry again for all the hassle.
*update3*
I just got one of those "text verification failed" errors. It was just one time and I can't reproduce it. If someone has time to investigate on this further then I'd be really thankful if you could give me a hint as to where my mistake lies (perhaps the numbering of the captcha textfields?). And it wouldn't bother me if you'd have to spam on my site to find something suspicious ;)
On another note I saw some warnings within the Liferay log saying that "The struts path message_boards does not belong to portlet 33. Check the definition in liferay-portlet.xml".
Add this to your ext-web/docroot/WEB-INF/struts-config.xml to fix it:
<action path="/blogs/captcha" type="com.liferay.portal.captcha.CaptchaPortletAction" />
And don't forget to change the Struts action parameter for the captchaURL variable.
simbaba.net goes Java
Nur eine kurze Wortmeldung meinerseits... ich habe die Test- und Betaphase in der Softwareentwicklung übersprungen und heute die neue Seite online genommen.
Ich setze jetzt voll auf Java als Backend, das heißt Tomcat mit entsprechendem Portlet-Container... ich werde darauf aber später nochmal genauer eingehen. Ich brauche euch wohl nicht erzählen, wie weh es tut, wenn man Quellcode aufgeben muss, an dem man Monate, wenn nicht Jahre, geschrieben hat; aber es war einfach Zeit für einen Bruch. PHP ist in meinen Augen gut für kleine Projekte, aber sobald man damit ein CMS angehen will, kommt am Ende Spaghetti-Code raus. Habe mir z.B. Drupal näher angeguckt und musste eben diese Erfahrung wieder machen.
Die Oberfläche ist quasi gleich geblieben, gewohnt hässlich eben. Hätte ich auch nur ein bisschen mehr grafisches Talent würde das wohl anders aussehen. Falls sich natürlich jemand befähigt fühlt... ;-)
Falls es Probleme mit Mails geben sollte, bitte melden! Der Mail-Server ist jetzt sehr viel komplizierter und ich bin noch nicht sicher, ob die Konfiguration 100%-ig passt. Habe mich von XMail verabschiedet - auch wenn er mir treue dienste geleistet hat - und hab' den Dovecot-Postfix-Weg eingeschlagen.
Und weil jetzt alles so doll ist, hoffe ich, dass ich mich öfter dazu durchringen kann zu bloggen :-)
Also bis bald und au revoir,
Simba
*update*
Unter dem Motto "Let's go Java" habe ich auch den Jabber-Server wiederbelebt. Openfire heißt er, ist vollständig in Java geschrieben und wirklich ein sehr schönes Stück Software.
Also einfach euren Lieblings-Messenger (Pidgin, Trillian, Miranda, ...) auf den Server simbaba.net einstellen und mit euren normalen Anmeldedaten einloggen. :)
Alles Gute nachträglich...
...oder so ähnlich muss es wohl heißen, denn 2 Jahre ist es nun her, dass ich hier die erste News gepostet hab.
Aber da wir in einer stressigen Zeit leben, bleibt nicht mal groß Zeit zum Gratulieren - und das, obwohl ich in letzter Zeit so schon wenig an der Seite gemacht habe.
Nachdems am Wochenende ein konspiratives Treffen gab und die Seite schon lang keine Neuerungen mehr erfahren hat - gibt's hoffentlich bald ein Revival mit neuen Features, Bugfixes und anderem Gedöhns. Ein cron-Job kümmert sich jetzt auch ums Logging, sodass ich Probleme wohl jetzt besser analysieren kann, falls ich mal wieder offline bin (sorry nochmal, hoffe, das läuft jetzt wieder...).
Hab' PHP installiert und Netbeans eingerichtet und die ersten neuen Zeilen Code geschrieben.
Da ich jetzt so JSP-Verwöhnt bin, fühlt sich PHP wieder wie ein Rückschritt an, aber meinem Router kann ich schließlich keine JVM zumuten ;)
Normalerweise gehört zu so einem Geburtstagsposting ja auch ein sentimentaler Rückblick auf damalige Verhältnisse, aber das erspar' ich euch und mir und verabschiede mich lieber in gewohnt lieblicher Stimmlage: Schlafet alle fein, man sieht sich :)