<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://gwiki3.thatlinuxbox.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vinny</id>
		<title>GeeklogWiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://gwiki3.thatlinuxbox.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vinny"/>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/Special:Contributions/Vinny"/>
		<updated>2026-04-04T18:41:12Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.27.5</generator>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6148</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6148"/>
				<updated>2012-03-09T21:42:22Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Updated mentor link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6142</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6142"/>
				<updated>2012-03-09T17:01:53Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added mentors and co-mentors list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=User:Vinny&amp;diff=6141</id>
		<title>User:Vinny</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=User:Vinny&amp;diff=6141"/>
				<updated>2012-03-09T14:41:55Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Email update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Email: [mailto:vfuriaATgmailDOTcom vfuria AT gmail DOT com]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6135</id>
		<title>SoC template engine</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6135"/>
				<updated>2012-03-08T22:21:11Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added cordiste as co-mentor, added &amp;quot;bonus&amp;quot; to objective&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(Return to the main idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog currently uses an antique template system that does not compile templates, nor does it support modern template library features such as loops or compilation. The student selecting this project should research modern template libraries, choosing one to integrate into Geeklog. &lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
The biggest concern replacing Geeklog's existing template engine is backwards compatibility. Existing templates should still be usable (or a conversion system created) and code modification to support the new template library should be kept to a minimum so plugins can be easily updated to use the new template library.&lt;br /&gt;
&lt;br /&gt;
Geeklog currently uses a large number of (relatively) small template files. A big bonus would be a design that can reduce the number of template files to ease template development without sacrificing backwards compatibility.&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''high''&lt;br /&gt;
&lt;br /&gt;
'''Mentor:''' Vinny Furia&lt;br /&gt;
&lt;br /&gt;
'''Co-Mentor:''' Ben aka &amp;quot;Cordiste&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
Some existing template libraries:&lt;br /&gt;
* [http://pear.php.net/package/HTML_Template_IT/redirected HTML Template IT]&lt;br /&gt;
* [http://pear.php.net/package/HTML_Template_Flexy/redirected HTML Template Flexy]&lt;br /&gt;
* [http://twig.sensiolabs.org/ Twig]&lt;br /&gt;
* [http://www.smarty.net/ Smarty]&lt;br /&gt;
&lt;br /&gt;
Some relevant feature requests:&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=1423 Allow a Topic to have it's own Theme]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=1424 Allow a Theme to have a Base Theme]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6131</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6131"/>
				<updated>2012-03-08T15:41:05Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Inserted missing spaces&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6122</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6122"/>
				<updated>2012-03-02T03:15:45Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Fixed beginner link formatting (escape [ and ])&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6121</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6121"/>
				<updated>2012-03-02T03:00:59Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Updated &amp;quot;beginner&amp;quot; link to exclude closed and resolved issues.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6120</id>
		<title>SoC template engine</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6120"/>
				<updated>2012-03-02T02:42:23Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added further reading (links to relevant feature requests)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(Return to the main idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog currently uses an antique template system that does not compile templates, nor does it support modern template library features such as loops or compilation. The student selecting this project should research modern template libraries, choosing one to integrate into Geeklog. &lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
The biggest concern replacing Geeklog's existing template engine is backwards compatibility. Existing templates should still be usable (or a conversion system created) and code modification to support the new template library should be kept to a minimum so plugins can be easily updated to use the new template library.&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''high''&lt;br /&gt;
&lt;br /&gt;
'''Mentor:''' Vinny Furia&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
Some existing template libraries:&lt;br /&gt;
* [http://pear.php.net/package/HTML_Template_IT/redirected HTML Template IT]&lt;br /&gt;
* [http://pear.php.net/package/HTML_Template_Flexy/redirected HTML Template Flexy]&lt;br /&gt;
* [http://twig.sensiolabs.org/ Twig]&lt;br /&gt;
* [http://www.smarty.net/ Smarty]&lt;br /&gt;
&lt;br /&gt;
Some relevant feature requests:&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=1423 Allow a Topic to have it's own Theme]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=1424 Allow a Theme to have a Base Theme]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6113</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6113"/>
				<updated>2012-02-27T01:37:21Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Removed openid/oauth project&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6112</id>
		<title>SoC template engine</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6112"/>
				<updated>2012-02-27T01:27:56Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Broad description in place. Details to come?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(Return to the main idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog currently uses an antique template system that does not compile templates, nor does it support modern template library features such as loops or compilation. The student selecting this project should research modern template libraries, choosing one to integrate into Geeklog. &lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
The biggest concern replacing Geeklog's existing template engine is backwards compatibility. Existing templates should still be usable (or a conversion system created) and code modification to support the new template library should be kept to a minimum so plugins can be easily updated to use the new template library.&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''high''&lt;br /&gt;
&lt;br /&gt;
'''Mentor:''' Vinny Furia&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
Some existing template libraries:&lt;br /&gt;
* [http://pear.php.net/package/HTML_Template_IT/redirected HTML Template IT]&lt;br /&gt;
* [http://pear.php.net/package/HTML_Template_Flexy/redirected HTML Template Flexy]&lt;br /&gt;
* [http://twig.sensiolabs.org/ Twig]&lt;br /&gt;
* [http://www.smarty.net/ Smarty]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_php_sessions&amp;diff=6111</id>
		<title>SoC php sessions</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_php_sessions&amp;diff=6111"/>
				<updated>2012-02-27T00:49:24Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Broad description in place. Details to come?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(Return to the main idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog currently uses custom session management to maintain users session information. The custom session implementation is antique and needs to be upgraded to a fully supported session management system such as the one provided by [http://www.php.net/manual/en/book.session.php PHP Sessions]. The implementation needs to be secure and should cache user data between page loads of a session.&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
Implement new session handling in Geeklog.&lt;br /&gt;
&lt;br /&gt;
This project could be extended by adding the ability for Geeklog to support http and https for the same site. By forcing logged-in users to use https, session hijacking can be prevented.&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium to high''&lt;br /&gt;
&lt;br /&gt;
Geeklog's existing session software must be understood before being replaced. Student's taking on this project will also have to ensure plugin compatibility with the new session implementation.&lt;br /&gt;
&lt;br /&gt;
'''Mentor:''' Vinny Furia&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
* [http://www.php.net/manual/en/book.session.php PHP Sessions]&lt;br /&gt;
* [http://phpsec.org/projects/guide/4.html PHP Security Guide: Sessions]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_php_sessions&amp;diff=6110</id>
		<title>SoC php sessions</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_php_sessions&amp;diff=6110"/>
				<updated>2012-02-27T00:38:09Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Template Only&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(Return to the main idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium to high''&lt;br /&gt;
&lt;br /&gt;
'''Mentor:''' Vinny Furia&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6109</id>
		<title>SoC template engine</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_template_engine&amp;diff=6109"/>
				<updated>2012-02-27T00:37:43Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Template Only&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(Return to the main idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium to high''&lt;br /&gt;
&lt;br /&gt;
'''Mentor:''' Vinny Furia&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_core_notification_support&amp;diff=6108</id>
		<title>SoC core notification support</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_core_notification_support&amp;diff=6108"/>
				<updated>2012-02-27T00:35:49Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Update for 2012 GSOC&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(Return to the main idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
There are a number of core GL features and plugins that send out email notifications and each plugin or module has to develop their own code. There is no central area for the site admin or members to moderate for what they can receive notifications or how they want them handled.&lt;br /&gt;
&lt;br /&gt;
There is also the need to expand the ability of sites to provide alerts for events in which administrators may have an interest.&lt;br /&gt;
&lt;br /&gt;
Many plugins would require a basic level of notification service. Others, such as the forum plugin, will require a more complex notification service. For instance, a notification service for the forum would need to allow a user to subscribe to a topic or a complete forum. If they have subscribed to a complete forum, they can selectively un-subscribe to some topics. The same level of control may be needed for stories (articles), where a user can subscribe to a complete site but then un-subscribe to certain topics or stories by a certain user.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Objective ==&lt;br /&gt;
&lt;br /&gt;
* Develop a set of core Geeklog API's to support the registration of new notification services and user notification of subscriptions. Ideally, an [https://en.wikipedia.org/wiki/Observer_pattern observer pattern] would be used for clarity and efficiency.&lt;br /&gt;
* Extend the plugin API to use the new services.&lt;br /&gt;
* Extend the core GL modules (polls, articles, links, etc) to use the new services.&lt;br /&gt;
* Develop the notification admin / site admin GUI.&lt;br /&gt;
* Develop the GUI for the users to manage their notification/subscription rules.&lt;br /&gt;
&lt;br /&gt;
Support for:&lt;br /&gt;
* Alert Classification (admin, general, moderation, error ...)&lt;br /&gt;
* Alert Type (core, plugin ...)&lt;br /&gt;
* Alert Subtype (module specific)&lt;br /&gt;
&lt;br /&gt;
Only Root or plugin Admin's have access to the admin and error type notifications but this should be a configurable mapping option and controllable via the online notification service admin.&lt;br /&gt;
&lt;br /&gt;
Users should be able to determine how they want to receive their notifications.&lt;br /&gt;
* Admin wants to be emailed on all admin and error notifications&lt;br /&gt;
* Admin wants to receive daily digest of all other notifications&lt;br /&gt;
* User wants daily digest of all notifications&lt;br /&gt;
* Support for RSS Feed per user - possibly using a random hash like URL&lt;br /&gt;
* Daily digest format needs to use a template so the site admin can modify it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Use Cases ==&lt;br /&gt;
&lt;br /&gt;
* Site Admin wants to be notified of all new forum topics and MG albums created but not new replies and images uploaded&lt;br /&gt;
* User wants daily digest of all MG updates for albums they have access to&lt;br /&gt;
* User wants daily digest of all comments to content they have created or have replied to.&lt;br /&gt;
* Admin wants daily digest of all items awaiting moderation&lt;br /&gt;
* Admin wants to be notified via email of all site logins&lt;br /&gt;
* Admin wants to be notified via email of all bad login attempts so they know if a user is now locked out&lt;br /&gt;
* Admin wants to be notified of new user signups.&lt;br /&gt;
&lt;br /&gt;
The site Admin and user can have multiple notification rules setup and setup the email subject, email address so they can filter or redirect notifications.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
&lt;br /&gt;
''medium to high''&lt;br /&gt;
&lt;br /&gt;
This project will require someone to spend time understanding how the core GL plugin API works. Need to install a number of the more popular plugins that use notification-like features and develop a model of the new notification service API.&lt;br /&gt;
&lt;br /&gt;
Students should have OO experience and knowledge of say the Observer Design Pattern as that would be a good base for the design of this project.&lt;br /&gt;
&lt;br /&gt;
'''Mentor:''' Vinny Furia&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
&lt;br /&gt;
* We had a student interested in this project in 2008. Please see the discussion &amp;quot;GSoC 2008: Core Notification Service&amp;quot; in our [http://eight.pairlist.net/pipermail/geeklog-devel/2008-March/thread.html mailing list archives].&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6107</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=6107"/>
				<updated>2012-02-27T00:24:38Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added two project ideas.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Geeklog.net_Redesign&amp;diff=6099</id>
		<title>Geeklog.net Redesign</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Geeklog.net_Redesign&amp;diff=6099"/>
				<updated>2012-02-18T02:17:12Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Homepage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Geeklog.net_Redesign&amp;diff=6098</id>
		<title>Geeklog.net Redesign</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Geeklog.net_Redesign&amp;diff=6098"/>
				<updated>2012-02-18T02:16:17Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=AddToConfiguration&amp;diff=6075</id>
		<title>AddToConfiguration</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=AddToConfiguration&amp;diff=6075"/>
				<updated>2011-08-11T20:35:34Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: New Article&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Guide to Adding 'Core' Configuration Items=&lt;br /&gt;
&lt;br /&gt;
Geeklog's move from a static configuration array to a database-based, web-managed configuration system using the [[Configuration_Class|Configuration Class]] in Geeklog 1.7.x has made adding new configuration parameters more complex. This guide includes step-by-step instructions for adding new configuration subgroups, tabs, fieldsets, and configuration parameters. Configuration groups are ignored, as for configuration parameters for Geeklog should always be in the 'Core' group. Other documentation exists about adding [[PluginConfiguration|configuration items for plugins]].&lt;br /&gt;
&lt;br /&gt;
This article will often refer to collective sort of organizing types, which includes groups, subgroups, tabs, and fieldsets, as grouping types.&lt;br /&gt;
&lt;br /&gt;
==Adding subgroups, tabs, and fieldsets==&lt;br /&gt;
===Creating new subgroups, tabs, and fieldsets===&lt;br /&gt;
There are two locations where new grouping types (and configuration parameters as well, but more on them later) must be added. The first is &amp;lt;tt&amp;gt;public_html/admin/install/config-install.php&amp;lt;/tt&amp;gt;, used by new Geeklog installs to add a complete set of configuration parameters to the Geeklog database. The second is &amp;lt;tt&amp;gt;public_html/admin/install/lib-upgrade.php&amp;lt;/tt&amp;gt;, where the Geeklog upgrade script goes to upgrade the database when a new Geeklog version is installed.&lt;br /&gt;
&lt;br /&gt;
In both locations and for all these grouping types, the [[Configuration_Class#function_add.28.29|add method of the configuration class]] is used to add new grouping types. Below are some examples of adding these different grouping types:&lt;br /&gt;
* subgroup: &amp;lt;tt&amp;gt;$c-&amp;gt;add('sg_site', NULL, 'subgroup', 0, 0, NULL, 0, TRUE, 'Core', 0);&amp;lt;/tt&amp;gt;&lt;br /&gt;
* tab: &amp;lt;tt&amp;gt;$c-&amp;gt;add('tab_site', NULL, 'tab', 0, 0, NULL, 0, TRUE, 'Core', 0);&amp;lt;/tt&amp;gt;&lt;br /&gt;
* fieldset: &amp;lt;tt&amp;gt;$c-&amp;gt;add('fs_site', NULL, 'fieldset', 0, 0, NULL, 0, TRUE, 'Core', 0);&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is complete documentation for the [[Configuration_Class#function_add.28.29|add method]]. The following parameters are particularly important for the grouping types:&lt;br /&gt;
* First Parameter: The internal name (i.e. not the display name). &lt;br /&gt;
* Third Parameter: The type. For grouping types, these are 'subgroup', 'tab', and 'fieldset'.&lt;br /&gt;
* Fourth Parameter: The subgroup number. This is a unique internal number to reference the subgroup. The fieldset and tab types use this to indicate which subgroup they belong under.&lt;br /&gt;
* Fifth Parameter: The fieldset number. This is the unique internal number to reference the fieldset. Subgroups do not use this number and use 0 by convention. Tabs do not use this number and use the number of the first fieldset they contain by convention.&lt;br /&gt;
* Tenth Parameter: The tab number. This is the unique internal number to reference the tab. Subgroups do not use this number and use 0 by convention. Fieldsets use this to indicate which tab they belong under.&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;lib-upgrade.php&amp;lt;/tt&amp;gt;, the code for the addition of the variables should be placed in the switch statement case for the previous version (e.g. if adding config value to 1.8.1, add the methods to the case statement for 1.8.0). Also in &amp;lt;tt&amp;gt;lib-upgrade.php&amp;lt;/tt&amp;gt;, you will need to initialize the config class before you can execute the add methods above. This is easily done by using the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
global $_CONF;&lt;br /&gt;
require_once $_CONF['path_system'] . 'classes/config.class.php';&lt;br /&gt;
$c = config::get_instance();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Display text for subgroups, tabs, and fieldsets===&lt;br /&gt;
Once the new grouping type(s) are added, the language file (by editing &amp;lt;tt&amp;gt;language/english.php&amp;lt;/tt&amp;gt; must be updated. Each grouping type has its own language associative array in this file. In these arrays, the key is the grouping types' name (such as 'sg_site' used above) and the value is the plain text display ('Site', for the same case).&lt;br /&gt;
* subgroup: &amp;lt;tt&amp;gt;$LANG_configsubgroups['Core']&amp;lt;/tt&amp;gt;&lt;br /&gt;
* tab: &amp;lt;tt&amp;gt;$LANG_tab['Core']&amp;lt;/tt&amp;gt;&lt;br /&gt;
* fieldset: &amp;lt;tt&amp;gt;$LANG_fs['Core']&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding configuration parameters==&lt;br /&gt;
===Creating new parameters===&lt;br /&gt;
Like the grouping types, configuration parameters use the [[Configuration_Class#function_add.28.29|add method]] of the [[Configuration_Class|configuration class]] to add new parameters. These add methods are placed in both &amp;lt;tt&amp;gt;public_html/admin/install/config-install.php&amp;lt;/tt&amp;gt; to be used in new installs and &amp;lt;tt&amp;gt;public_html/admin/install/lib-upgrade.php&amp;lt;/tt&amp;gt; to be used in upgrades. Here is an example of adding a new configuration variable:&lt;br /&gt;
* $c-&amp;gt;add('site_url', &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;, 'text', 0, 0, NULL, 20, TRUE, 'Core', 0);&lt;br /&gt;
&lt;br /&gt;
The configuration class supports three basic types of configuration parameters, these are:&lt;br /&gt;
* text: Manual text box entry.&lt;br /&gt;
* select: HTML Select box (i.e. choice dropdown).&lt;br /&gt;
* hidden: Undisplayed config parameters.&lt;br /&gt;
&lt;br /&gt;
The configuration class also allows the use of arrays by prepending the base type above with one of the following characters:&lt;br /&gt;
* @: array, the administrator cannot add keys&lt;br /&gt;
* *: array, the administrator can add named keys&lt;br /&gt;
* %: array, the administrator can add numbered keys&lt;br /&gt;
&lt;br /&gt;
The configuration class supports multidimensional arrays by prepending additional array symbols. For instance, @@example represents a two dimensional array.&lt;br /&gt;
&lt;br /&gt;
Default/initial values are defined in the second parameter to the add method. These can be of any type (including arrays) and get serialized by Geeklog for storage in the database.&lt;br /&gt;
&lt;br /&gt;
===Value validation===&lt;br /&gt;
Entered values for parameters are validated by a rules that are defined on a per-parameter basis. This rules are established in the &amp;lt;tt&amp;gt;$_CONF_VALIDATE&amp;lt;/tt&amp;gt; array defined in &amp;lt;tt&amp;gt;public_html/admin/configuration_validation.php&amp;lt;/tt&amp;gt;. Each parameter (for the 'Core' group) is a key in the &amp;lt;tt&amp;gt;$_CONF_VALIDATE['Core']&amp;lt;/tt&amp;gt; array. For instance, to add a validation function function to the 'site_url' parameter, the following entry is needed:&lt;br /&gt;
* &amp;lt;tt&amp;gt;$_CONF_VALIDATE['Core']['site_url'] = array('rule' =&amp;gt; 'url');&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every parameter should have an entry in this array. The 'rule' key is interpreted as follows: &lt;br /&gt;
# If a custom_validation_&amp;lt;rule&amp;gt; function exists, use that (e.g. &amp;quot;theme&amp;quot; -&amp;gt; custom_validation_theme() from &amp;lt;tt&amp;gt;public_html/admin/configuration.php&amp;lt;/tt&amp;gt;).&lt;br /&gt;
# If a method from the validator class with the same name as the rule exists, use that (e.g. &amp;quot;stringOrEmpty&amp;quot; -&amp;gt; stringOrEmpty() from &amp;lt;tt&amp;gt;system/classes/validator.class.php&amp;lt;/tt&amp;gt;). Currently the validator class supports the following rules: notEmpty, alphaNumeric, between, blank, comparison (isgreater, isless, greaterorequal, lessorequal, equalto, notequal), custom (regex), date, time, boolean, decimal, email, equalTo, extension, ip, minlength, maxlength, multiple, numeric, phone, range, string, stringOrEmpty, url, and inList.&lt;br /&gt;
# Otherwise assume the &amp;quot;rule&amp;quot; is a regexp&lt;br /&gt;
&lt;br /&gt;
===Parameter documentation===&lt;br /&gt;
To reference additional information about variables from the congiruation web page, new parameters should be placed in &amp;lt;tt&amp;gt;public_html/docs/english/config.html&amp;lt;/tt&amp;gt; (including their internal name, type, and description) with an anchor tag with the name 'desc_&amp;lt;parameter name&amp;gt;'.&lt;br /&gt;
&lt;br /&gt;
===Display text for parameters and selects===&lt;br /&gt;
Finally, display text for each parameter name should be placed in the &amp;lt;tt&amp;gt;language/english.php&amp;lt;/tt&amp;gt; file in the &amp;lt;tt&amp;gt;$LANG_confignames['Core']&amp;lt;/tt&amp;gt; associative array with the key being the internal name and the value the display text. Also, parameters with the 'select' type, need to update the &amp;lt;tt&amp;gt;$LANG_configselects['Core']&amp;lt;/tt&amp;gt; array. 'Select' types can use an existing numbered reference to an associative array of select values, or else create a new one. A new select needs a unique number index in &amp;lt;tt&amp;gt;$LANG_configselects['Core']&amp;lt;/tt&amp;gt; with an associative array of containing the displayed text as keys and the select values as values in the array.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
While these instructions can seem intimidating, by using other parameters and grouping types as reference adding to Geeklog's configuration is manageable. While the complexity of adding configuration has increased for developers, it is a necessary sacrifice for granting both a easy to manage web frontend and providing validation protection to entered configuration values.&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Programmers/Developers_Documentation&amp;diff=6074</id>
		<title>Programmers/Developers Documentation</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Programmers/Developers_Documentation&amp;diff=6074"/>
				<updated>2011-08-11T17:49:57Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added link to &amp;quot;AddToConfiguration&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Beginner%27s_Guide_to_Programming&amp;diff=6073</id>
		<title>Beginner's Guide to Programming</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Beginner%27s_Guide_to_Programming&amp;diff=6073"/>
				<updated>2011-08-11T17:36:50Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Squatty is completely gone, portalparts is &amp;quot;retired&amp;quot; with no active posts since mid-2010.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;By [[User:Amckay|Alan McKay]]&lt;br /&gt;
&lt;br /&gt;
[http://www.geeklog.net Geeklog] is a powerful weblog (blog) content management system (CMS) which is written in the popular programming language [http://www.php.net PHP], and uses the popular [http://www.mysql.com MySQL] database.  While Geeklog is powerful enough that many users will not have a need to write their own applications for it, it is flexible enough to allow those who do require extra functionality to do so easily.  These people write their programs in PHP, with some minor restrictions and using the Geeklog function library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Hello, World==&lt;br /&gt;
&lt;br /&gt;
The first program you write in any computer language is &amp;quot;Hello World&amp;quot;, and here it is in Geeklog.  This is saved in a file &amp;quot;hello.php&amp;quot; in Geeklog's &amp;quot;public_html&amp;quot; directory, and so is surfable at http://www.example.com/hello.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once( 'lib-common.php' );&lt;br /&gt;
$display =  COM_siteHeader();&lt;br /&gt;
$display .= &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
$display .= COM_siteFooter();&lt;br /&gt;
COM_output($display);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few important things to be noted from the given program.&lt;br /&gt;
&lt;br /&gt;
* geeklog programs stay in PHP mode - there is no flipping back and forth between PHP and HTML as is possible in the PHP language.  This means that all programs have &amp;quot;&amp;lt;?php&amp;quot; on the first line, and &amp;quot;?&amp;gt;&amp;quot; on the last line, and everything in between is PHP code.&lt;br /&gt;
* the HTML is generated using a single function, COM_output() as on the last line of the above code. Although it is possible to use a simple 'echo' statement to spit out the HTML, newer versions of Geeklog use the COM_output() function. COM_output() takes the $display variable to which all your HTML output is appended throughout the code (note the &amp;quot;.=&amp;quot; which is used for the append) as an argument and simply echoes it out in this case. (Newer versions of Geeklog use the COM_output() function to allow for any output that may use compression. More on that later)&lt;br /&gt;
* &amp;quot;lib-common.php&amp;quot; is the single file which must be included in all your Geeklog programs.  It includes everything else you need unless you decide to make your own include files, so it's one-stop shopping.&lt;br /&gt;
* there are functions in Geeklog to do lots of stuff for you - like for example COM_siteHeader() and COM_siteFooter().  In general Geeklog functions start with 2 or 3 capital letters and an understore - this tells you what type of function it is.  Then the name of the function. COM_ functions are &amp;quot;common&amp;quot; functions - not a terribly meaningful name.  But SEC_ functions like SEC_inGroup() which allows you to test if a user is in a particular group, allow your programs to access some of the powerful security features of Geeklog.  And DB_ commands allow you to access the Geeklog database.&lt;br /&gt;
&lt;br /&gt;
==Security==&lt;br /&gt;
Speaking of the powerful Geeklog security model (one of the key reasons I originally chose Geeklog for my sites), let's alter the hello world program such that any user in the &amp;quot;geeker&amp;quot; user group will see the &amp;quot;hello world&amp;quot; message, but anyone not in that group (which includes users not logged in) will get a &amp;quot;permission denied&amp;quot; error.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once( 'lib-common.php' );&lt;br /&gt;
&lt;br /&gt;
$display =  COM_siteHeader();&lt;br /&gt;
&lt;br /&gt;
if ( SEC_inGroup( 'geeker' ) )&lt;br /&gt;
          $display .= &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
          $display .= &amp;quot;Access Denied&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$display .= COM_siteFooter();&lt;br /&gt;
&lt;br /&gt;
COM_output($display);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To check out the full range of security functions available to you, and how to use them, read the /path/to/geeklog/system/lib-security.php file, which is where they are implemented.  &lt;br /&gt;
&lt;br /&gt;
Though the above code format is a bit clunky and not terribly useful, so let's make another change which shows us how most programs deal with group permissions issues.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once( 'lib-common.php' );&lt;br /&gt;
&lt;br /&gt;
$display =  COM_siteHeader();&lt;br /&gt;
&lt;br /&gt;
if ( ! SEC_inGroup( 'geeker' ) )&lt;br /&gt;
{&lt;br /&gt;
          $display .= &amp;quot;Access Denied&amp;quot;;&lt;br /&gt;
          $display .= COM_siteFooter();&lt;br /&gt;
          COM_output($display);&lt;br /&gt;
          exit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$display .= &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// do some other stuff here&lt;br /&gt;
&lt;br /&gt;
$display .= COM_siteFooter();&lt;br /&gt;
&lt;br /&gt;
COM_output($display);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The big difference in this version of the program is that right at the top of the program we test for group permissions, and if the user does not have them we display the site footer, then exit.  So a user not in the 'geeker' group will end right there and never see what the rest of the program does.  Very simple, but very powerful!  This is precisely how you control access to your pages in Geeklog!&lt;br /&gt;
&lt;br /&gt;
==Where to put it==&lt;br /&gt;
&lt;br /&gt;
If you are only writing a small program, then sticking a single file in the public_html directory as shown above will work fine.  As soon as you get to the point, however, when you start having your own include files and so on, you probably want to create a directory for it.  In our case we could create a directory in &amp;quot;public_html&amp;quot; called &amp;quot;hello&amp;quot;, and then create a file &amp;quot;index.php&amp;quot; with the above program.  This will require a very minor change to the original program - see if you can pick it out before peeking :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once( '../lib-common.php' );&lt;br /&gt;
&lt;br /&gt;
$display =  COM_siteHeader();&lt;br /&gt;
&lt;br /&gt;
$display .= &amp;quot;Hello World&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$display .= COM_siteFooter();&lt;br /&gt;
&lt;br /&gt;
COM_output($display);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yup, that's right, we had to add &amp;quot;../&amp;quot; to the &amp;quot;lib-common.php&amp;quot; in the &amp;quot;require_once&amp;quot; (which BTW is a type of &amp;quot;include&amp;quot; in PHP).  The reason is simple: lib-common.php lives in public_html, and our first program was in that directory as well.  This new program is in a subdirectory of public_html, so we have to go to the parent directory to get our include file.&lt;br /&gt;
&lt;br /&gt;
If you want to keep your geeklog installation &amp;quot;pure&amp;quot;, as I usually do, you can also put your program directory somewhere outside of the geeklog directory, and use directives for your webserver to map that directory into the web space of your geeklog installation.  That's easier than it sounds  - with Apache just use the &amp;quot;Alias&amp;quot; directive in your apache config file, like this :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Alias /hello/ &amp;quot;/path/to/your/hello/&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, this means that your require_once statement will have to contain the full path to lib-common.php &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require_once( '/path/to/geeklog/public_html/lib-common.php' );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==To Plug it in, or not==&lt;br /&gt;
&lt;br /&gt;
This is a bit of an advanced topic which in some ways is out of place at this point, but just about everyone who knows Geeklog and has used it a bit, knows about [[Plugin Developers Handbook|Geeklog plugins]].  And when writing your own Geeklog programs, this will obviously be something in your mind.  Not all Geeklog programs are plugins - and the above examples are not.  Plugins involve writing your program in a specific way, and defining specific functions which Geeklog will expect to find.  It also involves making some entries in the Geeklog database to let Geeklog know that your plugin is there.&lt;br /&gt;
&lt;br /&gt;
In general if you want to use the Geeklog comment engine, the Geeklog search engine (i.e. integrate your program data into the search feature of Geeklog), or the Geeklog submission engine, you must write a plugin.  Otherwise you can just write code.  Size doesn't matter.  There is no limit after which you have to make it a plugin.&lt;br /&gt;
&lt;br /&gt;
==Some Odds and Ends==&lt;br /&gt;
&lt;br /&gt;
A couple of more quick points on some basic Geeklog stuff&lt;br /&gt;
&lt;br /&gt;
* the $_USER array comes pre-populated for you by Geeklog.  If $_USER['uid'] is greater than 1, then you know your user is logged on.   Otherwise they are anonymous.  So in the above example if you wanted to test for &amp;quot;logged on user&amp;quot; rather than &amp;quot;member of geeker group&amp;quot;, just change the 'if' statement accordingly.  This array contains all of the user table from geeklog, the next most useful subscript being $_USER['username']&lt;br /&gt;
* the $_CONF array contains everything you set in your config.php, if you need it.  Just check config.php for what all is there.&lt;br /&gt;
* both of the above arrays are global, and as such if you use them in a function you must declare them in the function with the 'global' directive, as is normal for PHP.  Outside of any function in the main body of the program they can be just used.&lt;br /&gt;
&lt;br /&gt;
==Functions, Bring Me Functions!==&lt;br /&gt;
&lt;br /&gt;
We've already seen three of the most widely used functions that Geeklog has to offer - COM_siteHeader(), COM_siteFooter() and COM_output().  It is important to note with this that there are optional parameters you can pass to each of them to achieve certain results.  COM_siteHeader() displays the header and the left blocks, while its partner controls the footer and the right blocks.  By default COM_siteHeader() displays the left blocks, and by default COM_siteFooter() does not display the right blocks. COM_output takes your $display variable which contains all your HTML and displays it, allowing for compressed data to be decompressed and displayed in the process. Check the source code in lib-common.php for details on how to change this behavior.&lt;br /&gt;
&lt;br /&gt;
Another set of similar workhorse functions which are also defined in lib-common.php along with the aforementioned functions are COM_startBlock() and COM_endBlock().  COM_startBlock() accepts 3 optional parameters: title, helpfile and template.  The most useful and almost always used is title, which is a text string which will appear in the title bar of the block.  If a helpfile is specified, Geeklog will display the help question mark icon and link to a help file for that block.  And by default the 'blockheader.thtml' template is used unless another is specified.  COM_endBlock() '''must''' be called once for each call to COM_startBlock(), and its only optional parameter is template, the default being blockfooter.thtml.&lt;br /&gt;
&lt;br /&gt;
Blocks can be nested inside of each other, which is obvious by simply looking at just about any geeklog website.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once( 'lib-common.php' );&lt;br /&gt;
&lt;br /&gt;
$display =  COM_siteHeader();&lt;br /&gt;
&lt;br /&gt;
$display .= COM_startBlock(&amp;quot;Outer Block&amp;quot;)&lt;br /&gt;
             . &amp;quot;This text should be inside the outer block but outside the inner block&amp;quot;&lt;br /&gt;
             . COM_startBlock(&amp;quot;Inner Block&amp;quot;)&lt;br /&gt;
             . &amp;quot;This text should be inside the inner block&amp;quot;&lt;br /&gt;
             . COM_endBlock()&lt;br /&gt;
             . COM_endBlock();&lt;br /&gt;
&lt;br /&gt;
$display .= COM_siteFooter();&lt;br /&gt;
&lt;br /&gt;
COM_output($display);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using nested blocks inside of HTML tables, one simply has to be certain to call COM_endBlock() in the right place since these functions output HTML tables as well, and otherwise the display may not render properly. COM_startBlock() and COM_endBlock() are used like COM_siteHeader() and COM_siteFooter() but for internal page elements.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once( 'lib-common.php' );&lt;br /&gt;
&lt;br /&gt;
$display =  COM_siteHeader();&lt;br /&gt;
&lt;br /&gt;
$display .= COM_startBlock(&amp;quot;Outer Block&amp;quot;)&lt;br /&gt;
             . &amp;quot;This text should be inside the outer block but outside the inner blocks&amp;quot;&lt;br /&gt;
             . &amp;quot;&amp;lt;table align=center width=100% border=0&amp;gt;&amp;quot;&lt;br /&gt;
             . &amp;quot;&amp;lt;tr&amp;gt;&amp;lt;td align=center width=50%&amp;gt;&amp;quot;&lt;br /&gt;
             . COM_startBlock(&amp;quot;Left Inner Block&amp;quot;)&lt;br /&gt;
             . &amp;quot;This text should be inside the left inner block&amp;quot;&lt;br /&gt;
             . COM_endBlock()&lt;br /&gt;
             . &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;br /&gt;
             . &amp;quot;&amp;lt;td align=center width=50%&amp;gt;&amp;quot;&lt;br /&gt;
             . COM_startBlock(&amp;quot;Left Inner Block&amp;quot;)&lt;br /&gt;
             . &amp;quot;This text should be inside the right inner block&amp;quot;&lt;br /&gt;
             . COM_endBlock()&lt;br /&gt;
              . &amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;&lt;br /&gt;
             . &amp;quot;This text should be below the inner blocks but inside the outer block&amp;quot;&lt;br /&gt;
             . COM_endBlock();&lt;br /&gt;
&lt;br /&gt;
$display .= COM_siteFooter();&lt;br /&gt;
&lt;br /&gt;
COM_output($display);&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The great advantage of using these two functions is that whenever the site admin or user changes their Geeklog theme, your GUI will change to match.  Your program will always retain the same look-and-feel of the site in general.&lt;br /&gt;
&lt;br /&gt;
There are also some useful HTML form functions found in lib-common.php which come in very handy and make life a bit easier.  &amp;lt;pre&amp;gt;COM_optionList( $table, $selection, $selected='', $sortcol=1 )&amp;lt;/pre&amp;gt;.  This creates an HTML &amp;quot;&amp;lt;option&amp;quot; list generated from the given database table, using the passed variable &amp;quot;$selected&amp;quot; in the SELECT statement of the HTML query.  See source code for a better idea of what the function does, but it is very useful.&lt;br /&gt;
&lt;br /&gt;
In a similar vein, &amp;lt;pre&amp;gt;COM_checkList( $table, $selection, $where='', $selected='' )&amp;lt;/pre&amp;gt; creates a list of check boxes from the given database table, with the given select and where clauses being passed to the SQL statement inside the function.&lt;br /&gt;
&lt;br /&gt;
One more useful function is the &amp;lt;pre&amp;gt;COM_errorLog( $logentry, $actionid = '')&amp;lt;/pre&amp;gt; function which logs to the Geeklog logfile if $actionid is 1, or to the screen if it is set to 2.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;COM_checkWords( $Message )&amp;lt;/pre&amp;gt; gives you access to Geeklog's (somewhat rudimentary) profanity filter.  We find it to be not terribly useful since if you include for example the word &amp;quot;cock&amp;quot; in your filter, you will also filter out the completely innocuous word &amp;quot;peacock&amp;quot;.  If you nonetheless want to use the geeklog profanity filter, simply do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$text = COM_checkWords( $text );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;COM_mail( $to, $subject, $message, $from = '', $html = false, $priority = 0 )&amp;lt;/pre&amp;gt; does exactly what the name suggests and lets you send mail to someone.&lt;br /&gt;
&lt;br /&gt;
There are far too many functions in lib-common.php to discuss here, so we'll end off with two very important ones which can be used for accessing query-string variables.  What's a query string?  If you have a URL like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://www.example.com/someprogram.php?variable=value&amp;amp;othervariable=othervalue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The query string is the part after the question mark - the stuff you pass into your program.  In this example, inside the text of someprogram.php, if the PHP installation has &amp;quot;register_globals&amp;quot; turned on, the variable &amp;quot;$variable&amp;quot; will automagically exist in the program and will have the value &amp;quot;value&amp;quot;.  But there are certain security problems with using &amp;quot;register_globals&amp;quot; in PHP so a lot of people do not like to have it turned on.  Unfortunately Geeklog requires that it be turned on (at least for now until the programmers get it rewritten to eliminate the need), so to mitigate the risks involved you can use special functions to obtain your query string variables.&lt;br /&gt;
&lt;br /&gt;
Near the top of your program simply insert something like the following, first to define which are the only global variables your program expects to see, then finally to safely obtain the value of those variables:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
COM_setArgNames(array('variable','othervariable'));&lt;br /&gt;
$variable            = COM_getArgument('variable');&lt;br /&gt;
$othervariable       = COM_getArgument('othervariable');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the Database==&lt;br /&gt;
&lt;br /&gt;
Geeklog has a database abstraction layer which in theory makes it possible for you to use any database as the backend for it.  Though in practice the Geeklog team has only implemented a backend for the popular [http://www.mysql.com MySQL] database.  In any case, when programming Geeklog you do not use the regular PHP database functions - instead you use the DB_ functions which behave almost idenically to the PHP functions that have similar names.&lt;br /&gt;
&lt;br /&gt;
Another important thing to note about Geeklog is that you should never use table names directly in your queries.  Instead, you should use the $_TABLES global variable, and add your own table names to it if you make your own tables.  The reason for this is simply that Geeklog allows the installer to specify a &amp;quot;table prefix&amp;quot;, so if you use table names directly your code will not run on another Geeklog installation that uses a different table prefix.  Even if you think you'll never want to run your code on another Geeklog installation, we recommend you do things properly because you never do know.  I've written code that I thought would never have to run in another installation, and sure enough 2 years later I have to go back and convert it all to use the $_TABLES array because now I do indeed want to run it on another installation that is using a different table prefix.&lt;br /&gt;
&lt;br /&gt;
One final very important thing to state about using the Geeklog database is that '''under no circumstances whatsoever should you ever alter the default Geeklog tables'''.  One example of where you might be tempted to do this is if you want to track a specific option for users - you may be tempted to add a field or two to the Geeklog &amp;quot;users&amp;quot; table.  Say for example you are writing a program &amp;quot;buysell&amp;quot; which allows users to enter items into the database to put them up for sale to other users.  And when browsing the database to see what is for sale, you want each user to decide whether or not they want to see their own items.  You may be tempted to add a boolean field &amp;quot;seeown&amp;quot; to the Geeklog users table, but don't do it!  Instead, create your own table &amp;quot;buysell_userprefs&amp;quot; and add whatever fields you require to this new table.  At very least we need a field for the userid - so we'll call it &amp;quot;bsp_uid&amp;quot;, and we need a field for &amp;quot;see your own items&amp;quot; so we'll call it &amp;quot;bsp_seeown&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In general we like to give table fields names that have an abbreviation of the table name at the beginning of every field.  So in our case this is a table which contains &amp;quot;buy sell preferences&amp;quot; for each user, so we'll name all the fields &amp;quot;bsp_&amp;quot;.  This is optional, but we've found it to be a good practice so that you do not end up with fields from various tables with the same name - something that can under circumstances cause problems in your queries, or unexpected results.&lt;br /&gt;
&lt;br /&gt;
===Adding to $_TABLES===&lt;br /&gt;
As already mentioned, if you define your own tables, you have to add them to the global $_TABLES variable.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$_TABLES['buysell_userprefs']  = $_DB_table_prefix . 'buysell_userprefs';&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we've included the Geeklog global variable for table prefix, so that our code will work in all Geeklog installations.  And of course you need one line for every table you are adding to the Geeklog database.  And finally, like any global variable in Geelog you must declare it global in a function if you want to use it in that function.&lt;br /&gt;
&lt;br /&gt;
When doing a plugin you usually put this into the config.php for your plugin.  If not doing a plugin you have several options on where to put it, depending upon how you have your code organised.  If you have one big file, then put it at the top of that file.  If you have an include file that gets included by all the programs you are writing, put it there.  Basically you have to put it whereever you can that will ensure it gets executed by all of your programs and is visible by all of your programs.&lt;br /&gt;
&lt;br /&gt;
===Get on with it!===&lt;br /&gt;
And finally we can show you how to put it all together.  Let's write a simple little program that does nothing more than show you what your 'bsp_seeown' preference is set to.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
require_once('lib-common.php');&lt;br /&gt;
&lt;br /&gt;
$display =  COM_siteHeader(); &lt;br /&gt;
&lt;br /&gt;
if ( $_USER['uid'] &amp;lt; 2 ) {&lt;br /&gt;
           $display .= &amp;quot;You are not logged in&amp;quot;;&lt;br /&gt;
           $display .= COM_siteFooter();&lt;br /&gt;
           COM_output($display);&lt;br /&gt;
           exit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$_TABLES['buysell_userprefs']  = $_DB_table_prefix . 'buysell_userprefs';&lt;br /&gt;
&lt;br /&gt;
$sql = &amp;quot;SELECT bsp_seeown FROM {$_TABLES['buysell_userprefs']} &amp;quot;&lt;br /&gt;
        . &amp;quot; WHERE {$_TABLES['buysell_userprefs']}.bsp_uid = {$_USER['uid']} &amp;quot;;&lt;br /&gt;
$result = DB_query( $sql );&lt;br /&gt;
if ( ! $result ) {&lt;br /&gt;
          // some error condition and possibly exit&lt;br /&gt;
}&lt;br /&gt;
if ( DB_numRows( $result ) &amp;lt;&amp;gt; 1 ) {&lt;br /&gt;
         // there should be precisely one entry for each user&lt;br /&gt;
         // otherwise you may want to flag an error condition&lt;br /&gt;
         // or you may want to alternately check to see if this&lt;br /&gt;
         // value is less than 1 first, in which case they user&lt;br /&gt;
         // has not yet set their preferences&lt;br /&gt;
}&lt;br /&gt;
$bsp = DB_fetchArray( $result );&lt;br /&gt;
if ( ! $bsp ) {&lt;br /&gt;
        // some error condition&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
$display .= COM_startBlock(&amp;quot;Your Preference is&amp;quot;) &lt;br /&gt;
             . $bsp['bsp_seeown']&lt;br /&gt;
             . COM_endBlock(); &lt;br /&gt;
&lt;br /&gt;
$display .= COM_siteFooter(); &lt;br /&gt;
&lt;br /&gt;
COM_output($display); &lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wow!  There's lots going on in this program!  A lot more than what we might have expected!  First and foremost note that there are lots of potential error conditions to check for, when using the Geeklog database.  This is no different from just programming MySQL with the normal PHP functions, actually.  It is always a best practice to check for error conditions and react accordingly.&lt;br /&gt;
&lt;br /&gt;
Before we looked up the user's preference, we of course first did a check to make sure they were logged on, and if not we exited.   Then, you can see how we added our table to the $_TABLES global variable, and then inside of the SELECT statement used the $_TABLES variable to ensure our code is portable.  If you wanted to move this to another system you do not have to change a thing!&lt;br /&gt;
&lt;br /&gt;
As for the specific DB_ functions we used, they behave in the same way as the PHP MySQL functions with similar names.  If you aren't familiar with how they work, check the Geeklog source code as well as the PHP manual.  For a full listing of all the DB_ functions available to you, check out /path/to/geeklog/system/lib-database.php&lt;br /&gt;
&lt;br /&gt;
==Defining Functions==&lt;br /&gt;
Defining functions in Geeklog is of course no different from doing so in PHP.  Though there are a few lessons to be learned from the Geeklog coding style.  One handy thing to do is pick a 3 to 5 character prefix for all of your functions.  This will help prevent you and some other developer from walking on each others toes and writing plugins or other Geeklog programs which are incompatible with each other.  For example in my User Pages Plugin I chose the prefix &amp;quot;UPAGE_&amp;quot; for every one of my own functions.&lt;br /&gt;
&lt;br /&gt;
Figuring out how to do return codes from functions is never easy in Geeklog or PHP in general.  Many functions will return strings of HTML formatted text, and so returning error conditions is not easy.  There is no one solution for every circumstance - though I've found 2 solutions work most of the time.  If you hit an error condition in your function you can either return a NULL string so the caller can check for NULL string, or you can just return a string with an error message about the problem encountered, in which case the caller will not really know something went wrong - which may or may not matter.  It depends on your caller.&lt;br /&gt;
&lt;br /&gt;
Let's have a look at a couple of functions for making HTML select boxes out of the database.  The first function is essentially the same as the Geeklog function COM_optionList although it does get called with different parameters, and the Geeklog function is a bit more powerful. &lt;br /&gt;
&lt;br /&gt;
One thing you will see first off in the below function definition is that PHP gives you a means to specify default values for function parameters.  This means that when calling the function, only the first two parameters &amp;quot;myName&amp;quot; and &amp;quot;myOptions&amp;quot; need be specified.  myName is the name this element will have (variable name) and myOptions is a list of options separated by the &amp;quot;mySep&amp;quot; character which by default is &amp;quot;|&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
An important aspect to understand about default values for parameters is that you can only allow the X right-most parameters to have a default value.  That is to say you cannot specify a default value for the 1st parameter, then none for the 2nd, then one for the 3rd and so on.  The first zero or more parameters will have no default, then after the first one that has a default value all the rest must also have default values.  And also when calling the function that we have below, if I wanted to override the default for &amp;quot;mySep&amp;quot; for example by passing a value in, then I also have to override the defaults for every parameter to the left of it - so I must also specify overrides for &amp;quot;myDefault&amp;quot;, &amp;quot;myMulti&amp;quot; and &amp;quot;mySize&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
So I could call the function in any of the following ways :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$display   .= SSM_inputSelect( &amp;quot;SelectBox&amp;quot;, &amp;quot;one|two|three&amp;quot; );&lt;br /&gt;
$display   .= SSM_inputSelect( &amp;quot;SelectBox&amp;quot;, &amp;quot;one|two|three&amp;quot;, &amp;quot;one&amp;quot; );&lt;br /&gt;
$display   .= SSM_inputSelect( &amp;quot;SelectBox&amp;quot;, &amp;quot;one|two|three&amp;quot;, &amp;quot;one&amp;quot;, 0 );&lt;br /&gt;
$display   .= SSM_inputSelect( &amp;quot;SelectBox&amp;quot;, &amp;quot;one|two|three&amp;quot;, &amp;quot;one&amp;quot;, 0, 1 );&lt;br /&gt;
$display   .= SSM_inputSelect( &amp;quot;SelectBox&amp;quot;, &amp;quot;one:two:three&amp;quot;, &amp;quot;one&amp;quot;, 0, 1, &amp;quot;:&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and so on.  But I could not do this if all I wanted to specify was &amp;quot;mySep&amp;quot; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$display   .= SSM_inputSelect( &amp;quot;SelectBox&amp;quot;, &amp;quot;one:two:three&amp;quot;, ,,, &amp;quot;:&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So the moral of the story is that if you are having parameters with default values you have to give some consideration to the order of the arguments.  You want the ones least likey to be overridden to be the right-most, and the ones most likely to be overridden to be left-most.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function SSM_inputSelect( $myName, $myOptions, $myDefault=&amp;quot;&amp;quot;, $myMulti=0,&lt;br /&gt;
                                $mySize=1, $mySep=&amp;quot;|&amp;quot;, $visible=true )&lt;br /&gt;
{&lt;br /&gt;
        $retval .= &amp;quot;&amp;quot;&lt;br /&gt;
        . &amp;quot;&amp;lt;SELECT size=\&amp;quot;&amp;quot; . $mySize . &amp;quot;\&amp;quot; name=\&amp;quot;&amp;quot; . $myName . &amp;quot;\&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        $retval .= ($myMulti == 0) ? &amp;quot;&amp;gt;&amp;quot; : &amp;quot; multiple&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        $arrayOptions = explode($mySep,$myOptions);&lt;br /&gt;
&lt;br /&gt;
        foreach ($arrayOptions as $oneOption) {&lt;br /&gt;
                $oneOption = trim($oneOption);&lt;br /&gt;
                if ( $myMulti == 0 )&lt;br /&gt;
                        if ( $oneOption == $myDefault )&lt;br /&gt;
                                $retval .= &amp;quot;&amp;lt;OPTION SELECTED&amp;gt;&amp;quot; . $oneOption . &amp;quot;&amp;lt;/OPTION&amp;gt;&amp;quot;;&lt;br /&gt;
                        else&lt;br /&gt;
                                $retval .= &amp;quot;&amp;lt;OPTION&amp;gt;&amp;quot; . $oneOption . &amp;quot;&amp;lt;/OPTION&amp;gt;&amp;quot;;&lt;br /&gt;
                else&lt;br /&gt;
                        if ( in_array( $oneOption, $myDefault ))&lt;br /&gt;
                                $retval .= &amp;quot;&amp;lt;OPTION SELECTED&amp;gt;&amp;quot; . $oneOption . &amp;quot;&amp;lt;/OPTION&amp;gt;&amp;quot;;&lt;br /&gt;
                        else&lt;br /&gt;
                                $retval .= &amp;quot;&amp;lt;OPTION&amp;gt;&amp;quot; . $oneOption . &amp;quot;&amp;lt;/OPTION&amp;gt;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $retval .= &amp;quot;&amp;quot;&lt;br /&gt;
        . &amp;quot;&amp;lt;/SELECT&amp;gt;&amp;quot;&lt;br /&gt;
        . &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        return $retval;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now let's have a look at another function which builds on the above by allowing us to pull stuff out of the database and present it in an options list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function SSM_inputSelectDBField( $myName, $myTable, $myField, $myDefault=&amp;quot;&amp;quot;,&lt;br /&gt;
                                $mySize=1, $myMulti=0, $extra=&amp;quot;&amp;quot;, $mySep=&amp;quot;|&amp;quot; )&lt;br /&gt;
{&lt;br /&gt;
        // select distinct entries from the given field of given table&lt;br /&gt;
        $sql    = &amp;quot;SELECT DISTINCT &amp;quot; . $myField . &amp;quot; FROM &amp;quot; . $myTable&lt;br /&gt;
                . &amp;quot; ORDER BY &amp;quot; . $myField;&lt;br /&gt;
&lt;br /&gt;
        // allows us to add an extra entry that was not in the DB&lt;br /&gt;
&lt;br /&gt;
        if ( $extra != &amp;quot;&amp;quot; )&lt;br /&gt;
                $myOpts = $extra . $myOpts;&lt;br /&gt;
&lt;br /&gt;
        $result = DB_query($sql);&lt;br /&gt;
&lt;br /&gt;
        // format the data as required by SSM_inputSelect()&lt;br /&gt;
&lt;br /&gt;
        while ( $R = DB_fetchArray( $result ) )&lt;br /&gt;
                if ( $myOpts == &amp;quot;&amp;quot; )&lt;br /&gt;
                        $myOpts .= $R[$myField];&lt;br /&gt;
                else&lt;br /&gt;
                        $myOpts .= $mySep . $R[$myField];&lt;br /&gt;
&lt;br /&gt;
        // now call the guy doing the actual work&lt;br /&gt;
&lt;br /&gt;
        $retstr .= SSM_inputSelect( $myName, $myOpts, $myDefault, $myMulti,&lt;br /&gt;
                                $mySize, $mySep );&lt;br /&gt;
&lt;br /&gt;
        return $retstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally here is a similar function which once again builds upon &amp;quot;SSM_inputSelect&amp;quot; but this time it takes an field of type ENUM and builds a SELECT box out of all the possible preset values of the ENUM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Does not yet allow multi select but should be rewritten to do this&lt;br /&gt;
&lt;br /&gt;
function SSM_inputEnumDBField( $myName, $myTable, $myField, $myDefault=&amp;quot;&amp;quot;, $visible=true )&lt;br /&gt;
{&lt;br /&gt;
        // query the DB to extract the enum values&lt;br /&gt;
        $qqq    = &amp;quot;DESCRIBE $myTable $myField&amp;quot;;&lt;br /&gt;
        $result = DB_query( $qqq );&lt;br /&gt;
        $arow   = DB_fetchArray( $result );&lt;br /&gt;
        $myArr  = explode( &amp;quot;,&amp;quot;, trim( strstr( $arow['Type'], &amp;quot;(&amp;quot; ), &amp;quot;()&amp;quot;)) ;&lt;br /&gt;
&lt;br /&gt;
        // now format the values as required by SSM_inputSelect()&lt;br /&gt;
        $idx=0;&lt;br /&gt;
        $cnt    = count($myArr);&lt;br /&gt;
        while($idx&amp;lt;$cnt)&lt;br /&gt;
        {&lt;br /&gt;
                $myArr[$idx]    = trim( $myArr[$idx], &amp;quot;'&amp;quot; );&lt;br /&gt;
                $idx++;&lt;br /&gt;
        }&lt;br /&gt;
        sort( $myArr );&lt;br /&gt;
        $myList         = implode( &amp;quot;|&amp;quot;, $myArr );&lt;br /&gt;
&lt;br /&gt;
        // now call our workhorse&lt;br /&gt;
&lt;br /&gt;
        return SSM_inputSelect( $myName, $myList, $myDefault );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The lesson here is that your functions should be well-defined and reusable.  Here we could have written 2 different functions which have nothing to do with each other, but instead we wrote a 3rd base function first which the other 2 rely on to get the job done.  Now if there is some substantial change in how I want the SELECT boxes drawn, I only have to make the change in one place.&lt;br /&gt;
&lt;br /&gt;
==Support and Such==&lt;br /&gt;
&lt;br /&gt;
The best place for Geeklog support is of course [http://www.geeklog.net the main Geeklog site].&lt;br /&gt;
&lt;br /&gt;
If you want to report a bug or request a feature, set yourself up an account [http://project.geeklog.net/tracking/signup_page.php here] and do so.  If they don't know it is broken, they can't fix it.  I've reported several bugs and have had them fixed promptly.  I've also tracked down and fixed several bugs and simply submitted the code which was accepted.  And I've also requested several features which have been added over the years at my request.  The Geeklog development team is small, but very dedicated and they love to get feedback from the user base.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Installing_Geeklog:System_Requirements&amp;diff=6070</id>
		<title>Installing Geeklog:System Requirements</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Installing_Geeklog:System_Requirements&amp;diff=6070"/>
				<updated>2011-07-01T20:30:29Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Update minimum requirement to reflect 1.8.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation - System Requirements ==&lt;br /&gt;
&lt;br /&gt;
The system requirements for installing Geeklog 1.8.0 and later are as follows:&lt;br /&gt;
&lt;br /&gt;
# Web server - one of the following&lt;br /&gt;
## Apache Web Server&lt;br /&gt;
## Microsoft IIS (Internet Information Server)&lt;br /&gt;
## Zeus&lt;br /&gt;
# PHP 5.2.0&lt;br /&gt;
# Database server - one of the following&lt;br /&gt;
## MySQL 3.23.2 or higher, preferably at least 4.x or later&lt;br /&gt;
## Microsoft SQL Server 2000 or later&lt;br /&gt;
## Postgresql 7 or later&lt;br /&gt;
# The ability to create a new database or to have access to an existing one&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=6042</id>
		<title>CommentAlgorithm</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=6042"/>
				<updated>2011-05-13T01:33:35Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Representing Geeklog's Comments in the Database=&lt;br /&gt;
&lt;br /&gt;
Since Geeklog 1.3.10, Geeklog's comments have been stored in the database with columns (''lft'', ''rht'') representing a (modified) pre-order traversal ordering. This method of storage was chosen to improve comment retrieval performance, especially when viewing a subset of the comments for a given story.&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
The idea behind pre-order traversal ordering, is that each node is ordered (or visited) before any of its children. In the modified preorder traversal algorithm implemented by Geeklog, the ''lft'' value of a comment is always less than the ''lft'' and ''rht'' values of all of the children of that node. Likewise the ''rht'' value of a node is always greater that the ''lft'' and ''rht'' values of all of the children of that node. (And trivially for any node, ''lft'' is always less than ''rht''.) A node without any children has the property ''rht'' is exactly one more than ''lft''. &lt;br /&gt;
&lt;br /&gt;
Example: Comment A is a top level comment to a story. Comments A-A and A-B are children of A and comments A-A-A, A-A-B, and A-A-C are children of A-A. The table below shows the values for each comment:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |comment&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |parent&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |lft&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |rht&lt;br /&gt;
|-&lt;br /&gt;
|A&lt;br /&gt;
|N/A&lt;br /&gt;
|1&lt;br /&gt;
|12&lt;br /&gt;
|-&lt;br /&gt;
|A-A&lt;br /&gt;
|A&lt;br /&gt;
|2&lt;br /&gt;
|9&lt;br /&gt;
|-&lt;br /&gt;
|A-B&lt;br /&gt;
|A&lt;br /&gt;
|10&lt;br /&gt;
|11&lt;br /&gt;
|-&lt;br /&gt;
|A-A-A&lt;br /&gt;
|A-A&lt;br /&gt;
|3&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|A-A-B&lt;br /&gt;
|A-A&lt;br /&gt;
|5&lt;br /&gt;
|6&lt;br /&gt;
|-&lt;br /&gt;
|A-A-C&lt;br /&gt;
|A-A&lt;br /&gt;
|7&lt;br /&gt;
|8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The resulting database structure has many advantages. Selecting a subtree from the database is as easy as specifying the ''lft'' and ''rht'' numbers of the root node of the subtree. For instance, to get the subtree with root comment &amp;quot;A-A&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt;= 2 AND rht &amp;lt;= 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or selecting all the children of a give node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt; 2 AND rht &amp;lt; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To select comments ordered for display in a &amp;quot;nested&amp;quot; format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments ORDER BY lft&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Storing the preorder traversal information also allows us to easily find the path to a node (i.e. a nodes parents, grandparents, etc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;lt; 7 AND rht &amp;gt; 8&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Counting the number of children of a comment is equally easy: &amp;lt;code&amp;gt;('rht' - 'lft' - 1)/2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Previously these operations required a (very slow) recursive algorithm. The way Geeklog had implemented this algorithm required one database query for every comment in the result set. Another way would have been to do one query to fetch all comments, and then use a recursive function to choose the desired comments. Both methods were extremely inefficient and caused load problems on frequently viewed Geeklog sites.&lt;br /&gt;
&lt;br /&gt;
The downside to this method is that inserting and deleting comments takes more work (three queries instead of one) and must be done in a single transaction (or a write lock on the table). Inserts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht + 2 WHERE rht &amp;gt;= parent_comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft + 2 WHERE lft &amp;gt;= parent_comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
INSERT INTO comments SET lft = parent_comment.rht, rht = parent_comment.rht + 1&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht - 2 WHERE rht &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft - 2 WHERE lft &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
DELETE FROM comments WHERE id = comment.id&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, since fetching (reading) comments is a much more frequent action then adding or deleting comments and the increase in efficiency for fetching comments is much greater than the loss of efficiency for adding and deleting comments, the trade off is worthwhile.&lt;br /&gt;
&lt;br /&gt;
Please note that in the SQL examples above, parts of the query were left out to make the algorithm more clear. For more detail, see the Geeklog source code (specifically lib-comment.php).&lt;br /&gt;
&lt;br /&gt;
==External related articles==&lt;br /&gt;
* [http://www.sitepoint.com/article/hierarchical-data-database/2/ Storing Hierarchical Data in a Database]&lt;br /&gt;
* [http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html Trees in SQL]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Tree_traversal Tree Traversal]&lt;br /&gt;
* [http://dev.mysql.com/tech-resources/articles/hierarchical-data.html Managing Hierarchical Data in MySQL]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5934</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5934"/>
				<updated>2010-12-15T06:47:01Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Thoughts: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
* Review Security (specifically user access rights to events)&lt;br /&gt;
** Make use of SEC_createToken, SEC_checkToken to preven CSRF attacks.&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;br /&gt;
* Conversion script to convert existing Geeklog calendars to Calendarv2.&lt;br /&gt;
* Use PHP's locale settings for Day of Week, Month Names, etc instead of the language file [http://php.net/manual/en/function.setlocale.php]&lt;br /&gt;
&lt;br /&gt;
== Thoughts: ==&lt;br /&gt;
&lt;br /&gt;
* AEvents Class&lt;br /&gt;
** Should the _events array be an associative array with the events' EIDs as keys?&lt;br /&gt;
* Event Class&lt;br /&gt;
** Should the class be aware of whether the event already exists in the DB? That way it know which of &amp;quot;update_to_database&amp;quot; and &amp;quot;save_to_database&amp;quot; function is appropriate?&lt;br /&gt;
** Should the class be aware of whether the event is the moderation or event table? That way the &amp;quot;modify&amp;quot; and &amp;quot;modify_moderation&amp;quot; functions wouldn't be necessary (the class would know the appropriate table automatically).&lt;br /&gt;
* addslashes is used extensively to sanitize input. Should Geeklog's filter routines be used instead in places?&lt;br /&gt;
* upload.php -- mentioned in a previous email, but we should be using the upload.class.php that comes with Geeklog.&lt;br /&gt;
* Geeklog allows the use of InnoDB tables. The calendar should use whatever table type the rest of Geeklog is using.&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5933</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5933"/>
				<updated>2010-12-15T06:45:23Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Thoughts: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
* Review Security (specifically user access rights to events)&lt;br /&gt;
** Make use of SEC_createToken, SEC_checkToken to preven CSRF attacks.&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;br /&gt;
* Conversion script to convert existing Geeklog calendars to Calendarv2.&lt;br /&gt;
* Use PHP's locale settings for Day of Week, Month Names, etc instead of the language file [http://php.net/manual/en/function.setlocale.php]&lt;br /&gt;
&lt;br /&gt;
== Thoughts: ==&lt;br /&gt;
&lt;br /&gt;
* AEvents Class&lt;br /&gt;
** Should the _events array be an associative array with the events' EIDs as keys?&lt;br /&gt;
* Event Class&lt;br /&gt;
** Should the class be aware of whether the event already exists in the DB? That way it know which of &amp;quot;update_to_database&amp;quot; and &amp;quot;save_to_database&amp;quot; function is appropriate?&lt;br /&gt;
** Should the class be aware of whether the event is the moderation or event table? That way the &amp;quot;modify&amp;quot; and &amp;quot;modify_moderation&amp;quot; functions wouldn't be necessary (the class would know the appropriate table automatically).&lt;br /&gt;
* addslashes is used extensively to sanitize input. Should Geeklog's filter routines be used instead in places?&lt;br /&gt;
* upload.php -- mentioned in a previous email, but we should be using the upload.class.php that comes with Geeklog.&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5932</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5932"/>
				<updated>2010-12-15T06:44:14Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* What needs to be done till the alpha release? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
* Review Security (specifically user access rights to events)&lt;br /&gt;
** Make use of SEC_createToken, SEC_checkToken to preven CSRF attacks.&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;br /&gt;
* Conversion script to convert existing Geeklog calendars to Calendarv2.&lt;br /&gt;
* Use PHP's locale settings for Day of Week, Month Names, etc instead of the language file [http://php.net/manual/en/function.setlocale.php]&lt;br /&gt;
&lt;br /&gt;
== Thoughts: ==&lt;br /&gt;
&lt;br /&gt;
* AEvents Class&lt;br /&gt;
** Should the _events array be an associative array with the events' EIDs as keys?&lt;br /&gt;
* Event Class&lt;br /&gt;
** Should the class be aware of whether the event already exists in the DB? That way it know which of &amp;quot;update_to_database&amp;quot; and &amp;quot;save_to_database&amp;quot; function is appropriate?&lt;br /&gt;
** Should the class be aware of whether the event is the moderation or event table? That way the &amp;quot;modify&amp;quot; and &amp;quot;modify_moderation&amp;quot; functions wouldn't be necessary (the class would know the appropriate table automatically).&lt;br /&gt;
* addslashes is used extensively to sanitize input. Should Geeklog's filter routines be used instead in places?&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5931</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5931"/>
				<updated>2010-12-15T06:43:33Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Thoughts: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
* Review Security (specifically user access rights to events)&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;br /&gt;
* Conversion script to convert existing Geeklog calendars to Calendarv2.&lt;br /&gt;
* Use PHP's locale settings for Day of Week, Month Names, etc instead of the language file [http://php.net/manual/en/function.setlocale.php]&lt;br /&gt;
&lt;br /&gt;
== Thoughts: ==&lt;br /&gt;
&lt;br /&gt;
* AEvents Class&lt;br /&gt;
** Should the _events array be an associative array with the events' EIDs as keys?&lt;br /&gt;
* Event Class&lt;br /&gt;
** Should the class be aware of whether the event already exists in the DB? That way it know which of &amp;quot;update_to_database&amp;quot; and &amp;quot;save_to_database&amp;quot; function is appropriate?&lt;br /&gt;
** Should the class be aware of whether the event is the moderation or event table? That way the &amp;quot;modify&amp;quot; and &amp;quot;modify_moderation&amp;quot; functions wouldn't be necessary (the class would know the appropriate table automatically).&lt;br /&gt;
* addslashes is used extensively to sanitize input. Should Geeklog's filter routines be used instead in places?&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5930</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5930"/>
				<updated>2010-12-14T08:02:48Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
* Review Security (specifically user access rights to events)&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;br /&gt;
* Conversion script to convert existing Geeklog calendars to Calendarv2.&lt;br /&gt;
* Use PHP's locale settings for Day of Week, Month Names, etc instead of the language file [http://php.net/manual/en/function.setlocale.php]&lt;br /&gt;
&lt;br /&gt;
== Thoughts: ==&lt;br /&gt;
&lt;br /&gt;
* AEvents Class&lt;br /&gt;
** Should the _events array be an associative array with the events' EIDs as keys?&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5929</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5929"/>
				<updated>2010-12-14T07:32:11Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Future plans/improvements: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;br /&gt;
* Conversion script to convert existing Geeklog calendars to Calendarv2.&lt;br /&gt;
* Use PHP's locale settings for Day of Week, Month Names, etc instead of the language file [http://php.net/manual/en/function.setlocale.php]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5925</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5925"/>
				<updated>2010-11-29T03:24:43Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Future plans/improvements: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;br /&gt;
* Conversion script to convert existing Geeklog calendars to Calendarv2.&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5918</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5918"/>
				<updated>2010-11-28T03:07:17Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* What needs to be done till the alpha release? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
* Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5917</id>
		<title>Calendarv2</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Calendarv2&amp;diff=5917"/>
				<updated>2010-11-28T03:05:54Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Future plans/improvements: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What needs to be done till the alpha release? ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Fix Ical Support. &amp;lt;br&amp;gt;&lt;br /&gt;
- Render recurring events immediately after an event was created, not just on page load.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future plans/improvements: ==&lt;br /&gt;
&lt;br /&gt;
* When Geeklog moves to PHP 5.3 (or earlier, as time permits) switch to using MySQL Datetime types. PHP 5.3's enhanced DateTime class makes the switch easier.&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Plugin_Toolkit&amp;diff=5820</id>
		<title>Plugin Toolkit</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Plugin_Toolkit&amp;diff=5820"/>
				<updated>2010-05-06T17:15:24Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: grammer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Geeklog Plugin Toolkit is set to eventually replace the aging [[Universal Plugin ToolKit|Universal Plugin]]. It will contain of a set of tools to assist plugin developers in creating and maintaining their plugins.&lt;br /&gt;
&lt;br /&gt;
For now, there is only one tool available: The Plugin Generator.&lt;br /&gt;
&lt;br /&gt;
== Plugin Generator ==&lt;br /&gt;
&lt;br /&gt;
The Plugin Generator has to be called from the command line. For this, you need the CLI version of PHP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cd plugin-toolkit&lt;br /&gt;
php plgen.php&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Follow the on-screen instructions. Default values are given in square brackets and can be used by pressing enter. If you want to change a value, simply enter it and then press enter.&lt;br /&gt;
&lt;br /&gt;
A plugin directory, using the name you entered, will be created in the current directory. This is a fully usable plugin, although it doesn't exactly do much yet. It does, however, perform install and uninstall and includes generic public and admin pages. Filling in the functionality is your job ...&lt;br /&gt;
&lt;br /&gt;
'''Note:''' [http://project.geeklog.net/tracking/view.php?id=828 Currently] the created plugin requires Geeklog 1.6 or later.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.geeklog.net/filemgmt/index.php?id=941 Download] from geeklog.net&lt;br /&gt;
* [http://project.geeklog.net/cgi-bin/hgwebdir.cgi/plugin-toolkit/ Mercurial repository] for the Plugin Toolkit&lt;br /&gt;
* The Plugin Toolkit is a separate project in the [http://project.geeklog.net/tracking/ bugtracker]. Select &amp;quot;Plugin Toolkit&amp;quot; from the &amp;quot;Project:&amp;quot; dropdown.&lt;br /&gt;
* [[Plugin Developers Handbook|Plugin Developer Handbook]]&lt;br /&gt;
** also see [[Programmers/Developers Documentation]] for plugin API changes and additions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Plugin Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Plugin_Toolkit&amp;diff=5819</id>
		<title>Plugin Toolkit</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Plugin_Toolkit&amp;diff=5819"/>
				<updated>2010-05-06T17:14:59Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Updated compatible version information.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Geeklog Plugin Toolkit is set to eventually replace the aging [[Universal Plugin ToolKit|Universal Plugin]]. It will contain of a set of tools to assist plugin developers in creating and maintaining their plugins.&lt;br /&gt;
&lt;br /&gt;
For now, there is only one tool available: The Plugin Generator.&lt;br /&gt;
&lt;br /&gt;
== Plugin Generator ==&lt;br /&gt;
&lt;br /&gt;
The Plugin Generator has to be called from the command line. For this, you need the CLI version of PHP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cd plugin-toolkit&lt;br /&gt;
php plgen.php&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Follow the on-screen instructions. Default values are given in square brackets and can be used by pressing enter. If you want to change a value, simply enter it and then press enter.&lt;br /&gt;
&lt;br /&gt;
A plugin directory, using the name you entered, will be created in the current directory. This is a fully usable plugin, although it doesn't exactly do much yet. It does, however, perform install and uninstall and includes generic public and admin pages. Filling in the functionality is your job ...&lt;br /&gt;
&lt;br /&gt;
'''Note:''' [http://project.geeklog.net/tracking/view.php?id=828 Currently], the created plugin requires Geeklog 1.6 or later.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.geeklog.net/filemgmt/index.php?id=941 Download] from geeklog.net&lt;br /&gt;
* [http://project.geeklog.net/cgi-bin/hgwebdir.cgi/plugin-toolkit/ Mercurial repository] for the Plugin Toolkit&lt;br /&gt;
* The Plugin Toolkit is a separate project in the [http://project.geeklog.net/tracking/ bugtracker]. Select &amp;quot;Plugin Toolkit&amp;quot; from the &amp;quot;Project:&amp;quot; dropdown.&lt;br /&gt;
* [[Plugin Developers Handbook|Plugin Developer Handbook]]&lt;br /&gt;
** also see [[Programmers/Developers Documentation]] for plugin API changes and additions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Plugin Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5752</id>
		<title>SoC calendar plugin</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5752"/>
				<updated>2010-03-04T23:48:28Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: added outlook sync to &amp;quot;nice to haves&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(This is an idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog's current calendar plugin is old and unmaintainable. It has no support for modern calendar standards and cannot support such basic functionality as recurring events. It's interface is antiquated and its sharing/group features are extremely limited.&lt;br /&gt;
&lt;br /&gt;
A new Calendar plugin, written from scratch, could be designed from the ground up to work with calendar standards and support a wide variety of use cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
Listed below are an initial set of requirements. Students applying to complete this project can use the below list as a design outline. Though, don't let the requirement set here limit you!&lt;br /&gt;
&lt;br /&gt;
=== Basic Requirements ===&lt;br /&gt;
* The calendar shall support events for individual users.&lt;br /&gt;
** Individuals shall be able to create multiple calendars (possibly limited to a number defined by an administrator).&lt;br /&gt;
** The calendar owner shall be able to control the visibility of the calendar (private, shared to a group, public).&lt;br /&gt;
* The calendar shall support site wide events.&lt;br /&gt;
** Who can submit site wide events shall be controlled by the site administrator.&lt;br /&gt;
** When given permission to submit site wide events, users can submit a copy of an existing individual events to the site wide calendar.&lt;br /&gt;
** The site administrator shall be able to moderate events submitted by non-admin users.&lt;br /&gt;
** Only site administrators shall be able to modify existing events.&lt;br /&gt;
* The calendar shall support recurring events.&lt;br /&gt;
* The calendar shall have an efficient implementation (responsive).&lt;br /&gt;
** A smart design will be needed to support recurring events without causing a lack of responsiveness.&lt;br /&gt;
* The calendar shall implement Geeklog's [[Multilingual Support|Multi-language support]].&lt;br /&gt;
* The calendar shall support &amp;quot;locales&amp;quot;.&lt;br /&gt;
** Configurable date and time format (e.g. 01/21/2010 vs 2010/01/21 vs 21/01/2010, 8:00pm vs 20:00h)&lt;br /&gt;
*** also for date and time entry&lt;br /&gt;
** Configurable first day of week (e.g. Monday vs Sunday)&lt;br /&gt;
&lt;br /&gt;
=== Nice to Haves ===&lt;br /&gt;
This is a set of items that would be nice for a calendar plugin to have. At the very least, a calendar plugin should be designed so that adding these features would not be difficult.&lt;br /&gt;
* The calendar shall support group events.&lt;br /&gt;
* The calendar shall have the ability to import, export and perhaps sync using the iCal ([http://tools.ietf.org/html/rfc5545 RFC5545]) format.&lt;br /&gt;
** Ability to share with services like [http://upcoming.yahoo.com/ Upcoming], [http://www.dopplr.com/ Dopplr], or [http://www.google.com/calendar Google Calendar], so events only have to be entered once.&lt;br /&gt;
** The calendar shall optionally support WebDAV ([http://tools.ietf.org/html/rfc2518 RFC2518]) for calendar and schedule sharing.&lt;br /&gt;
* The calendar shall be able to sync with MS Outlook (very difficult!).&lt;br /&gt;
* The calendar shall support [http://microformats.org/wiki/hcalendar HCalendar].&lt;br /&gt;
* The calendar shall support for event reminders.&lt;br /&gt;
* The calendar shall support sending event invitations and tracking responses.&lt;br /&gt;
&lt;br /&gt;
=== Bonus Items ===&lt;br /&gt;
Listed here are items that do not have a direct impact on the plugin design, but are features that would be nice to have if time permits.&lt;br /&gt;
* A migration utility to convert existing Geeklog calendar tables to work with the new plugin.&lt;br /&gt;
* Create a calendar block for display in Geeklog's left or right blocks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
If desired, a license compatible (Geeklog is licensed [http://www.gnu.org/licenses/gpl-2.0.html GPL 2.0]) PHP library/program can be used. However, this should definitely be researched and decided upon before an application is submitted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium'' to ''difficult''&lt;br /&gt;
&lt;br /&gt;
The level of difficulty on this project will be dependent upon the design and feature set chosen to be implemented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
===References===&lt;br /&gt;
* [http://en.wikipedia.org/wiki/ICalendar Wikipedia: iCalendar]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/CalDAV Wikipedia: CalDAV]&lt;br /&gt;
&lt;br /&gt;
===Bug Tracker===&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=974 0000974: Make order of day/month/year dropdowns configurable in editors (without template change)]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=635 0000635: Required visual cues in Calendar Plugin's Event Editor v1.5b1]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=993 0000993: calendar plugin: submit event's owner is not submit user.]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=946 0000946: Issue about &amp;quot;Submit an Event&amp;quot; form of the Calendar plugin]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=775 0000775: Mark links to future dates in calendar with rel=&amp;quot;nofollow&amp;quot;]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=674 0000674: Calender Event invitations]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=675 0000675: Calendar Event Reminder Email]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5751</id>
		<title>SoC calendar plugin</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5751"/>
				<updated>2010-03-04T23:42:27Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Separated out &amp;quot;must haves&amp;quot; and &amp;quot;nice to haves&amp;quot;. Added Notes section. Fixed some spelling, grammer, and &amp;quot;clarity&amp;quot; errors.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(This is an idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog's current calendar plugin is old and unmaintainable. It has no support for modern calendar standards and cannot support such basic functionality as recurring events. It's interface is antiquated and its sharing/group features are extremely limited.&lt;br /&gt;
&lt;br /&gt;
A new Calendar plugin, written from scratch, could be designed from the ground up to work with calendar standards and support a wide variety of use cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
Listed below are an initial set of requirements. Students applying to complete this project can use the below list as a design outline. Though, don't let the requirement set here limit you!&lt;br /&gt;
&lt;br /&gt;
=== Basic Requirements ===&lt;br /&gt;
* The calendar shall support events for individual users.&lt;br /&gt;
** Individuals shall be able to create multiple calendars (possibly limited to a number defined by an administrator).&lt;br /&gt;
** The calendar owner shall be able to control the visibility of the calendar (private, shared to a group, public).&lt;br /&gt;
* The calendar shall support site wide events.&lt;br /&gt;
** Who can submit site wide events shall be controlled by the site administrator.&lt;br /&gt;
** When given permission to submit site wide events, users can submit a copy of an existing individual events to the site wide calendar.&lt;br /&gt;
** The site administrator shall be able to moderate events submitted by non-admin users.&lt;br /&gt;
** Only site administrators shall be able to modify existing events.&lt;br /&gt;
* The calendar shall support recurring events.&lt;br /&gt;
* The calendar shall have an efficient implementation (responsive).&lt;br /&gt;
** A smart design will be needed to support recurring events without causing a lack of responsiveness.&lt;br /&gt;
* The calendar shall implement Geeklog's [[Multilingual Support|Multi-language support]].&lt;br /&gt;
* The calendar shall support &amp;quot;locales&amp;quot;.&lt;br /&gt;
** Configurable date and time format (e.g. 01/21/2010 vs 2010/01/21 vs 21/01/2010, 8:00pm vs 20:00h)&lt;br /&gt;
*** also for date and time entry&lt;br /&gt;
** Configurable first day of week (e.g. Monday vs Sunday)&lt;br /&gt;
&lt;br /&gt;
=== Nice to Haves ===&lt;br /&gt;
This is a set of items that would be nice for a calendar plugin to have. At the very least, a calendar plugin should be designed so that adding these features would not be difficult.&lt;br /&gt;
* The calendar shall support group events.&lt;br /&gt;
* The calendar shall have the ability to import, export and perhaps sync using the iCal ([http://tools.ietf.org/html/rfc5545 RFC5545]) format.&lt;br /&gt;
** Ability to share with services like [http://upcoming.yahoo.com/ Upcoming], [http://www.dopplr.com/ Dopplr], or [http://www.google.com/calendar Google Calendar], so events only have to be entered once.&lt;br /&gt;
** The calendar shall optionally support WebDAV ([http://tools.ietf.org/html/rfc2518 RFC2518]) for calendar and schedule sharing.&lt;br /&gt;
* The calendar shall support [http://microformats.org/wiki/hcalendar HCalendar].&lt;br /&gt;
* The calendar shall support for event reminders.&lt;br /&gt;
* The calendar shall support sending event invitations and tracking responses.&lt;br /&gt;
&lt;br /&gt;
=== Bonus Items ===&lt;br /&gt;
Listed here are items that do not have a direct impact on the plugin design, but are features that would be nice to have if time permits.&lt;br /&gt;
* A migration utility to convert existing Geeklog calendar tables to work with the new plugin.&lt;br /&gt;
* Create a calendar block for display in Geeklog's left or right blocks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
If desired, a license compatible (Geeklog is licensed [http://www.gnu.org/licenses/gpl-2.0.html GPL 2.0]) PHP library/program can be used. However, this should definitely be researched and decided upon before an application is submitted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium'' to ''difficult''&lt;br /&gt;
&lt;br /&gt;
The level of difficulty on this project will be dependent upon the design and feature set chosen to be implemented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
===References===&lt;br /&gt;
* [http://en.wikipedia.org/wiki/ICalendar Wikipedia: iCalendar]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/CalDAV Wikipedia: CalDAV]&lt;br /&gt;
&lt;br /&gt;
===Bug Tracker===&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=974 0000974: Make order of day/month/year dropdowns configurable in editors (without template change)]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=635 0000635: Required visual cues in Calendar Plugin's Event Editor v1.5b1]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=993 0000993: calendar plugin: submit event's owner is not submit user.]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=946 0000946: Issue about &amp;quot;Submit an Event&amp;quot; form of the Calendar plugin]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=775 0000775: Mark links to future dates in calendar with rel=&amp;quot;nofollow&amp;quot;]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=674 0000674: Calender Event invitations]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=675 0000675: Calendar Event Reminder Email]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=5729</id>
		<title>CommentAlgorithm</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=5729"/>
				<updated>2010-02-25T18:37:45Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added missing /code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Representing Geeklog's Comments in the Database=&lt;br /&gt;
&lt;br /&gt;
Since Geeklog 1.3.10, Geeklog's comments have been stored in the database with columns (''lft'', ''rht'') representing a (modified) pre-order traversal ordering. This method of storage was chosen to improve comment retrieval performance, especially when viewing a subset of the comments for a given story.&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
The idea behind pre-order traversal ordering, is that each node is ordered (or visited) before any of its children. In the modified preorder traversal algorithm implemented by Geeklog, the ''lft'' value of a comment is always less than the ''lft'' and ''rht'' values of all of the children of that node. Likewise the ''rht'' value of a node is always greater that the ''lft'' and ''rht'' values of all of the children of that node. (And trivially for any node, ''lft'' is always less than ''rht''.) A node without any children has the property ''rht'' is exactly one more than ''lft''. &lt;br /&gt;
&lt;br /&gt;
Example: Comment A is a top level comment to a story. Comments A-A and A-B are children of A and comments A-A-A, A-A-B, and A-A-C are children of A-A. The table below shows the values for each comment:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |comment&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |parent&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |lft&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |rht&lt;br /&gt;
|-&lt;br /&gt;
|A&lt;br /&gt;
|N/A&lt;br /&gt;
|1&lt;br /&gt;
|12&lt;br /&gt;
|-&lt;br /&gt;
|A-A&lt;br /&gt;
|A&lt;br /&gt;
|2&lt;br /&gt;
|9&lt;br /&gt;
|-&lt;br /&gt;
|A-B&lt;br /&gt;
|A&lt;br /&gt;
|10&lt;br /&gt;
|11&lt;br /&gt;
|-&lt;br /&gt;
|A-A-A&lt;br /&gt;
|A-A&lt;br /&gt;
|3&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|A-A-B&lt;br /&gt;
|A-A&lt;br /&gt;
|5&lt;br /&gt;
|6&lt;br /&gt;
|-&lt;br /&gt;
|A-A-C&lt;br /&gt;
|A-A&lt;br /&gt;
|7&lt;br /&gt;
|8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The resulting database structure has many advantages. Selecting a subtree from the database is as easy as specifying the ''lft'' and ''rht'' numbers of the root node of the subtree. For instance, to get the subtree with root comment &amp;quot;A-A&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt;= 2 AND rht &amp;lt;= 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or selecting all the children of a give node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt; 2 AND rht &amp;lt; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To select comments ordered for display in a &amp;quot;nested&amp;quot; format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments ORDER BY lft&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Storing the preorder traversal information also allows us to easily find the path to a node (i.e. a nodes parents, grandparents, etc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;lt; 7 AND rht &amp;gt; 8&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Counting the number of children of a comment is equally easy: &amp;lt;code&amp;gt;('rht' - 'lft' - 1)/2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Previously these operations required a (very slow) recursive algorithm. The way Geeklog had implemented this algorithm required one database query for every comment in the result set. Another way would have been to do one query to fetch all comments, and then use a recursive function to choose the desired comments. Both methods were extremely inefficient and caused load problems on frequently viewed Geeklog sites.&lt;br /&gt;
&lt;br /&gt;
The downside to this method is that inserting and deleting comments takes more work (three queries instead of one) and must be done in a single transaction (or a write lock on the table). Inserts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht + 2 WHERE rht &amp;gt;= comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft + 2 WHERE lft &amp;gt;= comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
INSERT INTO comments SET lft = comment.rht, rht = comment.rht + 1&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht - 2 WHERE rht &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft - 2 WHERE lft &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
DELETE FROM comments WHERE id = comment.id&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, since fetching (reading) comments is a much more frequent action then adding or deleting comments and the increase in efficiency for fetching comments is much greater than the loss of efficiency for adding and deleting comments, the trade off is worth while.&lt;br /&gt;
&lt;br /&gt;
Please note that in the SQL examples above, parts of the query were left out to make the algorithm more clear. For more detail, see the Geeklog source code (specifically lib-comment.php).&lt;br /&gt;
&lt;br /&gt;
==External related articles==&lt;br /&gt;
* [http://www.sitepoint.com/article/hierarchical-data-database/2/ Storing Hierarchical Data in a Database]&lt;br /&gt;
* [http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html Trees in SQL]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Tree_traversal Tree Traversal]&lt;br /&gt;
* [http://dev.mysql.com/tech-resources/articles/hierarchical-data.html Managing Hierarchical Data in MySQL]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5726</id>
		<title>SoC calendar plugin</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5726"/>
				<updated>2010-02-24T18:29:09Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added some more links, WebDAV&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(This is an idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog's current calendar plugin is old and unmaintainable. It has no support for modern calendar standards and cannot support such basic functionality as recurring events. It's interface is antiquated and its sharing/group features are extremely limited.&lt;br /&gt;
&lt;br /&gt;
A new Calendar plugin, written from scratch, could be designed from the group up to work with calendar standards and support a wide variety of use cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
Listed below are an initial set of requirements. Students applying to complete this project can use the below list as a design outline.&lt;br /&gt;
&lt;br /&gt;
* The calendar shall support events for individual users.&lt;br /&gt;
** Individuals shall be able to create multiple calendars (limited to number defined by an administrator).&lt;br /&gt;
** The calendar owner shall be able to control the visibility of the calendar (private, shared to a group, public). &lt;br /&gt;
* The calendar shall support group events.&lt;br /&gt;
* The calendar shall support site wide events.&lt;br /&gt;
** Who can submit site wide events shall be controlled by the site administrator.&lt;br /&gt;
** When given permission to submit site wide events, users can submit a copy of an existing individual events to the site wide calendar.&lt;br /&gt;
** The site administrator shall be able to moderate events submitted by non-admin users.&lt;br /&gt;
** Only site administrators shall be able to modify existing events.&lt;br /&gt;
* The calendar shall have the ability to import, export and perhaps sync using the iCal ([http://tools.ietf.org/html/rfc5545 RFG5545]) format.&lt;br /&gt;
** Ability to share with services like [http://upcoming.yahoo.com/ Upcoming], [http://www.dopplr.com/ Dopplr], or [http://www.google.com/calendar Google Calendar], so events only have to be entered once.&lt;br /&gt;
** The calendar shall optionally support WebDAV ([http://tools.ietf.org/html/rfc2518 RFC2518]) for calendar and schedule sharing.&lt;br /&gt;
* The calendar shall support [http://microformats.org/wiki/hcalendar HCalendar].&lt;br /&gt;
* The calendar shall support recurring events.&lt;br /&gt;
* The calendar shall have an efficient implementation (responsive).&lt;br /&gt;
** A smart design will be needed to support recurring events without causing a lack of responsiveness.&lt;br /&gt;
* The calendar shall support for event reminders.&lt;br /&gt;
* The calendar shall support sending event invitations and tracking responses.&lt;br /&gt;
* The calendar shall implement Geeklog's [[Multilingual Support|Multi-language support]].&lt;br /&gt;
* The calendar shall support &amp;quot;locales&amp;quot;.&lt;br /&gt;
** Configurable date format (e.g. 01/21/2010 vs 2010/01/21 vs 21/01/2010)&lt;br /&gt;
** Configurable first day of week (e.g. Monday vs Sunday)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Bonus ==&lt;br /&gt;
* A migration utility to convert existing Geeklog calendar tables to work with the new plugin.&lt;br /&gt;
* Create a calendar block for display in Geeklog's left or right blocks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium'' to ''difficult''&lt;br /&gt;
&lt;br /&gt;
The level of difficulty on this project will be dependent upon the chosen design and implemented features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
===References===&lt;br /&gt;
* [http://en.wikipedia.org/wiki/ICalendar Wikipedia: iCalendar]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/CalDAV Wikipedia: CalDAV]&lt;br /&gt;
&lt;br /&gt;
===Bug Tracker===&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=974 0000974: Make order of day/month/year dropdowns configurable in editors (without template change)]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=635 0000635: Required visual cues in Calendar Plugin's Event Editor v1.5b1]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=993 0000993: calendar plugin: submit event's owner is not submit user.]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=946 0000946: Issue about &amp;quot;Submit an Event&amp;quot; form of the Calendar plugin]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=775 0000775: Mark links to future dates in calendar with rel=&amp;quot;nofollow&amp;quot;]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=674 0000674: Calender Event invitations]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=675 0000675: Calendar Event Reminder Email]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5725</id>
		<title>SoC calendar plugin</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5725"/>
				<updated>2010-02-24T17:36:44Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(This is an idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog's current calendar plugin is old and unmaintainable. It has no support for modern calendar standards and cannot support such basic functionality as recurring events. It's interface is antiquated and its sharing/group features are extremely limited.&lt;br /&gt;
&lt;br /&gt;
A new Calendar plugin, written from scratch, could be designed from the group up to work with calendar standards and support a wide variety of use cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
Listed below are an initial set of requirements. Students applying to complete this project can use the below list as a design outline.&lt;br /&gt;
&lt;br /&gt;
* The calendar shall support events for individual users.&lt;br /&gt;
** Individuals shall be able to create multiple calendars (limited to number defined by an administrator).&lt;br /&gt;
** The calendar owner shall be able to control the visibility of the calendar (private, shared to a group, public). &lt;br /&gt;
* The calendar shall support group events.&lt;br /&gt;
* The calendar shall support site wide events.&lt;br /&gt;
** Who can submit site wide events shall be controlled by the site administrator.&lt;br /&gt;
** When given permission to submit site wide events, users can submit a copy of an existing individual events to the site wide calendar.&lt;br /&gt;
** The site administrator shall be able to moderate events submitted by non-admin users.&lt;br /&gt;
** Only site administrators shall be able to modify existing events.&lt;br /&gt;
* The calendar shall have the ability to import, export and perhaps sync using the iCal ([http://tools.ietf.org/html/rfc5545 RFG5545]) format.&lt;br /&gt;
** Ability to share with services like [http://upcoming.yahoo.com/ Upcoming], [http://www.dopplr.com/ Dopplr], or [http://www.google.com/calendar Google Calendar], so events only have to be entered once.&lt;br /&gt;
* The calendar shall support [http://microformats.org/wiki/hcalendar HCalendar].&lt;br /&gt;
* The calendar shall support recurring events.&lt;br /&gt;
* The calendar shall have an efficient implementation (responsive).&lt;br /&gt;
** A smart design will be needed to support recurring events without causing a lack of responsiveness.&lt;br /&gt;
* The calendar shall support for event reminders.&lt;br /&gt;
* The calendar shall support sending event invitations and tracking responses.&lt;br /&gt;
* The calendar shall implement Geeklog's [[Multilingual Support|Multi-language support]].&lt;br /&gt;
* The calendar shall support &amp;quot;locales&amp;quot;.&lt;br /&gt;
** Configurable date format (e.g. 01/21/2010 vs 2010/01/21 vs 21/01/2010)&lt;br /&gt;
** Configurable first day of week (e.g. Monday vs Sunday)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Bonus ==&lt;br /&gt;
* A migration utility to convert existing Geeklog calendar tables to work with the new plugin.&lt;br /&gt;
* Create a calendar block for display in Geeklog's left or right blocks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium'' to ''difficult''&lt;br /&gt;
&lt;br /&gt;
The level of difficulty on this project will be dependent upon the chosen design and implemented features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
===From the Bug Tracker===&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=974 0000974: Make order of day/month/year dropdowns configurable in editors (without template change)]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=635 0000635: Required visual cues in Calendar Plugin's Event Editor v1.5b1]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=993 0000993: calendar plugin: submit event's owner is not submit user.]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=946 0000946: Issue about &amp;quot;Submit an Event&amp;quot; form of the Calendar plugin]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=775 0000775: Mark links to future dates in calendar with rel=&amp;quot;nofollow&amp;quot;]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=674 0000674: Calender Event invitations]&lt;br /&gt;
* [http://project.geeklog.net/tracking/view.php?id=675 0000675: Calendar Event Reminder Email]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5724</id>
		<title>SoC calendar plugin</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=SoC_calendar_plugin&amp;diff=5724"/>
				<updated>2010-02-24T17:20:55Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Initial Overview and Requriements.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;center&amp;gt;(This is an idea page for the [[Google Summer of Code]])&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Geeklog's current calendar plugin is old and unmaintainable. It has no support for modern calendar standards and cannot support such basic functionality as recurring events. It's interface is antiquated and its sharing/group features are extremely limited.&lt;br /&gt;
&lt;br /&gt;
A new Calendar plugin, written from scratch, could be designed from the group up to work with calendar standards and support a wide variety of use cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
Listed below are an initial set of requirements. Students applying to complete this project can use the below list as a design outline.&lt;br /&gt;
&lt;br /&gt;
* The calendar shall support events for individual users.&lt;br /&gt;
** Individuals shall be able to create multiple calendars (limited to number defined by an administrator).&lt;br /&gt;
** The calendar owner shall be able to control the visibility of the calendar (private, shared to a group, public). &lt;br /&gt;
* The calendar shall support group events.&lt;br /&gt;
* The calendar shall support site wide events.&lt;br /&gt;
** Who can submit site wide events shall be controlled by the site administrator.&lt;br /&gt;
** When given permission to submit site wide events, users can submit existing individual events to the site wide calendar.&lt;br /&gt;
** The site administrator shall be able to moderate events submitted by non-admin users.&lt;br /&gt;
* The calendar shall have the ability to import, export and perhaps sync using the iCal ([http://tools.ietf.org/html/rfc5545 RFG5545]) format.&lt;br /&gt;
** Ability to share with services like [http://upcoming.yahoo.com/ Upcoming], [http://www.dopplr.com/ Dopplr], or [http://www.google.com/calendar Google Calendar], so events only have to be entered once.&lt;br /&gt;
* The calendar shall support [http://microformats.org/wiki/hcalendar HCalendar].&lt;br /&gt;
* The calendar shall support recurring events.&lt;br /&gt;
* The calendar shall have an efficient implementation (responsive).&lt;br /&gt;
** A smart design will be needed to support recurring events without causing a lack of responsiveness.&lt;br /&gt;
* The calendar shall support for event reminders.&lt;br /&gt;
* The calendar shall support sending event invitations and tracking responses.&lt;br /&gt;
* The calendar shall implement Geeklog's [[Multilingual Support|Multi-language support]].&lt;br /&gt;
&lt;br /&gt;
== Bonus ==&lt;br /&gt;
* A migration utility to convert existing Geeklog calendar tables to work with the new plugin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level of Difficulty ==&lt;br /&gt;
''medium'' to ''difficult''&lt;br /&gt;
&lt;br /&gt;
The level of difficulty on this project will be dependent upon the chosen design and implemented features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=GSoC_Brainstorming&amp;diff=5723</id>
		<title>GSoC Brainstorming</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=GSoC_Brainstorming&amp;diff=5723"/>
				<updated>2010-02-24T17:16:48Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Moved calendar plugin into its own GSOC page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These are new and not fully fleshed-out ideas for the [[Google Summer of Code]]. Contributions welcome!&lt;br /&gt;
&lt;br /&gt;
* Site Migration for PostgreSQL and/or MS SQL&lt;br /&gt;
* Database Migration: Switch from Postgres to MySQL or MS SQL or the other way around&lt;br /&gt;
* E-Mail Subsystem: Geeklog sometimes has to send out a lot of emails. Instead of sending them all at once (and running into timeouts), we could queue them and send them out in batches. This queue should allow for other job types as well.&lt;br /&gt;
* Facebook Connect: Allow users to login to a Geeklog site with their Facebook Account. Could become part of the [[SoC socialnetworking|Social Networking Features]] Project.&lt;br /&gt;
* Multi-site Setup: Run several websites off of one codebase. There's a [http://geeklog.fr//wiki/doku.php/hack:geeklog-multi-sites-1.5.0 hack] for that, but it's a pain for upgrades.&lt;br /&gt;
* Admin toolbox: A collection of mini-plugins for admin tasks (e.g. reset stats, change a default setting for all users, etc.). Should have super easy install, e.g. just drop (upload?) a file in a predefined directory.&lt;br /&gt;
* Migration from/to other systems is always a hot topic. How could we make that easier?&lt;br /&gt;
* Multi user blogs. Geeklog can handle blogs of several users, actually, if you give one topic to a user then it is almost unlimited. There are a few existing discussions on the forum and also feature requests concerning the improvement of user blogs. E.g. read only topics, using GL for a large site with many users. Basically it is a native function of GL but it need some improvement.&lt;br /&gt;
* Add shopping cart and/or e-commerce functionality to Geeklog (in the form of a plugin). Using an existing open source shopping cart or e-commerce web application would probably be a good idea, but the result should be fully integrated with Geeklog's security model ([http://www.geeklog.net/forum/viewtopic.php?showtopic=74449 related forum discussion])&lt;br /&gt;
&lt;br /&gt;
As we flesh out these ideas, they will be moved to their own pages and linked to from our [[Google Summer of Code|GSoC Start Page]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=5722</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Google_Summer_of_Code&amp;diff=5722"/>
				<updated>2010-02-24T15:54:37Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added calendar plugin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=User:Vinny&amp;diff=5713</id>
		<title>User:Vinny</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=User:Vinny&amp;diff=5713"/>
				<updated>2010-02-16T23:08:07Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Email: [mailto:vinny01ATusersDOTsourceforgeDOTnet vinny01 AT users DOT sourceforge DOT net]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=GSoC_Brainstorming&amp;diff=5712</id>
		<title>GSoC Brainstorming</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=GSoC_Brainstorming&amp;diff=5712"/>
				<updated>2010-02-16T23:07:12Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added e-commerce idea&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These are new and not fully fleshed-out ideas for the [[Google Summer of Code]]. Contributions welcome!&lt;br /&gt;
&lt;br /&gt;
* Site Migration for PostgreSQL and/or MS SQL&lt;br /&gt;
* Database Migration: Switch from Postgres to MySQL or MS SQL or the other way around&lt;br /&gt;
* E-Mail Subsystem: Geeklog sometimes has to send out a lot of emails. Instead of sending them all at once (and running into timeouts), we could queue them and send them out in batches. This queue should allow for other job types as well.&lt;br /&gt;
* Facebook Connect: Allow users to login to a Geeklog site with their Facebook Account. Could become part of the [[SoC socialnetworking|Social Networking Features]] Project.&lt;br /&gt;
* Multi-site Setup: Run several websites off of one codebase. There's a [http://geeklog.fr//wiki/doku.php/hack:geeklog-multi-sites-1.5.0 hack] for that, but it's a pain for upgrades.&lt;br /&gt;
* Admin toolbox: A collection of mini-plugins for admin tasks (e.g. reset stats, change a default setting for all users, etc.). Should have super easy install, e.g. just drop (upload?) a file in a predefined directory.&lt;br /&gt;
* Migration from/to other systems is always a hot topic. How could we make that easier?&lt;br /&gt;
* Multi user blogs. Geeklog can handle blogs of several users, actually, if you give one topic to a user then it is almost unlimited. There are a few existing discussions on the forum and also feature requests concerning the improvement of user blogs. E.g. read only topics, using GL for a large site with many users. Basically it is a native function of GL but it need some improvement.&lt;br /&gt;
* New Calendar Plugin - Our current calendar plugin is, to say the least, lacking in lots of important features. Tries to enhance the calendar to add these features doesn't seem feasible from prior experience. A new calendar plugin could have the following features:&lt;br /&gt;
** Support for &amp;quot;site wide events&amp;quot;, &amp;quot;user events&amp;quot; and &amp;quot;group events&amp;quot;.&lt;br /&gt;
** Moderation for submission of site events. Ability to submit an existing &amp;quot;user event&amp;quot; as a site wide or group event.&lt;br /&gt;
** Ability to share personal calendars with other users.&lt;br /&gt;
** Ability to import, export and perhaps sync using the iCal format.&lt;br /&gt;
** Ability to create recurring events.&lt;br /&gt;
** Have an efficient implementation (especially important when implementing recurring events)&lt;br /&gt;
** Support for event reminders.&lt;br /&gt;
** Invitations and attendance tracking.&lt;br /&gt;
* Add shopping card and/or e-commerce functionality to Geeklog (in the form of a plugin). Using an existing open source shopping card or e-commerce web application would probably be a good idea, but the result should be fully integrated with Geeklog's security model.&lt;br /&gt;
&lt;br /&gt;
As we flesh out these ideas, they will be moved to their own pages and linked to from our [[Google Summer of Code|GSoC Start Page]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=GSoC_Brainstorming&amp;diff=5711</id>
		<title>GSoC Brainstorming</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=GSoC_Brainstorming&amp;diff=5711"/>
				<updated>2010-02-16T23:03:53Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: Added Calendar Plugin Suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These are new and not fully fleshed-out ideas for the [[Google Summer of Code]]. Contributions welcome!&lt;br /&gt;
&lt;br /&gt;
* Site Migration for PostgreSQL and/or MS SQL&lt;br /&gt;
* Database Migration: Switch from Postgres to MySQL or MS SQL or the other way around&lt;br /&gt;
* E-Mail Subsystem: Geeklog sometimes has to send out a lot of emails. Instead of sending them all at once (and running into timeouts), we could queue them and send them out in batches. This queue should allow for other job types as well.&lt;br /&gt;
* Facebook Connect: Allow users to login to a Geeklog site with their Facebook Account. Could become part of the [[SoC socialnetworking|Social Networking Features]] Project.&lt;br /&gt;
* Multi-site Setup: Run several websites off of one codebase. There's a [http://geeklog.fr//wiki/doku.php/hack:geeklog-multi-sites-1.5.0 hack] for that, but it's a pain for upgrades.&lt;br /&gt;
* Admin toolbox: A collection of mini-plugins for admin tasks (e.g. reset stats, change a default setting for all users, etc.). Should have super easy install, e.g. just drop (upload?) a file in a predefined directory.&lt;br /&gt;
* Migration from/to other systems is always a hot topic. How could we make that easier?&lt;br /&gt;
* Multi user blogs. Geeklog can handle blogs of several users, actually, if you give one topic to a user then it is almost unlimited. There are a few existing discussions on the forum and also feature requests concerning the improvement of user blogs. E.g. read only topics, using GL for a large site with many users. Basically it is a native function of GL but it need some improvement.&lt;br /&gt;
* New Calendar Plugin - Our current calendar plugin is, to say the least, lacking in lots of important features. Tries to enhance the calendar to add these features doesn't seem feasible from prior experience. A new calendar plugin could have the following features:&lt;br /&gt;
** Support for &amp;quot;site wide events&amp;quot;, &amp;quot;user events&amp;quot; and &amp;quot;group events&amp;quot;.&lt;br /&gt;
** Moderation for submission of site events. Ability to submit an existing &amp;quot;user event&amp;quot; as a site wide or group event.&lt;br /&gt;
** Ability to share personal calendars with other users.&lt;br /&gt;
** Ability to import, export and perhaps sync using the iCal format.&lt;br /&gt;
** Ability to create recurring events.&lt;br /&gt;
** Have an efficient implementation (especially important when implementing recurring events)&lt;br /&gt;
** Support for event reminders.&lt;br /&gt;
** Invitations and attendance tracking.&lt;br /&gt;
&lt;br /&gt;
As we flesh out these ideas, they will be moved to their own pages and linked to from our [[Google Summer of Code|GSoC Start Page]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]] [[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=5542</id>
		<title>CommentAlgorithm</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=5542"/>
				<updated>2009-07-23T22:36:15Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Representing Geeklog's Comments in the Database */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Representing Geeklog's Comments in the Database=&lt;br /&gt;
&lt;br /&gt;
Since Geeklog 1.3.10, Geeklog's comments have been stored in the database with columns (''lft'', ''rht'') representing a (modified) pre-order traversal ordering. This method of storage was chosen to improve comment retrieval performance, especially when viewing a subset of the comments for a given story.&lt;br /&gt;
&lt;br /&gt;
The idea behind pre-order traversal ordering, is that each node is ordered (or visited) before any of its children. In the modified preorder traversal algorithm implemented by Geeklog, the ''lft'' value of a comment is always less than the ''lft'' and ''rht'' values of all of the children of that node. Likewise the ''rht'' value of a node is always greater that the ''lft'' and ''rht'' values of all of the children of that node. (And trivially for any node, ''lft'' is always less than ''rht''.) A node without any children has the property ''rht'' is exactly one more than ''lft''. &lt;br /&gt;
&lt;br /&gt;
Example: Comment A is a top level comment to a story. Comments A-A and A-B are children of A and comments A-A-A, A-A-B, and A-A-C are children of A-A. The table below shows the values for each comment:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |comment&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |parent&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |lft&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |rht&lt;br /&gt;
|-&lt;br /&gt;
|A&lt;br /&gt;
|N/A&lt;br /&gt;
|1&lt;br /&gt;
|12&lt;br /&gt;
|-&lt;br /&gt;
|A-A&lt;br /&gt;
|A&lt;br /&gt;
|2&lt;br /&gt;
|9&lt;br /&gt;
|-&lt;br /&gt;
|A-B&lt;br /&gt;
|A&lt;br /&gt;
|10&lt;br /&gt;
|11&lt;br /&gt;
|-&lt;br /&gt;
|A-A-A&lt;br /&gt;
|A-A&lt;br /&gt;
|3&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|A-A-B&lt;br /&gt;
|A-A&lt;br /&gt;
|5&lt;br /&gt;
|6&lt;br /&gt;
|-&lt;br /&gt;
|A-A-C&lt;br /&gt;
|A-A&lt;br /&gt;
|7&lt;br /&gt;
|8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The resulting database structure has many advantages. Selecting a subtree from the database is as easy as specifying the ''lft'' and ''rht'' numbers of the root node of the subtree. For instance, to get the subtree with root comment &amp;quot;A-A&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt;= 2 AND rht &amp;lt;= 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or selecting all the children of a give node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt; 2 AND rht &amp;lt; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To select comments ordered for display in a &amp;quot;nested&amp;quot; format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments ORDER BY lft&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Storing the preorder traversal information also allows us to easily find the path to a node (i.e. a nodes parents, grandparents, etc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;lt; 7 AND rht &amp;gt; 8&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Counting the number of children of a comment is equally easy: &amp;lt;code&amp;gt;('rht' - 'lft' - 1)/2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Previously these operations required a (very slow) recursive algorithm. The way Geeklog had implemented this algorithm required one database query for every comment in the result set. Another way would have been to do one query to fetch all comments, and then use a recursive function to choose the desired comments. Both methods were extremely inefficient and caused load problems on frequently viewed Geeklog sites.&lt;br /&gt;
&lt;br /&gt;
The downside to this method is that inserting and deleting comments takes more work (three queries instead of one) and must be done in a single transaction (or a write lock on the table). Inserts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht + 2 WHERE rht &amp;gt;= comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft + 2 WHERE lft &amp;gt;= comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
INSERT INTO comments SET lft = comment.rht, rht = comment.rht + 1&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht - 2 WHERE rht &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft - 2 WHERE lft &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
DELETE FROM comments WHERE id = comment.id&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, since fetching (reading) comments is a much more frequent action then adding or deleting comments and the increase in efficiency for fetching comments is much greater than the loss of efficiency for adding and deleting comments, the trade off is worth while.&lt;br /&gt;
&lt;br /&gt;
Please note that in the SQL examples above, parts of the query were left out to make the algorithm more clear. For more detail, see the Geeklog source code (specifically lib-comment.php).&lt;br /&gt;
&lt;br /&gt;
Related Articles:&lt;br /&gt;
* [http://www.sitepoint.com/article/hierarchical-data-database/2/ Storing Hierarchical Data in a Database]&lt;br /&gt;
* [http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html Trees in SQL]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Tree_traversal Tree Traversal]&lt;br /&gt;
* [http://dev.mysql.com/tech-resources/articles/hierarchical-data.html Managing Hierarchical Data in MySQL]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=5541</id>
		<title>CommentAlgorithm</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=CommentAlgorithm&amp;diff=5541"/>
				<updated>2009-07-23T20:42:51Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: New page: =Representing Geeklog's Comments in the Database=  Since Geeklog 1.4.x, Geeklog's comments have been stored in the database with columns (''lft'', ''rht'') representing a (modified) pre-or...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Representing Geeklog's Comments in the Database=&lt;br /&gt;
&lt;br /&gt;
Since Geeklog 1.4.x, Geeklog's comments have been stored in the database with columns (''lft'', ''rht'') representing a (modified) pre-order traversal ordering. This method of storage was chosen to improve comment retrieval performance, especially when viewing a subset of the comments for a given story.&lt;br /&gt;
&lt;br /&gt;
The idea behind pre-order traversal ordering, is that each node is ordered (or visited) before any of its children. In the modified preorder traversal algorithm implemented by Geeklog, the ''lft'' value of a comment is always less than the ''lft'' and ''rht'' values of all of the children of that node. Likewise the ''rht'' value of a node is always greater that the ''lft'' and ''rht'' values of all of the children of that node. (And trivially for any node, ''lft'' is always less than ''rht''.) A node without any children has the property ''rht'' is exactly one more than ''lft''. &lt;br /&gt;
&lt;br /&gt;
Example: Comment A is a top level comment to a story. Comments A-A and A-B are children of A and comments A-A-A, A-A-B, and A-A-C are children of A-A. The table below shows the values for each comment:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |comment&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |parent&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |lft&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot; |rht&lt;br /&gt;
|-&lt;br /&gt;
|A&lt;br /&gt;
|N/A&lt;br /&gt;
|1&lt;br /&gt;
|12&lt;br /&gt;
|-&lt;br /&gt;
|A-A&lt;br /&gt;
|A&lt;br /&gt;
|2&lt;br /&gt;
|9&lt;br /&gt;
|-&lt;br /&gt;
|A-B&lt;br /&gt;
|A&lt;br /&gt;
|10&lt;br /&gt;
|11&lt;br /&gt;
|-&lt;br /&gt;
|A-A-A&lt;br /&gt;
|A-A&lt;br /&gt;
|3&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|A-A-B&lt;br /&gt;
|A-A&lt;br /&gt;
|5&lt;br /&gt;
|6&lt;br /&gt;
|-&lt;br /&gt;
|A-A-C&lt;br /&gt;
|A-A&lt;br /&gt;
|7&lt;br /&gt;
|8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The resulting database structure has many advantages. Selecting a subtree from the database is as easy as specifying the ''lft'' and ''rht'' numbers of the root node of the subtree. For instance, to get the subtree with root comment &amp;quot;A-A&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt;= 2 AND rht &amp;lt;= 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or selecting all the children of a give node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;gt; 2 AND rht &amp;lt; 9&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To select comments ordered for display in a &amp;quot;nested&amp;quot; format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments ORDER BY lft&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Storing the preorder traversal information also allows us to easily find the path to a node (i.e. a nodes parents, grandparents, etc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SELECT * FROM comments WHERE lft &amp;lt; 7 AND rht &amp;gt; 8&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Counting the number of children of a comment is equally easy: &amp;lt;code&amp;gt;('rht' - 'lft' - 1)/2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Previously these operations required a (very slow) recursive algorithm. The way Geeklog had implemented this algorithm required one database query for every comment in the result set. Another way would have been to do one query to fetch all comments, and then use a recursive function to choose the desired comments. Both methods were extremely inefficient and caused load problems on frequently viewed Geeklog sites.&lt;br /&gt;
&lt;br /&gt;
The downside to this method is that inserting and deleting comments takes more work (three queries instead of one) and must be done in a single transaction (or a write lock on the table). Inserts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht + 2 WHERE rht &amp;gt;= comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft + 2 WHERE lft &amp;gt;= comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
INSERT INTO comments SET lft = comment.rht, rht = comment.rht + 1&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;START TRANSACTION&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET rht = rht - 2 WHERE rht &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE comments SET lft = lft - 2 WHERE lft &amp;gt; comment.rht&amp;lt;br&amp;gt;&lt;br /&gt;
DELETE FROM comments WHERE id = comment.id&amp;lt;br&amp;gt;&lt;br /&gt;
COMMIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, since fetching (reading) comments is a much more frequent action then adding or deleting comments and the increase in efficiency for fetching comments is much greater than the loss of efficiency for adding and deleting comments, the trade off is worth while.&lt;br /&gt;
&lt;br /&gt;
Please note that in the SQL examples above, parts of the query were left out to make the algorithm more clear. For more detail, see the Geeklog source code (specifically lib-comment.php).&lt;br /&gt;
&lt;br /&gt;
Related Articles:&lt;br /&gt;
* [http://www.sitepoint.com/article/hierarchical-data-database/2/ Storing Hierarchical Data in a Database]&lt;br /&gt;
* [http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html Trees in SQL]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Tree_traversal Tree Traversal]&lt;br /&gt;
* [http://dev.mysql.com/tech-resources/articles/hierarchical-data.html Managing Hierarchical Data in MySQL]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Programmers/Developers_Documentation&amp;diff=5540</id>
		<title>Programmers/Developers Documentation</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Programmers/Developers_Documentation&amp;diff=5540"/>
				<updated>2009-07-23T19:39:44Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Development_Environment&amp;diff=4928</id>
		<title>Development Environment</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Development_Environment&amp;diff=4928"/>
				<updated>2009-04-27T20:33:36Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Getting things up and running */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= What is it? =&lt;br /&gt;
&lt;br /&gt;
We're providing a &amp;quot;ready to roll&amp;quot; development environment for Geeklog and AptitudeCMS in a VMware image that includes&lt;br /&gt;
&lt;br /&gt;
* Ubuntu Linux as the operation system&lt;br /&gt;
* Apache Web Server&lt;br /&gt;
* PHP&lt;br /&gt;
* MySQL&lt;br /&gt;
* Mercurial and Subversion&lt;br /&gt;
* checked-out repository for Geeklog&lt;br /&gt;
* pre-installed version of Geeklog&lt;br /&gt;
&lt;br /&gt;
We hope that in providing this environment, we make it easier for those interested in working on Geeklog and AptitudeCMS to start developing without having to install all the required tools first.&lt;br /&gt;
&lt;br /&gt;
= Getting things up and running =&lt;br /&gt;
&lt;br /&gt;
== Downloading the VM image ==&lt;br /&gt;
&lt;br /&gt;
The URL for the image will be provided on request (due to bandwidth limitations - it's about 1 GB). Requests for the URL can be sent to &amp;lt;contact-us AT lists DOT geeklog DOT net&amp;gt;. Download and unpack it using bzip2 and tar.&lt;br /&gt;
&lt;br /&gt;
== Get a Virtual Machine ==&lt;br /&gt;
&lt;br /&gt;
Most providers of virtual machine software provide a free version with minor (or no) limitations. Try one of these:&lt;br /&gt;
&lt;br /&gt;
* [http://www.virtualbox.org/ VirtualBox] from Sun, available for Linux, Solaris, Mac OS X, and Windows&lt;br /&gt;
* [http://www.vmware.com/products/player/ VMware Player] from VMware, available for Linux and Windows&lt;br /&gt;
* [http://www.vmware.com/products/server/ VMware Server] from VMware, available for Linux and Windows&lt;br /&gt;
&lt;br /&gt;
Follow the installation instructions for the software you chose. When asked for the image to use, select the &amp;quot;primaryMaster.vmdk&amp;quot; file from the GeeklogVM.tar.bz2 archive.&lt;br /&gt;
&lt;br /&gt;
= First Steps =&lt;br /&gt;
&lt;br /&gt;
''TBD''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Development_Environment&amp;diff=4919</id>
		<title>Development Environment</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Development_Environment&amp;diff=4919"/>
				<updated>2009-04-02T19:39:54Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: /* Get a Virtual Machine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= What is it? =&lt;br /&gt;
&lt;br /&gt;
We're providing a &amp;quot;ready to roll&amp;quot; development environment for Geeklog and AptitudeCMS in a VMware image that includes&lt;br /&gt;
&lt;br /&gt;
* Ubuntu Linux as the operation system&lt;br /&gt;
* Apache Web Server&lt;br /&gt;
* PHP&lt;br /&gt;
* MySQL&lt;br /&gt;
* Mercurial and Subversion&lt;br /&gt;
* checked-out repository for Geeklog&lt;br /&gt;
* pre-installed version of Geeklog&lt;br /&gt;
&lt;br /&gt;
We hope that in providing this environment, we make it easier for those interested in working on Geeklog and AptitudeCMS to start developing without having to install all the required tools first.&lt;br /&gt;
&lt;br /&gt;
= Getting things up and running =&lt;br /&gt;
&lt;br /&gt;
== Downloading the VM image ==&lt;br /&gt;
&lt;br /&gt;
The URL for the image will be provided on request (due to bandwidth limitations - it's about 1 GB). Download and unpack it using bzip2 and tar.&lt;br /&gt;
&lt;br /&gt;
== Get a Virtual Machine ==&lt;br /&gt;
&lt;br /&gt;
Most providers of virtual machine software provide a free version with minor (or no) limitations. Try one of these:&lt;br /&gt;
&lt;br /&gt;
* [http://www.virtualbox.org/ VirtualBox] from Sun, available for Linux, Solaris, Mac OS X, and Windows&lt;br /&gt;
* [http://www.vmware.com/products/player/ VMware Player] from VMware, available for Linux and Windows&lt;br /&gt;
* [http://www.vmware.com/products/server/ VMware Server] from VMware, available for Linux and Windows&lt;br /&gt;
&lt;br /&gt;
Follow the installation instructions for the software you chose. When asked for the image to use, select the &amp;quot;primaryMaster.vmdk&amp;quot; file from the GeeklogVM.tar.bz2 archive.&lt;br /&gt;
&lt;br /&gt;
= First Steps =&lt;br /&gt;
&lt;br /&gt;
''TBD''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	<entry>
		<id>http://gwiki3.thatlinuxbox.com/index.php?title=Development_Environment&amp;diff=4918</id>
		<title>Development Environment</title>
		<link rel="alternate" type="text/html" href="http://gwiki3.thatlinuxbox.com/index.php?title=Development_Environment&amp;diff=4918"/>
				<updated>2009-04-02T19:35:14Z</updated>
		
		<summary type="html">&lt;p&gt;Vinny: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= What is it? =&lt;br /&gt;
&lt;br /&gt;
We're providing a &amp;quot;ready to roll&amp;quot; development environment for Geeklog and AptitudeCMS in a VMware image that includes&lt;br /&gt;
&lt;br /&gt;
* Ubuntu Linux as the operation system&lt;br /&gt;
* Apache Web Server&lt;br /&gt;
* PHP&lt;br /&gt;
* MySQL&lt;br /&gt;
* Mercurial and Subversion&lt;br /&gt;
* checked-out repository for Geeklog&lt;br /&gt;
* pre-installed version of Geeklog&lt;br /&gt;
&lt;br /&gt;
We hope that in providing this environment, we make it easier for those interested in working on Geeklog and AptitudeCMS to start developing without having to install all the required tools first.&lt;br /&gt;
&lt;br /&gt;
= Getting things up and running =&lt;br /&gt;
&lt;br /&gt;
== Downloading the VM image ==&lt;br /&gt;
&lt;br /&gt;
The URL for the image will be provided on request (due to bandwidth limitations - it's about 1 GB). Download and unpack it using bzip2 and tar.&lt;br /&gt;
&lt;br /&gt;
== Get a Virtual Machine ==&lt;br /&gt;
&lt;br /&gt;
Most providers of virtual machine software provide a free version with minor (or no) limitations. Try one of these:&lt;br /&gt;
&lt;br /&gt;
* [http://www.virtualbox.org/ VirtualBox] from Sun, available for Linux, Solaris, Mac OS X, and Windows&lt;br /&gt;
* [http://www.vmware.com/products/player/ VMware player] from VMware, available for Linux and Windows&lt;br /&gt;
&lt;br /&gt;
Follow the installation instructions for the software you chose. When asked for the image to use, select the &amp;quot;primaryMaster.vmdk&amp;quot; file from the GeeklogVM.tar.bz2 archive.&lt;br /&gt;
&lt;br /&gt;
= First Steps =&lt;br /&gt;
&lt;br /&gt;
''TBD''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Vinny</name></author>	</entry>

	</feed>