<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://eden.sahanafoundation.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dominic</id>
	<title>Sahana Eden Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://eden.sahanafoundation.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dominic"/>
	<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/wiki/Special:Contributions/Dominic"/>
	<updated>2026-10-30T02:23:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=326</id>
		<title>Guidelines:Quality</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=326"/>
		<updated>2026-10-29T13:48:56Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Consistent */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard. &lt;br /&gt;
&lt;br /&gt;
Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an iterative approach of continuous quality improvement.&lt;br /&gt;
&lt;br /&gt;
In order to pass a level, all criteria of this level and all previous levels must be met.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|+ Quality Levels&lt;br /&gt;
|-&lt;br /&gt;
! Level !! Priority (MoSCoW) !! Key Attributes !! Description&lt;br /&gt;
|-&lt;br /&gt;
||0 - &#039;&#039;&#039;Experimental&#039;&#039;&#039;||-||-||any solution that does not (yet) meet all criteria of level 1&lt;br /&gt;
|-&lt;br /&gt;
||1 - &#039;&#039;&#039;Minimal&#039;&#039;&#039;||Must||[[#Valid| valid]], [[#Correct| correct]], [[#Safe| safe]]||minimum standard for any solution&lt;br /&gt;
|-&lt;br /&gt;
||2 - &#039;&#039;&#039;Appropriate&#039;&#039;&#039;||Should||[[#Usable| usable]], [[#Maintainable| maintainable]], [[#Secure| secure]]||minimum standard for production use&lt;br /&gt;
|-&lt;br /&gt;
||3 - &#039;&#039;&#039;Good&#039;&#039;&#039;||Can||[[#Consistent| consistent]], [[#Robust| robust]], [[#Configurable| configurable]]||long-term development goals&lt;br /&gt;
|-&lt;br /&gt;
||4 - &#039;&#039;&#039;Optimal&#039;&#039;&#039;||Want||[[#Efficient| efficient]], [[#Scalable| scalable]], [[#Interoperable| interoperable]]||optimization and enhancement goals&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level 1: Minimal ==&lt;br /&gt;
&lt;br /&gt;
=== Valid ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the right code&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The specified solution solves the targeted problem and meets the minimum functional requirements&lt;br /&gt;
* The required input data are available in the target scenario&lt;br /&gt;
* The user actions required to apply and/or use the solution or its responses are &#039;&#039;possible&#039;&#039; in the target scenario&lt;br /&gt;
* All dependencies of the feature set are resolvable, and hardware and infrastructure requirements can be met in the target scenario&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the code right&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Processing does not fail for any valid input data or user action.&lt;br /&gt;
* All responses are correct for the respective input data or user actions according to the specification&lt;br /&gt;
&lt;br /&gt;
=== Safe ===&lt;br /&gt;
&lt;br /&gt;
* The solution does not break other functionality of the application (except for functionality it replaces or supersedes)&lt;br /&gt;
* All processing always ends with a valid database status regardless whether it succeeds or fails&lt;br /&gt;
* All failed processes are effectively removed from the system and their transactions properly rolled back&lt;br /&gt;
* The solution effectively prevents uncontrolled indefinite object or process proliferation&lt;br /&gt;
* The solution always returns to a defined system status after a failure so that the application remains accessible&lt;br /&gt;
&lt;br /&gt;
== Level 2: Appropriate ==&lt;br /&gt;
&lt;br /&gt;
=== Usable ===&lt;br /&gt;
&lt;br /&gt;
* The solution &#039;&#039;can&#039;&#039; be used by the intended user group in the target scenario, i.e. the users can:&lt;br /&gt;
** discover and access the features&lt;br /&gt;
** understand and perform the required user actions&lt;br /&gt;
** understand and control the consequences of actions&lt;br /&gt;
** understand and provide the required type, quality and format of input data&lt;br /&gt;
** discover and access the results, and apply them to achieve their goals&lt;br /&gt;
&lt;br /&gt;
* Usability criteria apply analogously for back-end libraries and tools with developers in the role of the user&lt;br /&gt;
&lt;br /&gt;
=== Maintainable ===&lt;br /&gt;
&lt;br /&gt;
* All critical dependencies are obvious at their starting point&lt;br /&gt;
* All non-critical dependencies have meaningful fallbacks&lt;br /&gt;
* Processing failures produce useful and accessible feedback about the reasons&lt;br /&gt;
* The design of the solution does not obstruct diagnostics of defects&lt;br /&gt;
* The code is structured in a way that the processing flow can easily be determined from it&lt;br /&gt;
&lt;br /&gt;
=== Secure ===&lt;br /&gt;
&lt;br /&gt;
* The solution applies all relevant system configurations for authentication, authorization and accounting (AAA) appropriately and correctly.&lt;br /&gt;
* The solution does not allow the user to perform actions or initiate processes beyond the intended functionality.&lt;br /&gt;
&lt;br /&gt;
== Level 3: Good ==&lt;br /&gt;
&lt;br /&gt;
=== Consistent ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Maintaining Conceptual Integrity across the Application and beyond&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The solution applies the application framework appropriately and correctly&lt;br /&gt;
* The data structures defined in the solution are consistent with the global application data model&lt;br /&gt;
* The solution interoperates appropriately and correctly with other system components&lt;br /&gt;
* The solution applies the application&#039;s global design and style guidelines (both for code and interfaces)&lt;br /&gt;
* Where appropriate or required, the solution complies with specified standards (see [[#Standards| Standards]])&lt;br /&gt;
&lt;br /&gt;
=== Robust ===&lt;br /&gt;
&lt;br /&gt;
* The solution delivers consistent behavior, results and performance for all valid configurations&lt;br /&gt;
* The solution handles invalid input data, unexpected user actions and irregular system conditions appropriately and consistently for all valid configurations&lt;br /&gt;
* The solution detects invalid configurations and prevents any inadvertent effects that could result from them&lt;br /&gt;
&lt;br /&gt;
=== Configurable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can be easily and safely turned on and off without inadvertent side-effects (where appropriate, not for framework solutions)&lt;br /&gt;
* The solution applies global configuration settings correctly and consistently&lt;br /&gt;
* Processing parameters, behavior and/or appearance of the solution can be adapted to requirements variations using configuration patterns separate from its core code&lt;br /&gt;
&lt;br /&gt;
== Level 4: Optimal ==&lt;br /&gt;
&lt;br /&gt;
=== Efficient ===&lt;br /&gt;
&lt;br /&gt;
* The solution provides acceptable performance with the minimum available hardware/infrastructure resources in the target scenario&lt;br /&gt;
* The solution can be applied with minimal configuration effort&lt;br /&gt;
* The solution can be applied, developed and maintained with minimal learning effort&lt;br /&gt;
&lt;br /&gt;
=== Scalable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can handle/adapt to varying problem sizes (e.g. amount of data, frequency of events) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
* The solution can utilize hardware/infrastructure enhancements and/or concurrency to provide better performance&lt;br /&gt;
* The solution can be applied in any number of concurrent instances (given the appropriate hardware and infrastructure) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
&lt;br /&gt;
=== Interoperable ===&lt;br /&gt;
&lt;br /&gt;
* Different instances of the solution can, where appropriate or required, interchange data and/or process information&lt;br /&gt;
* The solution can, where appropriate or required, interchange data and/or process information with other relevant solutions in the target scenario&lt;br /&gt;
* The solution provides external APIs (application programming interfaces)&lt;br /&gt;
&lt;br /&gt;
= User Experience (UX) Requirements =&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Wikipedia: ISO 9241-210[1] defines user experience as &amp;quot;a person&#039;s perceptions and responses that result from the use or anticipated use of a product, system or service&amp;quot;. According to the ISO definition, user experience includes all the users&#039; emotions, beliefs, preferences, perceptions, physical and psychological responses, behaviors and accomplishments that occur before, during and after use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User experience, as a result of human-computer-interaction, involves various aspects of a software solution - both in view of its design, its functionality as well as its quality, but also personal aspects of the individual user (e.g. skills, previous experiences, cultural background), and of the situations and environments in which the software is to be used.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Good UX&amp;quot; is though not a requirement in itself - but the generic name for any additional design, functional and quality requirements in view of human-computer-interaction that may be defined for a solution, and which must be met in order to achieve certain quality levels.&lt;br /&gt;
&lt;br /&gt;
Even though UX as such appears to be a largely subjective matter, there are usually a number of generalizable UX requirements for any user interface.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Example:&#039;&#039;&#039; &#039;&#039;User interfaces which are typically used in the darkness should not blind the user, but use a reduced palette of primarily reddish colors on dark background in order to cause less or no iris contraction. If the interface is though to be used under varying lighting conditions it should be adaptable (or even auto-adapt).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In order to be &#039;&#039;&#039;valid and accomplishable, UX requirements must be specific and clearly defined&#039;&#039;&#039; (like the above example) for the quality level for which they shall apply - even when their reasoning may be more complex sometimes.&lt;br /&gt;
&lt;br /&gt;
Some general quality requirements also influence the user experience (e.g. correctness, usability, efficiency), but are not specific for the use-case and therefore usually not separately discussed as UX requirements. They are however relevant for UX evaluations and should thus be taken into account in such analyses.&lt;br /&gt;
&lt;br /&gt;
= Advanced Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Advanced&#039;&#039; quality criteria can be used to compare different solutions, or to define quality roadmaps for particular feature sets beyond the standard criteria.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not apply equally for all use-cases - in certain cases they may even constitute anti-patterns.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not enhance the general quality level of a solution: a level-3 solution is still of better quality than a level-2 solution - regardless how many advanced criteria the level-2 solution meets.&lt;br /&gt;
&lt;br /&gt;
== Stability ==&lt;br /&gt;
&lt;br /&gt;
A solution is &#039;&#039;stable&#039;&#039; when its black-box model rarely changes, and it maintains backwards-compatibility and/or easy migration paths. Stable solutions are required for all critical dependencies, so that they can be built upon without risk for frequent regression issues or need for constant migration. Stability is especially critical in shared data models (i.e. where data are shared between different modules within the application or even across applications), and in authorization frameworks - and can thus be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Stability is typically perceived as a sign of maturity, but can actually be taken into account already during the initial solution design. Pragmatic approaches (e.g. integrated migration, or enforced backwards-compatibility) can create stability early on without limiting or obstructing further development.&lt;br /&gt;
&lt;br /&gt;
== Generalization ==&lt;br /&gt;
&lt;br /&gt;
Generalizable solutions are designed and/or implemented in a way that they can be generalized. Typically, they separate their core patterns/algorithms from the use-case specifics through parametrization and/or configuration patterns. This can be defined as an advanced quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Generalization means to modify and/or extend the core patterns/algorithms of the solution in a way that they can be re-used in other solutions which involve the same or similar functional requirements, thereby reducing future development efforts. There is a wide range of quality attributes - &amp;quot;flexible&amp;quot;, &amp;quot;customizable&amp;quot;, &amp;quot;re-usable&amp;quot;, &amp;quot;extensible&amp;quot;, just to name a few - all of which involve different degrees of and approaches to generalization.&lt;br /&gt;
&lt;br /&gt;
= Standards =&lt;br /&gt;
&lt;br /&gt;
Solutions can both define or implement standards (e.g. data standards, communication protocols, taxonomies). Standard compliance can be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Standards can define additional requirements beyond the immediate requirements of the targeted problem, which must however be met in order to comply with the standard. Such additional standard requirements would usually be seen as quality requirements under [[#Consistent| &amp;quot;Consistency&amp;quot;]] in level 3.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Index&amp;diff=325</id>
		<title>Guidelines:Index</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Index&amp;diff=325"/>
		<updated>2026-10-29T13:39:29Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Contributor Guidelines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Implementer Guidelines ==&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Contributor Guidelines ==&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
* [[Guidelines:CodingStyle|Coding Conventions]]&lt;br /&gt;
* [[Guidelines:Quality|Solution Quality Evaluation Guideline]]&lt;br /&gt;
* [[Guidelines:AI|Guideline for Responsible AI Contributions]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=324</id>
		<title>Guidelines:Quality</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=324"/>
		<updated>2026-10-29T13:37:35Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* General Quality Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard. &lt;br /&gt;
&lt;br /&gt;
Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an iterative approach of continuous quality improvement.&lt;br /&gt;
&lt;br /&gt;
In order to pass a level, all criteria of this level and all previous levels must be met.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|+ Quality Levels&lt;br /&gt;
|-&lt;br /&gt;
! Level !! Priority (MoSCoW) !! Key Attributes !! Description&lt;br /&gt;
|-&lt;br /&gt;
||0 - &#039;&#039;&#039;Experimental&#039;&#039;&#039;||-||-||any solution that does not (yet) meet all criteria of level 1&lt;br /&gt;
|-&lt;br /&gt;
||1 - &#039;&#039;&#039;Minimal&#039;&#039;&#039;||Must||[[#Valid| valid]], [[#Correct| correct]], [[#Safe| safe]]||minimum standard for any solution&lt;br /&gt;
|-&lt;br /&gt;
||2 - &#039;&#039;&#039;Appropriate&#039;&#039;&#039;||Should||[[#Usable| usable]], [[#Maintainable| maintainable]], [[#Secure| secure]]||minimum standard for production use&lt;br /&gt;
|-&lt;br /&gt;
||3 - &#039;&#039;&#039;Good&#039;&#039;&#039;||Can||[[#Consistent| consistent]], [[#Robust| robust]], [[#Configurable| configurable]]||long-term development goals&lt;br /&gt;
|-&lt;br /&gt;
||4 - &#039;&#039;&#039;Optimal&#039;&#039;&#039;||Want||[[#Efficient| efficient]], [[#Scalable| scalable]], [[#Interoperable| interoperable]]||optimization and enhancement goals&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level 1: Minimal ==&lt;br /&gt;
&lt;br /&gt;
=== Valid ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the right code&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The specified solution solves the targeted problem and meets the minimum functional requirements&lt;br /&gt;
* The required input data are available in the target scenario&lt;br /&gt;
* The user actions required to apply and/or use the solution or its responses are &#039;&#039;possible&#039;&#039; in the target scenario&lt;br /&gt;
* All dependencies of the feature set are resolvable, and hardware and infrastructure requirements can be met in the target scenario&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the code right&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Processing does not fail for any valid input data or user action.&lt;br /&gt;
* All responses are correct for the respective input data or user actions according to the specification&lt;br /&gt;
&lt;br /&gt;
=== Safe ===&lt;br /&gt;
&lt;br /&gt;
* The solution does not break other functionality of the application (except for functionality it replaces or supersedes)&lt;br /&gt;
* All processing always ends with a valid database status regardless whether it succeeds or fails&lt;br /&gt;
* All failed processes are effectively removed from the system and their transactions properly rolled back&lt;br /&gt;
* The solution effectively prevents uncontrolled indefinite object or process proliferation&lt;br /&gt;
* The solution always returns to a defined system status after a failure so that the application remains accessible&lt;br /&gt;
&lt;br /&gt;
== Level 2: Appropriate ==&lt;br /&gt;
&lt;br /&gt;
=== Usable ===&lt;br /&gt;
&lt;br /&gt;
* The solution &#039;&#039;can&#039;&#039; be used by the intended user group in the target scenario, i.e. the users can:&lt;br /&gt;
** discover and access the features&lt;br /&gt;
** understand and perform the required user actions&lt;br /&gt;
** understand and control the consequences of actions&lt;br /&gt;
** understand and provide the required type, quality and format of input data&lt;br /&gt;
** discover and access the results, and apply them to achieve their goals&lt;br /&gt;
&lt;br /&gt;
* Usability criteria apply analogously for back-end libraries and tools with developers in the role of the user&lt;br /&gt;
&lt;br /&gt;
=== Maintainable ===&lt;br /&gt;
&lt;br /&gt;
* All critical dependencies are obvious at their starting point&lt;br /&gt;
* All non-critical dependencies have meaningful fallbacks&lt;br /&gt;
* Processing failures produce useful and accessible feedback about the reasons&lt;br /&gt;
* The design of the solution does not obstruct diagnostics of defects&lt;br /&gt;
* The code is structured in a way that the processing flow can easily be determined from it&lt;br /&gt;
&lt;br /&gt;
=== Secure ===&lt;br /&gt;
&lt;br /&gt;
* The solution applies all relevant system configurations for authentication, authorization and accounting (AAA) appropriately and correctly.&lt;br /&gt;
* The solution does not allow the user to perform actions or initiate processes beyond the intended functionality.&lt;br /&gt;
&lt;br /&gt;
== Level 3: Good ==&lt;br /&gt;
&lt;br /&gt;
=== Consistent ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Maintaining Conceptual Integrity across the Application and beyond&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The solution applies the application framework appropriately and correctly&lt;br /&gt;
* The data structures defined in the solution are consistent with the global application data model&lt;br /&gt;
* The solution interoperates appropriately and correctly with other system components&lt;br /&gt;
* The solution applies the application&#039;s global design and style guidelines (both for code and interfaces)&lt;br /&gt;
* Where appropriate or required, the solution complies with specified standards (see [#Standards Standards])&lt;br /&gt;
&lt;br /&gt;
=== Robust ===&lt;br /&gt;
&lt;br /&gt;
* The solution delivers consistent behavior, results and performance for all valid configurations&lt;br /&gt;
* The solution handles invalid input data, unexpected user actions and irregular system conditions appropriately and consistently for all valid configurations&lt;br /&gt;
* The solution detects invalid configurations and prevents any inadvertent effects that could result from them&lt;br /&gt;
&lt;br /&gt;
=== Configurable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can be easily and safely turned on and off without inadvertent side-effects (where appropriate, not for framework solutions)&lt;br /&gt;
* The solution applies global configuration settings correctly and consistently&lt;br /&gt;
* Processing parameters, behavior and/or appearance of the solution can be adapted to requirements variations using configuration patterns separate from its core code&lt;br /&gt;
&lt;br /&gt;
== Level 4: Optimal ==&lt;br /&gt;
&lt;br /&gt;
=== Efficient ===&lt;br /&gt;
&lt;br /&gt;
* The solution provides acceptable performance with the minimum available hardware/infrastructure resources in the target scenario&lt;br /&gt;
* The solution can be applied with minimal configuration effort&lt;br /&gt;
* The solution can be applied, developed and maintained with minimal learning effort&lt;br /&gt;
&lt;br /&gt;
=== Scalable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can handle/adapt to varying problem sizes (e.g. amount of data, frequency of events) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
* The solution can utilize hardware/infrastructure enhancements and/or concurrency to provide better performance&lt;br /&gt;
* The solution can be applied in any number of concurrent instances (given the appropriate hardware and infrastructure) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
&lt;br /&gt;
=== Interoperable ===&lt;br /&gt;
&lt;br /&gt;
* Different instances of the solution can, where appropriate or required, interchange data and/or process information&lt;br /&gt;
* The solution can, where appropriate or required, interchange data and/or process information with other relevant solutions in the target scenario&lt;br /&gt;
* The solution provides external APIs (application programming interfaces)&lt;br /&gt;
&lt;br /&gt;
= User Experience (UX) Requirements =&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Wikipedia: ISO 9241-210[1] defines user experience as &amp;quot;a person&#039;s perceptions and responses that result from the use or anticipated use of a product, system or service&amp;quot;. According to the ISO definition, user experience includes all the users&#039; emotions, beliefs, preferences, perceptions, physical and psychological responses, behaviors and accomplishments that occur before, during and after use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User experience, as a result of human-computer-interaction, involves various aspects of a software solution - both in view of its design, its functionality as well as its quality, but also personal aspects of the individual user (e.g. skills, previous experiences, cultural background), and of the situations and environments in which the software is to be used.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Good UX&amp;quot; is though not a requirement in itself - but the generic name for any additional design, functional and quality requirements in view of human-computer-interaction that may be defined for a solution, and which must be met in order to achieve certain quality levels.&lt;br /&gt;
&lt;br /&gt;
Even though UX as such appears to be a largely subjective matter, there are usually a number of generalizable UX requirements for any user interface.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Example:&#039;&#039;&#039; &#039;&#039;User interfaces which are typically used in the darkness should not blind the user, but use a reduced palette of primarily reddish colors on dark background in order to cause less or no iris contraction. If the interface is though to be used under varying lighting conditions it should be adaptable (or even auto-adapt).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In order to be &#039;&#039;&#039;valid and accomplishable, UX requirements must be specific and clearly defined&#039;&#039;&#039; (like the above example) for the quality level for which they shall apply - even when their reasoning may be more complex sometimes.&lt;br /&gt;
&lt;br /&gt;
Some general quality requirements also influence the user experience (e.g. correctness, usability, efficiency), but are not specific for the use-case and therefore usually not separately discussed as UX requirements. They are however relevant for UX evaluations and should thus be taken into account in such analyses.&lt;br /&gt;
&lt;br /&gt;
= Advanced Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Advanced&#039;&#039; quality criteria can be used to compare different solutions, or to define quality roadmaps for particular feature sets beyond the standard criteria.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not apply equally for all use-cases - in certain cases they may even constitute anti-patterns.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not enhance the general quality level of a solution: a level-3 solution is still of better quality than a level-2 solution - regardless how many advanced criteria the level-2 solution meets.&lt;br /&gt;
&lt;br /&gt;
== Stability ==&lt;br /&gt;
&lt;br /&gt;
A solution is &#039;&#039;stable&#039;&#039; when its black-box model rarely changes, and it maintains backwards-compatibility and/or easy migration paths. Stable solutions are required for all critical dependencies, so that they can be built upon without risk for frequent regression issues or need for constant migration. Stability is especially critical in shared data models (i.e. where data are shared between different modules within the application or even across applications), and in authorization frameworks - and can thus be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Stability is typically perceived as a sign of maturity, but can actually be taken into account already during the initial solution design. Pragmatic approaches (e.g. integrated migration, or enforced backwards-compatibility) can create stability early on without limiting or obstructing further development.&lt;br /&gt;
&lt;br /&gt;
== Generalization ==&lt;br /&gt;
&lt;br /&gt;
Generalizable solutions are designed and/or implemented in a way that they can be generalized. Typically, they separate their core patterns/algorithms from the use-case specifics through parametrization and/or configuration patterns. This can be defined as an advanced quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Generalization means to modify and/or extend the core patterns/algorithms of the solution in a way that they can be re-used in other solutions which involve the same or similar functional requirements, thereby reducing future development efforts. There is a wide range of quality attributes - &amp;quot;flexible&amp;quot;, &amp;quot;customizable&amp;quot;, &amp;quot;re-usable&amp;quot;, &amp;quot;extensible&amp;quot;, just to name a few - all of which involve different degrees of and approaches to generalization.&lt;br /&gt;
&lt;br /&gt;
= Standards =&lt;br /&gt;
&lt;br /&gt;
Solutions can both define or implement standards (e.g. data standards, communication protocols, taxonomies). Standard compliance can be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Standards can define additional requirements beyond the immediate requirements of the targeted problem, which must however be met in order to comply with the standard. Such additional standard requirements would usually be seen as quality requirements under [[#Consistent| &amp;quot;Consistency&amp;quot;]] in level 3.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=323</id>
		<title>Guidelines:Quality</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=323"/>
		<updated>2026-10-29T13:37:11Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard. &lt;br /&gt;
&lt;br /&gt;
Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an iterative approach of continuous quality improvement.&lt;br /&gt;
&lt;br /&gt;
In order to pass a level, all criteria of this level and all previous levels must be met.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|+ Quality Levels&lt;br /&gt;
|-&lt;br /&gt;
! Level !! Priority (MoSCoW) !! Key Attributes !! Description&lt;br /&gt;
|-&lt;br /&gt;
||0 - &#039;&#039;&#039;Experimental&#039;&#039;&#039;||-||-||any solution that does not (yet) meet all criteria of level 1||&lt;br /&gt;
|-&lt;br /&gt;
||1 - &#039;&#039;&#039;Minimal&#039;&#039;&#039;||Must||[[#Valid| valid]], [[#Correct| correct]], [[#Safe| safe]]||minimum standard for any solution||&lt;br /&gt;
|-&lt;br /&gt;
||2 - &#039;&#039;&#039;Appropriate&#039;&#039;&#039;||Should||[[#Usable| usable]], [[#Maintainable| maintainable]], [[#Secure| secure]]||minimum standard for production use||&lt;br /&gt;
|-&lt;br /&gt;
||3 - &#039;&#039;&#039;Good&#039;&#039;&#039;||Can||[[#Consistent| consistent]], [[#Robust| robust]], [[#Configurable| configurable]]||long-term development goals||&lt;br /&gt;
|-&lt;br /&gt;
||4 - &#039;&#039;&#039;Optimal&#039;&#039;&#039;||Want||[[#Efficient| efficient]], [[#Scalable| scalable]], [[#Interoperable| interoperable]]||optimization and enhancement goals||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level 1: Minimal ==&lt;br /&gt;
&lt;br /&gt;
=== Valid ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the right code&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The specified solution solves the targeted problem and meets the minimum functional requirements&lt;br /&gt;
* The required input data are available in the target scenario&lt;br /&gt;
* The user actions required to apply and/or use the solution or its responses are &#039;&#039;possible&#039;&#039; in the target scenario&lt;br /&gt;
* All dependencies of the feature set are resolvable, and hardware and infrastructure requirements can be met in the target scenario&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the code right&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Processing does not fail for any valid input data or user action.&lt;br /&gt;
* All responses are correct for the respective input data or user actions according to the specification&lt;br /&gt;
&lt;br /&gt;
=== Safe ===&lt;br /&gt;
&lt;br /&gt;
* The solution does not break other functionality of the application (except for functionality it replaces or supersedes)&lt;br /&gt;
* All processing always ends with a valid database status regardless whether it succeeds or fails&lt;br /&gt;
* All failed processes are effectively removed from the system and their transactions properly rolled back&lt;br /&gt;
* The solution effectively prevents uncontrolled indefinite object or process proliferation&lt;br /&gt;
* The solution always returns to a defined system status after a failure so that the application remains accessible&lt;br /&gt;
&lt;br /&gt;
== Level 2: Appropriate ==&lt;br /&gt;
&lt;br /&gt;
=== Usable ===&lt;br /&gt;
&lt;br /&gt;
* The solution &#039;&#039;can&#039;&#039; be used by the intended user group in the target scenario, i.e. the users can:&lt;br /&gt;
** discover and access the features&lt;br /&gt;
** understand and perform the required user actions&lt;br /&gt;
** understand and control the consequences of actions&lt;br /&gt;
** understand and provide the required type, quality and format of input data&lt;br /&gt;
** discover and access the results, and apply them to achieve their goals&lt;br /&gt;
&lt;br /&gt;
* Usability criteria apply analogously for back-end libraries and tools with developers in the role of the user&lt;br /&gt;
&lt;br /&gt;
=== Maintainable ===&lt;br /&gt;
&lt;br /&gt;
* All critical dependencies are obvious at their starting point&lt;br /&gt;
* All non-critical dependencies have meaningful fallbacks&lt;br /&gt;
* Processing failures produce useful and accessible feedback about the reasons&lt;br /&gt;
* The design of the solution does not obstruct diagnostics of defects&lt;br /&gt;
* The code is structured in a way that the processing flow can easily be determined from it&lt;br /&gt;
&lt;br /&gt;
=== Secure ===&lt;br /&gt;
&lt;br /&gt;
* The solution applies all relevant system configurations for authentication, authorization and accounting (AAA) appropriately and correctly.&lt;br /&gt;
* The solution does not allow the user to perform actions or initiate processes beyond the intended functionality.&lt;br /&gt;
&lt;br /&gt;
== Level 3: Good ==&lt;br /&gt;
&lt;br /&gt;
=== Consistent ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Maintaining Conceptual Integrity across the Application and beyond&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The solution applies the application framework appropriately and correctly&lt;br /&gt;
* The data structures defined in the solution are consistent with the global application data model&lt;br /&gt;
* The solution interoperates appropriately and correctly with other system components&lt;br /&gt;
* The solution applies the application&#039;s global design and style guidelines (both for code and interfaces)&lt;br /&gt;
* Where appropriate or required, the solution complies with specified standards (see [#Standards Standards])&lt;br /&gt;
&lt;br /&gt;
=== Robust ===&lt;br /&gt;
&lt;br /&gt;
* The solution delivers consistent behavior, results and performance for all valid configurations&lt;br /&gt;
* The solution handles invalid input data, unexpected user actions and irregular system conditions appropriately and consistently for all valid configurations&lt;br /&gt;
* The solution detects invalid configurations and prevents any inadvertent effects that could result from them&lt;br /&gt;
&lt;br /&gt;
=== Configurable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can be easily and safely turned on and off without inadvertent side-effects (where appropriate, not for framework solutions)&lt;br /&gt;
* The solution applies global configuration settings correctly and consistently&lt;br /&gt;
* Processing parameters, behavior and/or appearance of the solution can be adapted to requirements variations using configuration patterns separate from its core code&lt;br /&gt;
&lt;br /&gt;
== Level 4: Optimal ==&lt;br /&gt;
&lt;br /&gt;
=== Efficient ===&lt;br /&gt;
&lt;br /&gt;
* The solution provides acceptable performance with the minimum available hardware/infrastructure resources in the target scenario&lt;br /&gt;
* The solution can be applied with minimal configuration effort&lt;br /&gt;
* The solution can be applied, developed and maintained with minimal learning effort&lt;br /&gt;
&lt;br /&gt;
=== Scalable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can handle/adapt to varying problem sizes (e.g. amount of data, frequency of events) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
* The solution can utilize hardware/infrastructure enhancements and/or concurrency to provide better performance&lt;br /&gt;
* The solution can be applied in any number of concurrent instances (given the appropriate hardware and infrastructure) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
&lt;br /&gt;
=== Interoperable ===&lt;br /&gt;
&lt;br /&gt;
* Different instances of the solution can, where appropriate or required, interchange data and/or process information&lt;br /&gt;
* The solution can, where appropriate or required, interchange data and/or process information with other relevant solutions in the target scenario&lt;br /&gt;
* The solution provides external APIs (application programming interfaces)&lt;br /&gt;
&lt;br /&gt;
= User Experience (UX) Requirements =&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Wikipedia: ISO 9241-210[1] defines user experience as &amp;quot;a person&#039;s perceptions and responses that result from the use or anticipated use of a product, system or service&amp;quot;. According to the ISO definition, user experience includes all the users&#039; emotions, beliefs, preferences, perceptions, physical and psychological responses, behaviors and accomplishments that occur before, during and after use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User experience, as a result of human-computer-interaction, involves various aspects of a software solution - both in view of its design, its functionality as well as its quality, but also personal aspects of the individual user (e.g. skills, previous experiences, cultural background), and of the situations and environments in which the software is to be used.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Good UX&amp;quot; is though not a requirement in itself - but the generic name for any additional design, functional and quality requirements in view of human-computer-interaction that may be defined for a solution, and which must be met in order to achieve certain quality levels.&lt;br /&gt;
&lt;br /&gt;
Even though UX as such appears to be a largely subjective matter, there are usually a number of generalizable UX requirements for any user interface.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Example:&#039;&#039;&#039; &#039;&#039;User interfaces which are typically used in the darkness should not blind the user, but use a reduced palette of primarily reddish colors on dark background in order to cause less or no iris contraction. If the interface is though to be used under varying lighting conditions it should be adaptable (or even auto-adapt).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In order to be &#039;&#039;&#039;valid and accomplishable, UX requirements must be specific and clearly defined&#039;&#039;&#039; (like the above example) for the quality level for which they shall apply - even when their reasoning may be more complex sometimes.&lt;br /&gt;
&lt;br /&gt;
Some general quality requirements also influence the user experience (e.g. correctness, usability, efficiency), but are not specific for the use-case and therefore usually not separately discussed as UX requirements. They are however relevant for UX evaluations and should thus be taken into account in such analyses.&lt;br /&gt;
&lt;br /&gt;
= Advanced Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Advanced&#039;&#039; quality criteria can be used to compare different solutions, or to define quality roadmaps for particular feature sets beyond the standard criteria.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not apply equally for all use-cases - in certain cases they may even constitute anti-patterns.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not enhance the general quality level of a solution: a level-3 solution is still of better quality than a level-2 solution - regardless how many advanced criteria the level-2 solution meets.&lt;br /&gt;
&lt;br /&gt;
== Stability ==&lt;br /&gt;
&lt;br /&gt;
A solution is &#039;&#039;stable&#039;&#039; when its black-box model rarely changes, and it maintains backwards-compatibility and/or easy migration paths. Stable solutions are required for all critical dependencies, so that they can be built upon without risk for frequent regression issues or need for constant migration. Stability is especially critical in shared data models (i.e. where data are shared between different modules within the application or even across applications), and in authorization frameworks - and can thus be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Stability is typically perceived as a sign of maturity, but can actually be taken into account already during the initial solution design. Pragmatic approaches (e.g. integrated migration, or enforced backwards-compatibility) can create stability early on without limiting or obstructing further development.&lt;br /&gt;
&lt;br /&gt;
== Generalization ==&lt;br /&gt;
&lt;br /&gt;
Generalizable solutions are designed and/or implemented in a way that they can be generalized. Typically, they separate their core patterns/algorithms from the use-case specifics through parametrization and/or configuration patterns. This can be defined as an advanced quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Generalization means to modify and/or extend the core patterns/algorithms of the solution in a way that they can be re-used in other solutions which involve the same or similar functional requirements, thereby reducing future development efforts. There is a wide range of quality attributes - &amp;quot;flexible&amp;quot;, &amp;quot;customizable&amp;quot;, &amp;quot;re-usable&amp;quot;, &amp;quot;extensible&amp;quot;, just to name a few - all of which involve different degrees of and approaches to generalization.&lt;br /&gt;
&lt;br /&gt;
= Standards =&lt;br /&gt;
&lt;br /&gt;
Solutions can both define or implement standards (e.g. data standards, communication protocols, taxonomies). Standard compliance can be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Standards can define additional requirements beyond the immediate requirements of the targeted problem, which must however be met in order to comply with the standard. Such additional standard requirements would usually be seen as quality requirements under [[#Consistent| &amp;quot;Consistency&amp;quot;]] in level 3.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=322</id>
		<title>Guidelines:Quality</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=322"/>
		<updated>2026-10-29T13:36:55Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
This guideline outlines criteria to evaluate the quality of a feature set or other solution detail, and can be used both to determine the current quality level and to set future development goals.&lt;br /&gt;
&lt;br /&gt;
= General Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard. &lt;br /&gt;
&lt;br /&gt;
Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an iterative approach of continuous quality improvement.&lt;br /&gt;
&lt;br /&gt;
In order to pass a level, all criteria of this level and all previous levels must be met.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|+ Quality Levels&lt;br /&gt;
|-&lt;br /&gt;
! Level !! Priority (MoSCoW) !! Key Attributes !! Description&lt;br /&gt;
|-&lt;br /&gt;
||0 - &#039;&#039;&#039;Experimental&#039;&#039;&#039;||-||-||any solution that does not (yet) meet all criteria of level 1||&lt;br /&gt;
|-&lt;br /&gt;
||1 - &#039;&#039;&#039;Minimal&#039;&#039;&#039;||Must||[[#Valid| valid]], [[#Correct| correct]], [[#Safe| safe]]||minimum standard for any solution||&lt;br /&gt;
|-&lt;br /&gt;
||2 - &#039;&#039;&#039;Appropriate&#039;&#039;&#039;||Should||[[#Usable| usable]], [[#Maintainable| maintainable]], [[#Secure| secure]]||minimum standard for production use||&lt;br /&gt;
|-&lt;br /&gt;
||3 - &#039;&#039;&#039;Good&#039;&#039;&#039;||Can||[[#Consistent| consistent]], [[#Robust| robust]], [[#Configurable| configurable]]||long-term development goals||&lt;br /&gt;
|-&lt;br /&gt;
||4 - &#039;&#039;&#039;Optimal&#039;&#039;&#039;||Want||[[#Efficient| efficient]], [[#Scalable| scalable]], [[#Interoperable| interoperable]]||optimization and enhancement goals||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Level 1: Minimal ==&lt;br /&gt;
&lt;br /&gt;
=== Valid ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the right code&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The specified solution solves the targeted problem and meets the minimum functional requirements&lt;br /&gt;
* The required input data are available in the target scenario&lt;br /&gt;
* The user actions required to apply and/or use the solution or its responses are &#039;&#039;possible&#039;&#039; in the target scenario&lt;br /&gt;
* All dependencies of the feature set are resolvable, and hardware and infrastructure requirements can be met in the target scenario&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the code right&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Processing does not fail for any valid input data or user action.&lt;br /&gt;
* All responses are correct for the respective input data or user actions according to the specification&lt;br /&gt;
&lt;br /&gt;
=== Safe ===&lt;br /&gt;
&lt;br /&gt;
* The solution does not break other functionality of the application (except for functionality it replaces or supersedes)&lt;br /&gt;
* All processing always ends with a valid database status regardless whether it succeeds or fails&lt;br /&gt;
* All failed processes are effectively removed from the system and their transactions properly rolled back&lt;br /&gt;
* The solution effectively prevents uncontrolled indefinite object or process proliferation&lt;br /&gt;
* The solution always returns to a defined system status after a failure so that the application remains accessible&lt;br /&gt;
&lt;br /&gt;
== Level 2: Appropriate ==&lt;br /&gt;
&lt;br /&gt;
=== Usable ===&lt;br /&gt;
&lt;br /&gt;
* The solution &#039;&#039;can&#039;&#039; be used by the intended user group in the target scenario, i.e. the users can:&lt;br /&gt;
** discover and access the features&lt;br /&gt;
** understand and perform the required user actions&lt;br /&gt;
** understand and control the consequences of actions&lt;br /&gt;
** understand and provide the required type, quality and format of input data&lt;br /&gt;
** discover and access the results, and apply them to achieve their goals&lt;br /&gt;
&lt;br /&gt;
* Usability criteria apply analogously for back-end libraries and tools with developers in the role of the user&lt;br /&gt;
&lt;br /&gt;
=== Maintainable ===&lt;br /&gt;
&lt;br /&gt;
* All critical dependencies are obvious at their starting point&lt;br /&gt;
* All non-critical dependencies have meaningful fallbacks&lt;br /&gt;
* Processing failures produce useful and accessible feedback about the reasons&lt;br /&gt;
* The design of the solution does not obstruct diagnostics of defects&lt;br /&gt;
* The code is structured in a way that the processing flow can easily be determined from it&lt;br /&gt;
&lt;br /&gt;
=== Secure ===&lt;br /&gt;
&lt;br /&gt;
* The solution applies all relevant system configurations for authentication, authorization and accounting (AAA) appropriately and correctly.&lt;br /&gt;
* The solution does not allow the user to perform actions or initiate processes beyond the intended functionality.&lt;br /&gt;
&lt;br /&gt;
== Level 3: Good ==&lt;br /&gt;
&lt;br /&gt;
=== Consistent ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Maintaining Conceptual Integrity across the Application and beyond&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The solution applies the application framework appropriately and correctly&lt;br /&gt;
* The data structures defined in the solution are consistent with the global application data model&lt;br /&gt;
* The solution interoperates appropriately and correctly with other system components&lt;br /&gt;
* The solution applies the application&#039;s global design and style guidelines (both for code and interfaces)&lt;br /&gt;
* Where appropriate or required, the solution complies with specified standards (see [#Standards Standards])&lt;br /&gt;
&lt;br /&gt;
=== Robust ===&lt;br /&gt;
&lt;br /&gt;
* The solution delivers consistent behavior, results and performance for all valid configurations&lt;br /&gt;
* The solution handles invalid input data, unexpected user actions and irregular system conditions appropriately and consistently for all valid configurations&lt;br /&gt;
* The solution detects invalid configurations and prevents any inadvertent effects that could result from them&lt;br /&gt;
&lt;br /&gt;
=== Configurable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can be easily and safely turned on and off without inadvertent side-effects (where appropriate, not for framework solutions)&lt;br /&gt;
* The solution applies global configuration settings correctly and consistently&lt;br /&gt;
* Processing parameters, behavior and/or appearance of the solution can be adapted to requirements variations using configuration patterns separate from its core code&lt;br /&gt;
&lt;br /&gt;
== Level 4: Optimal ==&lt;br /&gt;
&lt;br /&gt;
=== Efficient ===&lt;br /&gt;
&lt;br /&gt;
* The solution provides acceptable performance with the minimum available hardware/infrastructure resources in the target scenario&lt;br /&gt;
* The solution can be applied with minimal configuration effort&lt;br /&gt;
* The solution can be applied, developed and maintained with minimal learning effort&lt;br /&gt;
&lt;br /&gt;
=== Scalable ===&lt;br /&gt;
&lt;br /&gt;
* The solution can handle/adapt to varying problem sizes (e.g. amount of data, frequency of events) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
* The solution can utilize hardware/infrastructure enhancements and/or concurrency to provide better performance&lt;br /&gt;
* The solution can be applied in any number of concurrent instances (given the appropriate hardware and infrastructure) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
&lt;br /&gt;
=== Interoperable ===&lt;br /&gt;
&lt;br /&gt;
* Different instances of the solution can, where appropriate or required, interchange data and/or process information&lt;br /&gt;
* The solution can, where appropriate or required, interchange data and/or process information with other relevant solutions in the target scenario&lt;br /&gt;
* The solution provides external APIs (application programming interfaces)&lt;br /&gt;
&lt;br /&gt;
= User Experience (UX) Requirements =&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Wikipedia: ISO 9241-210[1] defines user experience as &amp;quot;a person&#039;s perceptions and responses that result from the use or anticipated use of a product, system or service&amp;quot;. According to the ISO definition, user experience includes all the users&#039; emotions, beliefs, preferences, perceptions, physical and psychological responses, behaviors and accomplishments that occur before, during and after use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User experience, as a result of human-computer-interaction, involves various aspects of a software solution - both in view of its design, its functionality as well as its quality, but also personal aspects of the individual user (e.g. skills, previous experiences, cultural background), and of the situations and environments in which the software is to be used.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Good UX&amp;quot; is though not a requirement in itself - but the generic name for any additional design, functional and quality requirements in view of human-computer-interaction that may be defined for a solution, and which must be met in order to achieve certain quality levels.&lt;br /&gt;
&lt;br /&gt;
Even though UX as such appears to be a largely subjective matter, there are usually a number of generalizable UX requirements for any user interface.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Example:&#039;&#039;&#039; &#039;&#039;User interfaces which are typically used in the darkness should not blind the user, but use a reduced palette of primarily reddish colors on dark background in order to cause less or no iris contraction. If the interface is though to be used under varying lighting conditions it should be adaptable (or even auto-adapt).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In order to be &#039;&#039;&#039;valid and accomplishable, UX requirements must be specific and clearly defined&#039;&#039;&#039; (like the above example) for the quality level for which they shall apply - even when their reasoning may be more complex sometimes.&lt;br /&gt;
&lt;br /&gt;
Some general quality requirements also influence the user experience (e.g. correctness, usability, efficiency), but are not specific for the use-case and therefore usually not separately discussed as UX requirements. They are however relevant for UX evaluations and should thus be taken into account in such analyses.&lt;br /&gt;
&lt;br /&gt;
= Advanced Quality Requirements =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Advanced&#039;&#039; quality criteria can be used to compare different solutions, or to define quality roadmaps for particular feature sets beyond the standard criteria.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not apply equally for all use-cases - in certain cases they may even constitute anti-patterns.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not enhance the general quality level of a solution: a level-3 solution is still of better quality than a level-2 solution - regardless how many advanced criteria the level-2 solution meets.&lt;br /&gt;
&lt;br /&gt;
== Stability ==&lt;br /&gt;
&lt;br /&gt;
A solution is &#039;&#039;stable&#039;&#039; when its black-box model rarely changes, and it maintains backwards-compatibility and/or easy migration paths. Stable solutions are required for all critical dependencies, so that they can be built upon without risk for frequent regression issues or need for constant migration. Stability is especially critical in shared data models (i.e. where data are shared between different modules within the application or even across applications), and in authorization frameworks - and can thus be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Stability is typically perceived as a sign of maturity, but can actually be taken into account already during the initial solution design. Pragmatic approaches (e.g. integrated migration, or enforced backwards-compatibility) can create stability early on without limiting or obstructing further development.&lt;br /&gt;
&lt;br /&gt;
== Generalization ==&lt;br /&gt;
&lt;br /&gt;
Generalizable solutions are designed and/or implemented in a way that they can be generalized. Typically, they separate their core patterns/algorithms from the use-case specifics through parametrization and/or configuration patterns. This can be defined as an advanced quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Generalization means to modify and/or extend the core patterns/algorithms of the solution in a way that they can be re-used in other solutions which involve the same or similar functional requirements, thereby reducing future development efforts. There is a wide range of quality attributes - &amp;quot;flexible&amp;quot;, &amp;quot;customizable&amp;quot;, &amp;quot;re-usable&amp;quot;, &amp;quot;extensible&amp;quot;, just to name a few - all of which involve different degrees of and approaches to generalization.&lt;br /&gt;
&lt;br /&gt;
= Standards =&lt;br /&gt;
&lt;br /&gt;
Solutions can both define or implement standards (e.g. data standards, communication protocols, taxonomies). Standard compliance can be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Standards can define additional requirements beyond the immediate requirements of the targeted problem, which must however be met in order to comply with the standard. Such additional standard requirements would usually be seen as quality requirements under [[#Consistent| &amp;quot;Consistency&amp;quot;]] in level 3.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=321</id>
		<title>Guidelines:Quality</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=321"/>
		<updated>2026-10-29T13:30:18Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Solution Quality Evaluation Guideline =&lt;br /&gt;
&lt;br /&gt;
== General Quality Requirements ==&lt;br /&gt;
&lt;br /&gt;
The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard. &lt;br /&gt;
&lt;br /&gt;
Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an iterative approach of continuous quality improvement.&lt;br /&gt;
&lt;br /&gt;
In order to pass a level, all criteria of this level and all previous levels must be met.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|+ Quality Levels&lt;br /&gt;
|-&lt;br /&gt;
! Level !! Priority (MoSCoW) !! Key Attributes !! Description&lt;br /&gt;
|-&lt;br /&gt;
||0 - &#039;&#039;&#039;Experimental&#039;&#039;&#039;||-||-||any solution that does not (yet) meet all criteria of level 1||&lt;br /&gt;
|-&lt;br /&gt;
||1 - &#039;&#039;&#039;Minimal&#039;&#039;&#039;||Must||[[#Valid| valid]], [[#Correct| correct]], [[#Safe| safe]]||minimum standard for any solution||&lt;br /&gt;
|-&lt;br /&gt;
||2 - &#039;&#039;&#039;Appropriate&#039;&#039;&#039;||Should||[[#Usable| usable]], [[#Maintainable| maintainable]], [[#Secure| secure]]||minimum standard for production use||&lt;br /&gt;
|-&lt;br /&gt;
||3 - &#039;&#039;&#039;Good&#039;&#039;&#039;||Can||[[#Consistent| consistent]], [[#Robust| robust]], [[#Configurable| configurable]]||long-term development goals||&lt;br /&gt;
|-&lt;br /&gt;
||4 - &#039;&#039;&#039;Optimal&#039;&#039;&#039;||Want||[[#Efficient| efficient]], [[#Scalable| scalable]], [[#Interoperable| interoperable]]||optimization and enhancement goals||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Level 1: Minimal ===&lt;br /&gt;
&lt;br /&gt;
==== Valid ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the right code&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The specified solution solves the targeted problem and meets the minimum functional requirements&lt;br /&gt;
* The required input data are available in the target scenario&lt;br /&gt;
* The user actions required to apply and/or use the solution or its responses are &#039;&#039;possible&#039;&#039; in the target scenario&lt;br /&gt;
* All dependencies of the feature set are resolvable, and hardware and infrastructure requirements can be met in the target scenario&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the code right&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Processing does not fail for any valid input data or user action.&lt;br /&gt;
* All responses are correct for the respective input data or user actions according to the specification&lt;br /&gt;
&lt;br /&gt;
==== Safe ====&lt;br /&gt;
&lt;br /&gt;
* The solution does not break other functionality of the application (except for functionality it replaces or supersedes)&lt;br /&gt;
* All processing always ends with a valid database status regardless whether it succeeds or fails&lt;br /&gt;
* All failed processes are effectively removed from the system and their transactions properly rolled back&lt;br /&gt;
* The solution effectively prevents uncontrolled indefinite object or process proliferation&lt;br /&gt;
* The solution always returns to a defined system status after a failure so that the application remains accessible&lt;br /&gt;
&lt;br /&gt;
=== Level 2: Appropriate ===&lt;br /&gt;
&lt;br /&gt;
==== Usable ====&lt;br /&gt;
&lt;br /&gt;
* The solution &#039;&#039;can&#039;&#039; be used by the intended user group in the target scenario, i.e. the users can:&lt;br /&gt;
** discover and access the features&lt;br /&gt;
** understand and perform the required user actions&lt;br /&gt;
** understand and control the consequences of actions&lt;br /&gt;
** understand and provide the required type, quality and format of input data&lt;br /&gt;
** discover and access the results, and apply them to achieve their goals&lt;br /&gt;
&lt;br /&gt;
* Usability criteria apply analogously for back-end libraries and tools with developers in the role of the user&lt;br /&gt;
&lt;br /&gt;
==== Maintainable ====&lt;br /&gt;
&lt;br /&gt;
* All critical dependencies are obvious at their starting point&lt;br /&gt;
* All non-critical dependencies have meaningful fallbacks&lt;br /&gt;
* Processing failures produce useful and accessible feedback about the reasons&lt;br /&gt;
* The design of the solution does not obstruct diagnostics of defects&lt;br /&gt;
* The code is structured in a way that the processing flow can easily be determined from it&lt;br /&gt;
&lt;br /&gt;
==== Secure ====&lt;br /&gt;
&lt;br /&gt;
* The solution applies all relevant system configurations for authentication, authorization and accounting (AAA) appropriately and correctly.&lt;br /&gt;
* The solution does not allow the user to perform actions or initiate processes beyond the intended functionality.&lt;br /&gt;
&lt;br /&gt;
=== Level 3: Good ===&lt;br /&gt;
&lt;br /&gt;
==== Consistent ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Maintaining Conceptual Integrity across the Application and beyond&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The solution applies the application framework appropriately and correctly&lt;br /&gt;
* The data structures defined in the solution are consistent with the global application data model&lt;br /&gt;
* The solution interoperates appropriately and correctly with other system components&lt;br /&gt;
* The solution applies the application&#039;s global design and style guidelines (both for code and interfaces)&lt;br /&gt;
* Where appropriate or required, the solution complies with specified standards (see [#Standards Standards])&lt;br /&gt;
&lt;br /&gt;
==== Robust ====&lt;br /&gt;
&lt;br /&gt;
* The solution delivers consistent behavior, results and performance for all valid configurations&lt;br /&gt;
* The solution handles invalid input data, unexpected user actions and irregular system conditions appropriately and consistently for all valid configurations&lt;br /&gt;
* The solution detects invalid configurations and prevents any inadvertent effects that could result from them&lt;br /&gt;
&lt;br /&gt;
==== Configurable ====&lt;br /&gt;
&lt;br /&gt;
* The solution can be easily and safely turned on and off without inadvertent side-effects (where appropriate, not for framework solutions)&lt;br /&gt;
* The solution applies global configuration settings correctly and consistently&lt;br /&gt;
* Processing parameters, behavior and/or appearance of the solution can be adapted to requirements variations using configuration patterns separate from its core code&lt;br /&gt;
&lt;br /&gt;
=== Level 4: Optimal ===&lt;br /&gt;
&lt;br /&gt;
==== Efficient ====&lt;br /&gt;
&lt;br /&gt;
* The solution provides acceptable performance with the minimum available hardware/infrastructure resources in the target scenario&lt;br /&gt;
* The solution can be applied with minimal configuration effort&lt;br /&gt;
* The solution can be applied, developed and maintained with minimal learning effort&lt;br /&gt;
&lt;br /&gt;
==== Scalable ====&lt;br /&gt;
&lt;br /&gt;
* The solution can handle/adapt to varying problem sizes (e.g. amount of data, frequency of events) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
* The solution can utilize hardware/infrastructure enhancements and/or concurrency to provide better performance&lt;br /&gt;
* The solution can be applied in any number of concurrent instances (given the appropriate hardware and infrastructure) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
&lt;br /&gt;
==== Interoperable ====&lt;br /&gt;
&lt;br /&gt;
* Different instances of the solution can, where appropriate or required, interchange data and/or process information&lt;br /&gt;
* The solution can, where appropriate or required, interchange data and/or process information with other relevant solutions in the target scenario&lt;br /&gt;
* The solution provides external APIs (application programming interfaces)&lt;br /&gt;
&lt;br /&gt;
== User Experience (UX) Requirements ==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Wikipedia: ISO 9241-210[1] defines user experience as &amp;quot;a person&#039;s perceptions and responses that result from the use or anticipated use of a product, system or service&amp;quot;. According to the ISO definition, user experience includes all the users&#039; emotions, beliefs, preferences, perceptions, physical and psychological responses, behaviors and accomplishments that occur before, during and after use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User experience, as a result of human-computer-interaction, involves various aspects of a software solution - both in view of its design, its functionality as well as its quality, but also personal aspects of the individual user (e.g. skills, previous experiences, cultural background), and of the situations and environments in which the software is to be used.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Good UX&amp;quot; is though not a requirement in itself - but the generic name for any additional design, functional and quality requirements in view of human-computer-interaction that may be defined for a solution, and which must be met in order to achieve certain quality levels.&lt;br /&gt;
&lt;br /&gt;
Even though UX as such appears to be a largely subjective matter, there are usually a number of generalizable UX requirements for any user interface.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Example:&#039;&#039;&#039; &#039;&#039;User interfaces which are typically used in the darkness should not blind the user, but use a reduced palette of primarily reddish colors on dark background in order to cause less or no iris contraction. If the interface is though to be used under varying lighting conditions it should be adaptable (or even auto-adapt).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In order to be &#039;&#039;&#039;valid and accomplishable, UX requirements must be specific and clearly defined&#039;&#039;&#039; (like the above example) for the quality level for which they shall apply - even when their reasoning may be more complex sometimes.&lt;br /&gt;
&lt;br /&gt;
Some general quality requirements also influence the user experience (e.g. correctness, usability, efficiency), but are not specific for the use-case and therefore usually not separately discussed as UX requirements. They are however relevant for UX evaluations and should thus be taken into account in such analyses.&lt;br /&gt;
&lt;br /&gt;
== Advanced Quality Requirements ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Advanced&#039;&#039; quality criteria can be used to compare different solutions, or to define quality roadmaps for particular feature sets beyond the standard criteria.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not apply equally for all use-cases - in certain cases they may even constitute anti-patterns.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not enhance the general quality level of a solution: a level-3 solution is still of better quality than a level-2 solution - regardless how many advanced criteria the level-2 solution meets.&lt;br /&gt;
&lt;br /&gt;
=== Stability ===&lt;br /&gt;
&lt;br /&gt;
A solution is &#039;&#039;stable&#039;&#039; when its black-box model rarely changes, and it maintains backwards-compatibility and/or easy migration paths. Stable solutions are required for all critical dependencies, so that they can be built upon without risk for frequent regression issues or need for constant migration. Stability is especially critical in shared data models (i.e. where data are shared between different modules within the application or even across applications), and in authorization frameworks - and can thus be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Stability is typically perceived as a sign of maturity, but can actually be taken into account already during the initial solution design. Pragmatic approaches (e.g. integrated migration, or enforced backwards-compatibility) can create stability early on without limiting or obstructing further development.&lt;br /&gt;
&lt;br /&gt;
=== Generalization ===&lt;br /&gt;
&lt;br /&gt;
Generalizable solutions are designed and/or implemented in a way that they can be generalized. Typically, they separate their core patterns/algorithms from the use-case specifics through parametrization and/or configuration patterns. This can be defined as an advanced quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Generalization means to modify and/or extend the core patterns/algorithms of the solution in a way that they can be re-used in other solutions which involve the same or similar functional requirements, thereby reducing future development efforts. There is a wide range of quality attributes - &amp;quot;flexible&amp;quot;, &amp;quot;customizable&amp;quot;, &amp;quot;re-usable&amp;quot;, &amp;quot;extensible&amp;quot;, just to name a few - all of which involve different degrees of and approaches to generalization.&lt;br /&gt;
&lt;br /&gt;
== Standards ==&lt;br /&gt;
&lt;br /&gt;
Solutions can both define or implement standards (e.g. data standards, communication protocols, taxonomies). Standard compliance can be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Standards can define additional requirements beyond the immediate requirements of the targeted problem, which must however be met in order to comply with the standard. Such additional standard requirements would usually be seen as quality requirements under [[#Consistent| &amp;quot;Consistency&amp;quot;]] in level 3.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=320</id>
		<title>Guidelines:Quality</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=320"/>
		<updated>2026-10-29T13:28:42Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Solution Quality Evaluation Guideline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Solution Quality Evaluation Guideline =&lt;br /&gt;
&lt;br /&gt;
== General Quality Requirements ==&lt;br /&gt;
&lt;br /&gt;
The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard. &lt;br /&gt;
&lt;br /&gt;
Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an iterative approach of continuous quality improvement.&lt;br /&gt;
&lt;br /&gt;
In order to pass a level, all criteria of this level and all previous levels must be met.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|+ Quality Levels&lt;br /&gt;
|-&lt;br /&gt;
! Level !! Priority (MoSCoW) !! Key Attributes !! Description&lt;br /&gt;
|-&lt;br /&gt;
||0 - &#039;&#039;&#039;Experimental&#039;&#039;&#039;||-||-||any solution that does not (yet) meet all criteria of level 1||&lt;br /&gt;
|-&lt;br /&gt;
||1 - &#039;&#039;&#039;Minimal&#039;&#039;&#039;||Must||[[#Valid| valid]], [[#Correct| correct]], [[#Safe| safe]]||minimum standard for any solution||&lt;br /&gt;
|-&lt;br /&gt;
||2 - &#039;&#039;&#039;Appropriate&#039;&#039;&#039;||Should||[[#Usable| usable]], [[#Maintainable| maintainable]], [[#Secure| secure]]||minimum standard for production use||&lt;br /&gt;
|-&lt;br /&gt;
||3 - &#039;&#039;&#039;Good&#039;&#039;&#039;||Can||[[#Consistent| consistent]], [[#Robust| robust]], [[#Configurable| configurable]]||long-term development goals||&lt;br /&gt;
|-&lt;br /&gt;
||4 - &#039;&#039;&#039;Optimal&#039;&#039;&#039;||Want||[[#Efficient| efficient]], [[#Scalable| scalable]], [[#Interoperable| interoperable]]||optimization and enhancement goals||&lt;br /&gt;
|}&lt;br /&gt;
=== Level 1: Minimal ===&lt;br /&gt;
&lt;br /&gt;
==== Valid ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the right code&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The specified solution solves the targeted problem and meets the minimum functional requirements&lt;br /&gt;
* The required input data are available in the target scenario&lt;br /&gt;
* The user actions required to apply and/or use the solution or its responses are &#039;&#039;possible&#039;&#039; in the target scenario&lt;br /&gt;
* All dependencies of the feature set are resolvable, and hardware and infrastructure requirements can be met in the target scenario&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the code right&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Processing does not fail for any valid input data or user action.&lt;br /&gt;
* All responses are correct for the respective input data or user actions according to the specification&lt;br /&gt;
&lt;br /&gt;
==== Safe ====&lt;br /&gt;
&lt;br /&gt;
* The solution does not break other functionality of the application (except for functionality it replaces or supersedes)&lt;br /&gt;
* All processing always ends with a valid database status regardless whether it succeeds or fails&lt;br /&gt;
* All failed processes are effectively removed from the system and their transactions properly rolled back&lt;br /&gt;
* The solution effectively prevents uncontrolled indefinite object or process proliferation&lt;br /&gt;
* The solution always returns to a defined system status after a failure so that the application remains accessible&lt;br /&gt;
&lt;br /&gt;
=== Level 2: Appropriate ===&lt;br /&gt;
&lt;br /&gt;
==== Usable ====&lt;br /&gt;
&lt;br /&gt;
* The solution &#039;&#039;can&#039;&#039; be used by the intended user group in the target scenario, i.e. the users can:&lt;br /&gt;
** discover and access the features&lt;br /&gt;
** understand and perform the required user actions&lt;br /&gt;
** understand and control the consequences of actions&lt;br /&gt;
** understand and provide the required type, quality and format of input data&lt;br /&gt;
** discover and access the results, and apply them to achieve their goals&lt;br /&gt;
&lt;br /&gt;
* Usability criteria apply analogously for back-end libraries and tools with developers in the role of the user&lt;br /&gt;
&lt;br /&gt;
==== Maintainable ====&lt;br /&gt;
&lt;br /&gt;
* All critical dependencies are obvious at their starting point&lt;br /&gt;
* All non-critical dependencies have meaningful fallbacks&lt;br /&gt;
* Processing failures produce useful and accessible feedback about the reasons&lt;br /&gt;
* The design of the solution does not obstruct diagnostics of defects&lt;br /&gt;
* The code is structured in a way that the processing flow can easily be determined from it&lt;br /&gt;
&lt;br /&gt;
==== Secure ====&lt;br /&gt;
&lt;br /&gt;
* The solution applies all relevant system configurations for authentication, authorization and accounting (AAA) appropriately and correctly.&lt;br /&gt;
* The solution does not allow the user to perform actions or initiate processes beyond the intended functionality.&lt;br /&gt;
&lt;br /&gt;
=== Level 3: Good ===&lt;br /&gt;
&lt;br /&gt;
==== Consistent ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Maintaining Conceptual Integrity across the Application and beyond&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The solution applies the application framework appropriately and correctly&lt;br /&gt;
* The data structures defined in the solution are consistent with the global application data model&lt;br /&gt;
* The solution interoperates appropriately and correctly with other system components&lt;br /&gt;
* The solution applies the application&#039;s global design and style guidelines (both for code and interfaces)&lt;br /&gt;
* Where appropriate or required, the solution complies with specified standards (see [#Standards Standards])&lt;br /&gt;
&lt;br /&gt;
==== Robust ====&lt;br /&gt;
&lt;br /&gt;
* The solution delivers consistent behavior, results and performance for all valid configurations&lt;br /&gt;
* The solution handles invalid input data, unexpected user actions and irregular system conditions appropriately and consistently for all valid configurations&lt;br /&gt;
* The solution detects invalid configurations and prevents any inadvertent effects that could result from them&lt;br /&gt;
&lt;br /&gt;
==== Configurable ====&lt;br /&gt;
&lt;br /&gt;
* The solution can be easily and safely turned on and off without inadvertent side-effects (where appropriate, not for framework solutions)&lt;br /&gt;
* The solution applies global configuration settings correctly and consistently&lt;br /&gt;
* Processing parameters, behavior and/or appearance of the solution can be adapted to requirements variations using configuration patterns separate from its core code&lt;br /&gt;
&lt;br /&gt;
=== Level 4: Optimal ===&lt;br /&gt;
&lt;br /&gt;
==== Efficient ====&lt;br /&gt;
&lt;br /&gt;
* The solution provides acceptable performance with the minimum available hardware/infrastructure resources in the target scenario&lt;br /&gt;
* The solution can be applied with minimal configuration effort&lt;br /&gt;
* The solution can be applied, developed and maintained with minimal learning effort&lt;br /&gt;
&lt;br /&gt;
==== Scalable ====&lt;br /&gt;
&lt;br /&gt;
* The solution can handle/adapt to varying problem sizes (e.g. amount of data, frequency of events) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
* The solution can utilize hardware/infrastructure enhancements and/or concurrency to provide better performance&lt;br /&gt;
* The solution can be applied in any number of concurrent instances (given the appropriate hardware and infrastructure) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
&lt;br /&gt;
==== Interoperable ====&lt;br /&gt;
&lt;br /&gt;
* Different instances of the solution can, where appropriate or required, interchange data and/or process information&lt;br /&gt;
* The solution can, where appropriate or required, interchange data and/or process information with other relevant solutions in the target scenario&lt;br /&gt;
* The solution provides external APIs (application programming interfaces)&lt;br /&gt;
&lt;br /&gt;
== User Experience (UX) Requirements ==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Wikipedia: ISO 9241-210[1] defines user experience as &amp;quot;a person&#039;s perceptions and responses that result from the use or anticipated use of a product, system or service&amp;quot;. According to the ISO definition, user experience includes all the users&#039; emotions, beliefs, preferences, perceptions, physical and psychological responses, behaviors and accomplishments that occur before, during and after use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User experience, as a result of human-computer-interaction, involves various aspects of a software solution - both in view of its design, its functionality as well as its quality, but also personal aspects of the individual user (e.g. skills, previous experiences, cultural background), and of the situations and environments in which the software is to be used.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Good UX&amp;quot; is though not a requirement in itself - but the generic name for any additional design, functional and quality requirements in view of human-computer-interaction that may be defined for a solution, and which must be met in order to achieve certain quality levels.&lt;br /&gt;
&lt;br /&gt;
Even though UX as such appears to be a largely subjective matter, there are usually a number of generalizable UX requirements for any user interface.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Example:&#039;&#039;&#039; &#039;&#039;User interfaces which are typically used in the darkness should not blind the user, but use a reduced palette of primarily reddish colors on dark background in order to cause less or no iris contraction. If the interface is though to be used under varying lighting conditions it should be adaptable (or even auto-adapt).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In order to be &#039;&#039;&#039;valid and accomplishable, UX requirements must be specific and clearly defined&#039;&#039;&#039; (like the above example) for the quality level for which they shall apply - even when their reasoning may be more complex sometimes.&lt;br /&gt;
&lt;br /&gt;
Some general quality requirements also influence the user experience (e.g. correctness, usability, efficiency), but are not specific for the use-case and therefore usually not separately discussed as UX requirements. They are however relevant for UX evaluations and should thus be taken into account in such analyses.&lt;br /&gt;
&lt;br /&gt;
== Advanced Quality Requirements ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Advanced&#039;&#039; quality criteria can be used to compare different solutions, or to define quality roadmaps for particular feature sets beyond the standard criteria.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not apply equally for all use-cases - in certain cases they may even constitute anti-patterns.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not enhance the general quality level of a solution: a level-3 solution is still of better quality than a level-2 solution - regardless how many advanced criteria the level-2 solution meets.&lt;br /&gt;
&lt;br /&gt;
=== Stability ===&lt;br /&gt;
&lt;br /&gt;
A solution is &#039;&#039;stable&#039;&#039; when its black-box model rarely changes, and it maintains backwards-compatibility and/or easy migration paths. Stable solutions are required for all critical dependencies, so that they can be built upon without risk for frequent regression issues or need for constant migration. Stability is especially critical in shared data models (i.e. where data are shared between different modules within the application or even across applications), and in authorization frameworks - and can thus be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Stability is typically perceived as a sign of maturity, but can actually be taken into account already during the initial solution design. Pragmatic approaches (e.g. integrated migration, or enforced backwards-compatibility) can create stability early on without limiting or obstructing further development.&lt;br /&gt;
&lt;br /&gt;
=== Generalization ===&lt;br /&gt;
&lt;br /&gt;
Generalizable solutions are designed and/or implemented in a way that they can be generalized. Typically, they separate their core patterns/algorithms from the use-case specifics through parametrization and/or configuration patterns. This can be defined as an advanced quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Generalization means to modify and/or extend the core patterns/algorithms of the solution in a way that they can be re-used in other solutions which involve the same or similar functional requirements, thereby reducing future development efforts. There is a wide range of quality attributes - &amp;quot;flexible&amp;quot;, &amp;quot;customizable&amp;quot;, &amp;quot;re-usable&amp;quot;, &amp;quot;extensible&amp;quot;, just to name a few - all of which involve different degrees of and approaches to generalization.&lt;br /&gt;
&lt;br /&gt;
== Standards ==&lt;br /&gt;
&lt;br /&gt;
Solutions can both define or implement standards (e.g. data standards, communication protocols, taxonomies). Standard compliance can be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Standards can define additional requirements beyond the immediate requirements of the targeted problem, which must however be met in order to comply with the standard. Such additional standard requirements would usually be seen as quality requirements under [[#Consistent| &amp;quot;Consistency&amp;quot;]] in level 3.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=319</id>
		<title>Guidelines:Quality</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Quality&amp;diff=319"/>
		<updated>2026-10-29T13:27:49Z</updated>

		<summary type="html">&lt;p&gt;Dominic: Created page with &amp;quot;= Solution Quality Evaluation Guideline =  == General Quality Requirements ==  The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).  These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard.   Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an it...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Solution Quality Evaluation Guideline =&lt;br /&gt;
&lt;br /&gt;
== General Quality Requirements ==&lt;br /&gt;
&lt;br /&gt;
The general quality requirements are defined here as attributes of the solution that is to be evaluated (&amp;quot;The solution must be ...&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
These attributes are grouped in four quality &amp;quot;levels&amp;quot; - a higher level representing a higher quality standard. &lt;br /&gt;
&lt;br /&gt;
Projects can refer to these levels to define minimum quality goals, to prioritize certain quality aspects vs. other requirements, or to define an iterative approach of continuous quality improvement.&lt;br /&gt;
&lt;br /&gt;
In order to pass a level, all criteria of this level and all previous levels must be met.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|+ Quality Levels&lt;br /&gt;
|-&lt;br /&gt;
! Level !! Priority (MoSCoW) !! Key Attributes !! Description&lt;br /&gt;
|-&lt;br /&gt;
||0 - &#039;&#039;&#039;Experimental&#039;&#039;&#039;||-||-||any solution that does not (yet) meet all criteria of level 1||&lt;br /&gt;
|-&lt;br /&gt;
||1 - &#039;&#039;&#039;Minimal&#039;&#039;&#039;||Must||[[#Valid| valid]], [[#Correct| correct]], [[#Safe| safe]]||minimum standard for any solution||&lt;br /&gt;
|-&lt;br /&gt;
||2 - &#039;&#039;&#039;Appropriate&#039;&#039;&#039;||Should||[[#Usable| usable]], [[#Maintainable| maintainable]], [[#Secure| secure]]||minimum standard for production use||&lt;br /&gt;
|-&lt;br /&gt;
||3 - &#039;&#039;&#039;Good&#039;&#039;&#039;||Can||[[#Consistent| consistent]], [[#Robust| robust]], [[#Configurable| configurable]]||long-term development goals||&lt;br /&gt;
|-&lt;br /&gt;
||4 - &#039;&#039;&#039;Optimal&#039;&#039;&#039;||Want||[[#Efficient| efficient]], [[#Scalable| scalable]], [[#Interoperable| interoperable]]||optimization and enhancement goals||&lt;br /&gt;
|}&lt;br /&gt;
=== Level 1: Minimal ===&lt;br /&gt;
&lt;br /&gt;
==== Valid ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the right code&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The specified solution solves the targeted problem and meets the minimum functional requirements&lt;br /&gt;
* The required input data are available in the target scenario&lt;br /&gt;
* The user actions required to apply and/or use the solution or its responses are &#039;&#039;possible&#039;&#039; in the target scenario&lt;br /&gt;
* All dependencies of the feature set are resolvable, and hardware and infrastructure requirements can be met in the target scenario&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Writing the code right&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Processing does not fail for any valid input data or user action.&lt;br /&gt;
* All responses are correct for the respective input data or user actions according to the specification&lt;br /&gt;
&lt;br /&gt;
==== Safe ====&lt;br /&gt;
&lt;br /&gt;
* The solution does not break other functionality of the application (except for functionality it replaces or supersedes)&lt;br /&gt;
* All processing always ends with a valid database status regardless whether it succeeds or fails&lt;br /&gt;
* All failed processes are effectively removed from the system and their transactions properly rolled back&lt;br /&gt;
* The solution effectively prevents uncontrolled indefinite object or process proliferation&lt;br /&gt;
* The solution always returns to a defined system status after a failure so that the application remains accessible&lt;br /&gt;
&lt;br /&gt;
=== Level 2: Appropriate ===&lt;br /&gt;
&lt;br /&gt;
==== Usable ====&lt;br /&gt;
&lt;br /&gt;
* The solution &#039;&#039;can&#039;&#039; be used by the intended user group in the target scenario, i.e. the users can:&lt;br /&gt;
** discover and access the features&lt;br /&gt;
** understand and perform the required user actions&lt;br /&gt;
** understand and control the consequences of actions&lt;br /&gt;
** understand and provide the required type, quality and format of input data&lt;br /&gt;
** discover and access the results, and apply them to achieve their goals&lt;br /&gt;
&lt;br /&gt;
* Usability criteria apply analogously for back-end libraries and tools with developers in the role of the user&lt;br /&gt;
&lt;br /&gt;
==== Maintainable ====&lt;br /&gt;
&lt;br /&gt;
* All critical dependencies are obvious at their starting point&lt;br /&gt;
* All non-critical dependencies have meaningful fallbacks&lt;br /&gt;
* Processing failures produce useful and accessible feedback about the reasons&lt;br /&gt;
* The design of the solution does not obstruct diagnostics of defects&lt;br /&gt;
* The code is structured in a way that the processing flow can easily be determined from it&lt;br /&gt;
&lt;br /&gt;
==== Secure ====&lt;br /&gt;
&lt;br /&gt;
* The solution applies all relevant system configurations for authentication, authorization and accounting (AAA) appropriately and correctly.&lt;br /&gt;
* The solution does not allow the user to perform actions or initiate processes beyond the intended functionality.&lt;br /&gt;
&lt;br /&gt;
=== Level 3: Good ===&lt;br /&gt;
&lt;br /&gt;
==== Consistent ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;quot;Maintaining Conceptual Integrity across the Application and beyond&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The solution applies the application framework appropriately and correctly&lt;br /&gt;
* The data structures defined in the solution are consistent with the global application data model&lt;br /&gt;
* The solution interoperates appropriately and correctly with other system components&lt;br /&gt;
* The solution applies the application&#039;s global design and style guidelines (both for code and interfaces)&lt;br /&gt;
* Where appropriate or required, the solution complies with specified standards (see [#Standards Standards])&lt;br /&gt;
&lt;br /&gt;
==== Robust ====&lt;br /&gt;
&lt;br /&gt;
* The solution delivers consistent behavior, results and performance for all valid configurations&lt;br /&gt;
* The solution handles invalid input data, unexpected user actions and irregular system conditions appropriately and consistently for all valid configurations&lt;br /&gt;
* The solution detects invalid configurations and prevents any inadvertent effects that could result from them&lt;br /&gt;
&lt;br /&gt;
==== Configurable ====&lt;br /&gt;
&lt;br /&gt;
* The solution can be easily and safely turned on and off without inadvertent side-effects (where appropriate, not for framework solutions)&lt;br /&gt;
* The solution applies global configuration settings correctly and consistently&lt;br /&gt;
* Processing parameters, behavior and/or appearance of the solution can be adapted to requirements variations using configuration patterns separate from its core code&lt;br /&gt;
&lt;br /&gt;
=== Level 4: Optimal ===&lt;br /&gt;
&lt;br /&gt;
==== Efficient ====&lt;br /&gt;
&lt;br /&gt;
* The solution provides acceptable performance with the minimum available hardware/infrastructure resources in the target scenario&lt;br /&gt;
* The solution can be applied with minimal configuration effort&lt;br /&gt;
* The solution can be applied, developed and maintained with minimal learning effort&lt;br /&gt;
&lt;br /&gt;
==== Scalable ====&lt;br /&gt;
&lt;br /&gt;
* The solution can handle/adapt to varying problem sizes (e.g. amount of data, frequency of events) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
* The solution can utilize hardware/infrastructure enhancements and/or concurrency to provide better performance&lt;br /&gt;
* The solution can be applied in any number of concurrent instances (given the appropriate hardware and infrastructure) without failure, inconsistent behavior or significant loss of performance&lt;br /&gt;
&lt;br /&gt;
==== Interoperable ====&lt;br /&gt;
&lt;br /&gt;
* Different instances of the solution can, where appropriate or required, interchange data and/or process information&lt;br /&gt;
* The solution can, where appropriate or required, interchange data and/or process information with other relevant solutions in the target scenario&lt;br /&gt;
* The solution provides external APIs (application programming interfaces)&lt;br /&gt;
&lt;br /&gt;
== User Experience (UX) Requirements ==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;Wikipedia: ISO 9241-210[1] defines user experience as &amp;quot;a person&#039;s perceptions and responses that result from the use or anticipated use of a product, system or service&amp;quot;. According to the ISO definition, user experience includes all the users&#039; emotions, beliefs, preferences, perceptions, physical and psychological responses, behaviors and accomplishments that occur before, during and after use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
User experience, as a result of human-computer-interaction, involves various aspects of a software solution - both in view of its design, its functionality as well as its quality, but also personal aspects of the individual user (e.g. skills, previous experiences, cultural background), and of the situations and environments in which the software is to be used.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Good UX&amp;quot; is though not a requirement in itself - but the generic name for any additional design, functional and quality requirements in view of human-computer-interaction that may be defined for a solution, and which must be met in order to achieve certain quality levels.&lt;br /&gt;
&lt;br /&gt;
Even though UX as such appears to be a largely subjective matter, there are usually a number of generalizable UX requirements for any user interface.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Example:&#039;&#039;&#039; &#039;&#039;User interfaces which are typically used in the darkness should not blind the user, but use a reduced palette of primarily reddish colors on dark background in order to cause less or no iris contraction. If the interface is though to be used under varying lighting conditions it should be adaptable (or even auto-adapt).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In order to be &#039;&#039;&#039;valid and accomplishable, UX requirements must be specific and clearly defined&#039;&#039;&#039; (like the above example) for the quality level for which they shall apply - even when their reasoning may be more complex sometimes.&lt;br /&gt;
&lt;br /&gt;
Some general quality requirements also influence the user experience (e.g. correctness, usability, efficiency), but are not specific for the use-case and therefore usually not separately discussed as UX requirements. They are however relevant for UX evaluations and should thus be taken into account in such analyses.&lt;br /&gt;
&lt;br /&gt;
== Advanced Quality Requirements ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Advanced&#039;&#039; quality criteria can be used to compare different solutions, or to define quality roadmaps for particular feature sets beyond the standard criteria.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not apply equally for all use-cases - in certain cases they may even constitute anti-patterns.&lt;br /&gt;
&lt;br /&gt;
Advanced quality criteria do not enhance the general quality level of a solution: a level-3 solution is still of better quality than a level-2 solution - regardless how many advanced criteria the level-2 solution meets.&lt;br /&gt;
&lt;br /&gt;
=== Stability ===&lt;br /&gt;
&lt;br /&gt;
A solution is &#039;&#039;stable&#039;&#039; when its black-box model rarely changes, and it maintains backwards-compatibility and/or easy migration paths. Stable solutions are required for all critical dependencies, so that they can be built upon without risk for frequent regression issues or need for constant migration. Stability is especially critical in shared data models (i.e. where data are shared between different modules within the application or even across applications), and in authorization frameworks - and can thus be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Stability is typically perceived as a sign of maturity, but can actually be taken into account already during the initial solution design. Pragmatic approaches (e.g. integrated migration, or enforced backwards-compatibility) can create stability early on without limiting or obstructing further development.&lt;br /&gt;
&lt;br /&gt;
=== Generalization ===&lt;br /&gt;
&lt;br /&gt;
Generalizable solutions are designed and/or implemented in a way that they can be generalized. Typically, they separate their core patterns/algorithms from the use-case specifics through parametrization and/or configuration patterns. This can be defined as an advanced quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Generalization means to modify and/or extend the core patterns/algorithms of the solution in a way that they can be re-used in other solutions which involve the same or similar functional requirements, thereby reducing future development efforts. There is a wide range of quality attributes - &amp;quot;flexible&amp;quot;, &amp;quot;customizable&amp;quot;, &amp;quot;re-usable&amp;quot;, &amp;quot;extensible&amp;quot;, just to name a few - all of which involve different degrees of and approaches to generalization.&lt;br /&gt;
&lt;br /&gt;
== Standards ==&lt;br /&gt;
&lt;br /&gt;
Solutions can both define or implement standards (e.g. data standards, communication protocols, taxonomies). Standard compliance can be defined as quality requirement for a solution.&lt;br /&gt;
&lt;br /&gt;
Standards can define additional requirements beyond the immediate requirements of the targeted problem, which must however be met in order to comply with the standard. Such additional standard requirements would usually be seen as quality requirements under [[#Consistent| &amp;quot;Consistency&amp;quot;]] in level 3.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=318</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=318"/>
		<updated>2026-10-29T12:58:43Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Internationalisation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General =&lt;br /&gt;
&lt;br /&gt;
The following conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
= Python =&lt;br /&gt;
&lt;br /&gt;
== Line-length and Indentation ==&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;four spaces&#039;&#039;&#039; for indentation. &lt;br /&gt;
&lt;br /&gt;
Try to limit the length of code lines to &#039;&#039;&#039;80 characters&#039;&#039;&#039;, where possible (PEP8). This is not a strict requirement, however:&lt;br /&gt;
* a string literal making the line longer is acceptable as long as it is the last code element in that line&lt;br /&gt;
* a line that is only slightly longer (up to 96 characters) is acceptable if it aids readability/comprehensibility&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug and security risk&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
&lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Add comments so others can understand your code when they try to find bugs or improve/extend it. Comments in code should explain intent (or clarify techniques), not repeat the code (do not explain what is self-explaining).&lt;br /&gt;
&lt;br /&gt;
Poor:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Set free to True&lt;br /&gt;
free = True&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Good:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Indicate that the position is now free&lt;br /&gt;
free = True&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commented code should have a comment explaining why it is commented.&lt;br /&gt;
&lt;br /&gt;
Unclear:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#result = somefunction(somearg)&lt;br /&gt;
result = 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Better:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Not working yet, TODO: fix somefunction&lt;br /&gt;
#result = somefunction(somearg)&lt;br /&gt;
result = 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Internationalisation ==&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;br /&gt;
&lt;br /&gt;
== Print Function ==&lt;br /&gt;
&lt;br /&gt;
For compatibility with WSGI as well as newer web2py (&amp;gt;=2.15), using the &amp;lt;code&amp;gt;print()&amp;lt;/code&amp;gt; function in web application sources is &#039;&#039;&#039;strongly discouraged&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For everything that is to be executed in the restricted environment (i.e. all server code):&lt;br /&gt;
* for messages that are relevant during system setup (e.g. 1st run, module import failures etc.), use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for run-time debug/error messages: use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;current.log.*&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, as it can be controlled centrally, and routed to a log file when web2py isn&#039;t console-run&lt;br /&gt;
* for temporary debug output in code under development, use either &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;print(..., file=sys.stderr)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For CLI scripts:&lt;br /&gt;
* use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for status/error messages, or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stdout.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for results&lt;br /&gt;
* alternatively, use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;print()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;-function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.std*.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (remember that write expects string/buffer, so you must convert any parameters explicitly):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# For status/error/debug messages:&lt;br /&gt;
sys.stderr.write(&amp;quot;Here is a status message\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# For results:&lt;br /&gt;
sys.stdout.write(&amp;quot;%s\n&amp;quot; % result)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the logger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from gluon import current&lt;br /&gt;
&lt;br /&gt;
# Use this for any permanent message output in server code:&lt;br /&gt;
current.log.error(&amp;quot;Here is an error message&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
current.log.debug(&amp;quot;And this is a debug message&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the print-function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Using the print-function in CLI scripts:&lt;br /&gt;
print(&amp;quot;The print-function&amp;quot;, &amp;quot;accepts&amp;quot;, &amp;quot;multiple arguments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Remember that server code must write to stderr, not stdout:&lt;br /&gt;
print(&amp;quot;Direct output to stderr&amp;quot;, file=sys.stderr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JavaScript =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&#039;&#039;tbw&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings. Type specifications for parameters and return values are mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= HTML / XML =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=317</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=317"/>
		<updated>2026-10-29T12:54:16Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Project Conventions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Sahana Eden&#039;&#039;&#039; is an &#039;&#039;Application Development Kit&#039;&#039; designed to build database-driven web applications tailored for emergency and humanitarian management. It provides a robust foundation for application developers and IT service providers to meet the information management needs of aid organizations and governmental agencies during emergencies, disaster preparedness, and humanitarian operations.&lt;br /&gt;
&lt;br /&gt;
Eden is &#039;&#039;&#039;free and open-source software&#039;&#039;&#039; (FOSS) that can be freely used, modified, extended, and integrated by anyone without restrictions.&lt;br /&gt;
&lt;br /&gt;
As an open project, Eden fosters collaboration and the exchange of knowledge, experiences, and best practices among humanitarian organizations. The project is guided by input from experienced aid organizations worldwide and emphasizes the use of open technology and standards. Nearly all of Eden’s code is developed in close cooperation with humanitarians in the field, ensuring it is directly aligned with real-world needs.&lt;br /&gt;
&lt;br /&gt;
== Implementing Eden ==&lt;br /&gt;
&lt;br /&gt;
Sahana Eden is a multi-purpose &#039;&#039;web application&#039;&#039; written for the [https://web2py.com web2py] framework. &lt;br /&gt;
&lt;br /&gt;
The appearance and business logic of this application can be adjusted to the needs of a particular deployment by altering settings in the &amp;lt;code&amp;gt;models/000_config.py&amp;lt;/code&amp;gt; configuration file on the server. Such adjustments can be minimal, or (more commonly) be extensive customization involving menus, forms, user roles, workflows, data models and even processing logic - so that Eden can be repurposed and adapted for many different use-cases and scenarios.&lt;br /&gt;
&lt;br /&gt;
Rather than putting all these customizations into one server-side configuration file, they would normally be implemented as Python packages which are then imported as &#039;&#039;&#039;configuration templates&#039;&#039;&#039;. This way, complex custom configurations can be developed, tested and maintained away from the server - and can easily be shared and re-used in other deployments.&lt;br /&gt;
&lt;br /&gt;
An &#039;&#039;&#039;Eden application&#039;&#039;&#039; is understood as such a re-usable configuration template (or a combination of templates), and &#039;&#039;&#039;Application Development&#039;&#039;&#039; is focused on these templates. &lt;br /&gt;
&lt;br /&gt;
A small selection of configuration templates is included in the Eden code base. However, downstream projects will often develop their own templates, and may publish and/or market them independently - a business model which we encourage and support.&lt;br /&gt;
&lt;br /&gt;
== Deploying Eden ==&lt;br /&gt;
&lt;br /&gt;
=== Installation and Setup ===&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== How to Contribute ==&lt;br /&gt;
&lt;br /&gt;
=== What to Do ===&lt;br /&gt;
&lt;br /&gt;
==== Code ====&lt;br /&gt;
* [https://github.com/sahana/eden/issues Issues] are a good starting point for  short-term contribution&lt;br /&gt;
* [[Blueprint:Index|Blueprints]] describe more complex feature sets and requirements, best suited for longer-term contribution&lt;br /&gt;
* Many core modules are looking for a maintainer, who takes long-term overall responsibility for their continuous development, support and documentation. Tell us on our [https://groups.google.com/g/eden-asp mailing list] what you would be interested in leading, and we will guide you to the role.&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
* Our [https://eden-asp.readthedocs.io/en/latest Handbook for Application Developers] needs continuous maintenance and improvement. You can work on the handbook in the [https://github.com/sahana/eden/tree/dev/docs/source code base].&lt;br /&gt;
* If you want to contribute to this wiki, you can start by discussing your idea on our [https://groups.google.com/g/eden-asp mailing list] - we will then create a wiki account for you as needed.&lt;br /&gt;
&lt;br /&gt;
=== Information Resources ===&lt;br /&gt;
&lt;br /&gt;
* [[Code Repository]]&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
&lt;br /&gt;
=== Project Conventions ===&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:CodingStyle|Coding Conventions]]&lt;br /&gt;
* [[Guidelines:AI|Policy for Responsible AI Contributions]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Index&amp;diff=316</id>
		<title>Guidelines:Index</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Index&amp;diff=316"/>
		<updated>2026-10-29T12:53:37Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Contributor Guidelines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Implementer Guidelines ==&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Contributor Guidelines ==&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
* [[Guidelines:CodingStyle|Coding Conventions]]&lt;br /&gt;
* [[Guidelines:AI|Guideline for Responsible AI Contributions]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=315</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=315"/>
		<updated>2026-10-29T12:52:16Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General =&lt;br /&gt;
&lt;br /&gt;
The following conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
= Python =&lt;br /&gt;
&lt;br /&gt;
== Line-length and Indentation ==&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;four spaces&#039;&#039;&#039; for indentation. &lt;br /&gt;
&lt;br /&gt;
Try to limit the length of code lines to &#039;&#039;&#039;80 characters&#039;&#039;&#039;, where possible (PEP8). This is not a strict requirement, however:&lt;br /&gt;
* a string literal making the line longer is acceptable as long as it is the last code element in that line&lt;br /&gt;
* a line that is only slightly longer (up to 96 characters) is acceptable if it aids readability/comprehensibility&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug and security risk&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
&lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Internationalisation ==&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;br /&gt;
&lt;br /&gt;
== Print Function ==&lt;br /&gt;
&lt;br /&gt;
For compatibility with WSGI as well as newer web2py (&amp;gt;=2.15), using the &amp;lt;code&amp;gt;print()&amp;lt;/code&amp;gt; function in web application sources is &#039;&#039;&#039;strongly discouraged&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For everything that is to be executed in the restricted environment (i.e. all server code):&lt;br /&gt;
* for messages that are relevant during system setup (e.g. 1st run, module import failures etc.), use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for run-time debug/error messages: use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;current.log.*&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, as it can be controlled centrally, and routed to a log file when web2py isn&#039;t console-run&lt;br /&gt;
* for temporary debug output in code under development, use either &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;print(..., file=sys.stderr)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For CLI scripts:&lt;br /&gt;
* use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for status/error messages, or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stdout.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for results&lt;br /&gt;
* alternatively, use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;print()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;-function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.std*.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (remember that write expects string/buffer, so you must convert any parameters explicitly):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# For status/error/debug messages:&lt;br /&gt;
sys.stderr.write(&amp;quot;Here is a status message\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# For results:&lt;br /&gt;
sys.stdout.write(&amp;quot;%s\n&amp;quot; % result)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the logger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from gluon import current&lt;br /&gt;
&lt;br /&gt;
# Use this for any permanent message output in server code:&lt;br /&gt;
current.log.error(&amp;quot;Here is an error message&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
current.log.debug(&amp;quot;And this is a debug message&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the print-function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Using the print-function in CLI scripts:&lt;br /&gt;
print(&amp;quot;The print-function&amp;quot;, &amp;quot;accepts&amp;quot;, &amp;quot;multiple arguments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Remember that server code must write to stderr, not stdout:&lt;br /&gt;
print(&amp;quot;Direct output to stderr&amp;quot;, file=sys.stderr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JavaScript =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&#039;&#039;tbw&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings. Type specifications for parameters and return values are mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= HTML / XML =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=314</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=314"/>
		<updated>2026-10-29T12:26:37Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General =&lt;br /&gt;
&lt;br /&gt;
The following conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
= Python =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug and security risk&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
&lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Internationalisation ==&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;br /&gt;
&lt;br /&gt;
== Print Function ==&lt;br /&gt;
&lt;br /&gt;
For compatibility with WSGI as well as newer web2py (&amp;gt;=2.15), using the &amp;lt;code&amp;gt;print()&amp;lt;/code&amp;gt; function in web application sources is &#039;&#039;&#039;strongly discouraged&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For everything that is to be executed in the restricted environment (i.e. all server code):&lt;br /&gt;
* for messages that are relevant during system setup (e.g. 1st run, module import failures etc.), use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for run-time debug/error messages: use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;current.log.*&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, as it can be controlled centrally, and routed to a log file when web2py isn&#039;t console-run&lt;br /&gt;
* for temporary debug output in code under development, use either &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;print(..., file=sys.stderr)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For CLI scripts:&lt;br /&gt;
* use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stderr.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for status/error messages, or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.stdout.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for results&lt;br /&gt;
* alternatively, use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;print()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;-function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sys.std*.write()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (remember that write expects string/buffer, so you must convert any parameters explicitly):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# For status/error/debug messages:&lt;br /&gt;
sys.stderr.write(&amp;quot;Here is a status message\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# For results:&lt;br /&gt;
sys.stdout.write(&amp;quot;%s\n&amp;quot; % result)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the logger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from gluon import current&lt;br /&gt;
&lt;br /&gt;
# Use this for any permanent message output in server code:&lt;br /&gt;
current.log.error(&amp;quot;Here is an error message&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
current.log.debug(&amp;quot;And this is a debug message&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the print-function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Using the print-function in CLI scripts:&lt;br /&gt;
print(&amp;quot;The print-function&amp;quot;, &amp;quot;accepts&amp;quot;, &amp;quot;multiple arguments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Remember that server code must write to stderr, not stdout:&lt;br /&gt;
print(&amp;quot;Direct output to stderr&amp;quot;, file=sys.stderr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JavaScript =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&#039;&#039;tbw&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings. Type specifications for parameters and return values are mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= HTML / XML =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=313</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=313"/>
		<updated>2026-10-29T12:14:12Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* JavaScript */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General =&lt;br /&gt;
&lt;br /&gt;
The following conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
= Python =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug and security risk&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
&lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Internationalisation ==&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;br /&gt;
&lt;br /&gt;
= JavaScript =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&#039;&#039;tbw&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings. Type specifications for parameters and return values are mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= HTML / XML =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=312</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=312"/>
		<updated>2026-10-29T12:13:45Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= General =&lt;br /&gt;
&lt;br /&gt;
The following conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
= Python =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug and security risk&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
&lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Internationalisation ==&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;br /&gt;
&lt;br /&gt;
= JavaScript =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&#039;&#039;tbw&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== JavaScript ===&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings. Type specifications for parameters and return values are mandatory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= HTML / XML =&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=311</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=311"/>
		<updated>2026-10-28T23:08:20Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Quotes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Coding Style Guide =&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug and security risk&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JavaScript ===&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
== Internationalisation ==&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=310</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=310"/>
		<updated>2026-10-28T23:02:36Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Coding Style Guide =&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JavaScript ===&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
== Internationalisation ==&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Handling ==&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=309</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=309"/>
		<updated>2026-10-28T22:56:16Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Exceptions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Coding Style Guide =&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JavaScript ===&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exception Handling ===&lt;br /&gt;
&lt;br /&gt;
Catching exceptions too broadly can easily hide programming errors, obscure problem causes, and introduce serious risks for data integrity and security. Be as specific as possible as to which (type of) exception is to be caught, and always have a good reason for catching it.&lt;br /&gt;
&lt;br /&gt;
Do not catch an exception (&amp;quot;Let it crash&amp;quot;) unless:&lt;br /&gt;
* there is an immediate remedy or a meaningful alternative action, or&lt;br /&gt;
* the exception can be transformed into a meaningful error message that the users can act upon, or&lt;br /&gt;
* the exception needs to be logged (in which case it should be re-raised after logging)&lt;br /&gt;
&lt;br /&gt;
All critical exceptions on the server-side should be logged.&lt;br /&gt;
&lt;br /&gt;
Database exceptions should never be caught as they may block the current transaction and thus lead to another exception at a later point, obscuring the original cause of the problem.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=308</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=308"/>
		<updated>2026-10-28T22:12:47Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Coding Style Guide =&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
== Quotes ==&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
== Names ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Docstrings ==&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JavaScript ===&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=307</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=307"/>
		<updated>2026-10-28T22:11:23Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value &#039;&#039;&#039;should be included&#039;&#039;&#039; in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are &#039;&#039;&#039;discouraged&#039;&#039;&#039; for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JavaScript ====&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=306</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=306"/>
		<updated>2026-10-28T22:10:25Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Except where they are obvious, &#039;&#039;&#039;data types&#039;&#039;&#039; of parameters and return value should be included in the docstring.&lt;br /&gt;
&lt;br /&gt;
To that end, &#039;&#039;&#039;PEP484-style type hints&#039;&#039;&#039; can also be acceptable in simple cases - but are discouraged for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JavaScript ====&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=305</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=305"/>
		<updated>2026-10-28T22:02:35Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.&lt;br /&gt;
&lt;br /&gt;
In simple cases, &#039;&#039;PEP484-style type hints&#039;&#039; can also be acceptable - but are discouraged for more complex parameter lists as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JavaScript ====&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=304</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=304"/>
		<updated>2026-10-28T22:01:32Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.&lt;br /&gt;
&lt;br /&gt;
In simple cases, &#039;&#039;PEP484-style type hints&#039;&#039; can also be acceptable - but are otherwise discouraged as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of complex function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JavaScript ====&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=303</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=303"/>
		<updated>2026-10-28T21:49:16Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
We follow loosely the &#039;&#039;Google Style Guide&#039;&#039; for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.&lt;br /&gt;
&lt;br /&gt;
In some trivial cases, &#039;&#039;PEP484-style type hints&#039;&#039; can also be acceptable - but are otherwise discouraged as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of complex function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JavaScript ====&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=302</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=302"/>
		<updated>2026-10-28T21:48:26Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
We follow loosely the Google Style Guide for docstrings in Python, albeit with additional indentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.&lt;br /&gt;
&lt;br /&gt;
In some trivial cases, PEP484-style type hints can also be acceptable - but are otherwise discouraged as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of complex function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JavaScript ====&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=301</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=301"/>
		<updated>2026-10-28T21:43:24Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Docstrings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
Acceptable style:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.&lt;br /&gt;
&lt;br /&gt;
In some trivial cases, PEP484-style type hints can also be acceptable - but are otherwise discouraged as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of complex function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JavaScript ====&lt;br /&gt;
&lt;br /&gt;
In JavaScript, we use Java Docstrings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Retrieves events within a certain time interval.&lt;br /&gt;
 *&lt;br /&gt;
 * @param {moment|Date|string} start - the start of the interval&lt;br /&gt;
 * @param {moment|Date|string} end - the end of the interval&lt;br /&gt;
 *&lt;br /&gt;
 * @returns {Array} - the events within the interval,&lt;br /&gt;
 *                    or null if the interval is not completely cached&lt;br /&gt;
 */&lt;br /&gt;
EventCache.prototype.retrieve = function(start, end) {&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return values are mandatory here.&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=300</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=300"/>
		<updated>2026-10-28T21:35:43Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Docstrings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
Acceptable style:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.&lt;br /&gt;
&lt;br /&gt;
In some trivial cases, PEP484-style type hints can also be acceptable - but are otherwise discouraged as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=299</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=299"/>
		<updated>2026-10-28T21:31:56Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Docstrings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.&lt;br /&gt;
&lt;br /&gt;
Acceptable style:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r, idcard):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF.&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            (CRUDRequest) r: the request context&lt;br /&gt;
            (IDCard) idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            DIV: the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.&lt;br /&gt;
&lt;br /&gt;
In some trivial cases, PEP484-style type hints can also be acceptable - but are otherwise discouraged as not every syntax highlighter will aid the visual parsing of function annotations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def card_details(r: CRUDRequest, idcard: IDCard) -&amp;gt; DIV:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Displays the details of the new registration card, and offers&lt;br /&gt;
        a button to download the PDF&lt;br /&gt;
&lt;br /&gt;
        Args:&lt;br /&gt;
            r: the request context&lt;br /&gt;
            idcard: the new registration card&lt;br /&gt;
&lt;br /&gt;
        Returns:&lt;br /&gt;
            the card contents&lt;br /&gt;
&lt;br /&gt;
        Raises:&lt;br /&gt;
            ValueError: if the idcard is invalid or expired&lt;br /&gt;
&lt;br /&gt;
        Note:&lt;br /&gt;
            Card secrets will not be rendered.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=298</id>
		<title>Guidelines:CodingStyle</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:CodingStyle&amp;diff=298"/>
		<updated>2026-10-28T16:17:40Z</updated>

		<summary type="html">&lt;p&gt;Dominic: Created page with &amp;quot;* All Guidelines  == Coding Style Guide ==  These conventions should be followed in all code.  This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.  Our style guide aims to...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Coding Style Guide ==&lt;br /&gt;
&lt;br /&gt;
These conventions should be followed in all code.&lt;br /&gt;
&lt;br /&gt;
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.&lt;br /&gt;
&lt;br /&gt;
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.&lt;br /&gt;
&lt;br /&gt;
=== Quotes ===&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;Python&#039;&#039;&#039; use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt;, unless the string contains double-quotes&lt;br /&gt;
* for triple-quoted strings (such as &#039;&#039;Docstrings&#039;&#039; or &#039;&#039;Inline-XML&#039;&#039;) use &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;quot; &amp;quot;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; with double-quotes, except:&lt;br /&gt;
* for &#039;&#039;Inline-JavaScript&#039;&#039; or &#039;&#039;JSON&#039;&#039; inside &#039;&#039;&#039;Python&#039;&#039;&#039; code use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&#039; &#039;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note though that this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=&amp;quot;%s&amp;quot;;&#039;&#039;&#039; % sometext&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is a &#039;&#039;&#039;potential bug&#039;&#039;&#039; - the script breaks when &amp;lt;code&amp;gt;sometext&amp;lt;/code&amp;gt; contains a &amp;lt;code&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;. A safer way to do that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
inline_javascript = &#039;&#039;&#039;sometext=%s;&#039;&#039;&#039; % json.dumps(sometext)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for string literals in &#039;&#039;&#039;JavaScript&#039;&#039;&#039; use single-quotes &amp;lt;code&amp;gt;&#039; &#039;&amp;lt;/code&amp;gt;, unless the string contains single-quotes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* for attributes in &#039;&#039;&#039;HTML&#039;&#039;&#039; (such as &#039;&#039;view templates&#039;&#039;) use single-quotes &amp;lt;code&amp;gt;attr=&#039;value&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* for attributes in other &#039;&#039;&#039;XML&#039;&#039;&#039; (e.g. &#039;&#039;XSLT&#039;&#039;) use double-quotes &amp;lt;code&amp;gt;&amp;quot; &amp;quot;&amp;lt;/code&amp;gt; (inner quotes must be escaped anyway)&lt;br /&gt;
&lt;br /&gt;
=== Names ===&lt;br /&gt;
&lt;br /&gt;
==== General ====&lt;br /&gt;
&lt;br /&gt;
* Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn&#039;t require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn&#039;t take too long to write. Avoid inventing new acronyms. e.g. &lt;br /&gt;
  bad: &amp;lt;code&amp;gt; prm_lkp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;method_that_allows_us_to_create_a_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
  good: &amp;lt;code&amp;gt;personnel_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_gis_layer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
&lt;br /&gt;
* Class names start with an uppercase letter.&lt;br /&gt;
* CamelCase is for class names only.&lt;br /&gt;
* Constant names are all-uppercase and with underscores as word separator.&lt;br /&gt;
* everything else (including table names and field names) should be all-lowercase with underscores as word separator.&lt;br /&gt;
* Names should not be Python keywords or standard library names&lt;br /&gt;
* Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)&lt;br /&gt;
* Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix &amp;quot;S3&amp;quot; (e.g. &amp;lt;code&amp;gt;AuthS3&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix &amp;quot;s3_&amp;quot; (e.g. &amp;lt;code&amp;gt;s3_logged_in()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Eden-specific classes &#039;&#039;can&#039;&#039; have an &amp;quot;S3&amp;quot; prefix to their name in order to avoid name collisions, but ideally they &#039;&#039;should not&#039;&#039; (i.e. &amp;lt;code&amp;gt;BasicCRUD&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;S3BasicCRUD&amp;lt;/code&amp;gt;)&lt;br /&gt;
* Method names in Eden-specific classes do not need to (and thus should not) be prefixed&lt;br /&gt;
* avoid &amp;quot;s3&amp;quot; or &amp;quot;S3&amp;quot; prefixes in all other cases&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DataModel&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; should start with the all-uppercase module prefix, e.g. &amp;lt;code&amp;gt;DVRCaseModel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CRUDMethod&amp;lt;/code&amp;gt; subclasses in &amp;lt;code&amp;gt;s3db&amp;lt;/code&amp;gt; must start with the all-lowercase module prefix plus underscore, e.g. &amp;lt;code&amp;gt;pr_Contacts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docstrings ===&lt;br /&gt;
&lt;br /&gt;
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used. &lt;br /&gt;
&lt;br /&gt;
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.&lt;br /&gt;
&lt;br /&gt;
Acceptable style:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Internationalisation ===&lt;br /&gt;
&lt;br /&gt;
* All user-visible strings and labels &#039;&#039;must&#039;&#039; be internationalised: &amp;lt;code&amp;gt;T(&amp;quot;My string&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exceptions ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Edenctl&amp;diff=297</id>
		<title>Guidelines:Edenctl</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Edenctl&amp;diff=297"/>
		<updated>2026-10-26T20:27:31Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Switching Templates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Guidelines:Deployment|All Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Server Administration with Edenctl =&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;edenctl&#039;&#039;&#039; tool is a &#039;&#039;bash&#039;&#039; script for Eden server administration on &#039;&#039;&#039;Debian/Linux&#039;&#039;&#039; that comes with the DEB-Packages of the Eden release. The general usage of this script is (as root user):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl [command] [parameters]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Commands Overview ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Explanation !! Comments&lt;br /&gt;
|-&lt;br /&gt;
| setup || Set up a newly installed Eden instance ||&lt;br /&gt;
|-&lt;br /&gt;
| teardown || Undo a completed setup ||&lt;br /&gt;
|-&lt;br /&gt;
| start || Start the web interface || &lt;br /&gt;
|-&lt;br /&gt;
| stop || Stop the web interface || &lt;br /&gt;
|-&lt;br /&gt;
| shell || Open a Python shell in the web2py+Eden environment || &lt;br /&gt;
|-&lt;br /&gt;
| run || Run a Python script in the web2py+Eden environment || &lt;br /&gt;
|-&lt;br /&gt;
| clean || Reset the Eden instance || &lt;br /&gt;
|-&lt;br /&gt;
| pull || Update Eden from GitHub || new in Eden-6.1&lt;br /&gt;
|-&lt;br /&gt;
| template || Switch to another configuration template || new in Eden-6.2&lt;br /&gt;
|-&lt;br /&gt;
| compile || (Re-)compile models, controllers and views || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Setup and Teardown ==&lt;br /&gt;
&lt;br /&gt;
To set up a newly installed Eden, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl setup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will run you step-by-step through the setup process. Enter your server details as prompted for (or click enter to accept the default value as shown in square brackets).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; The &#039;&#039;&#039;setup&#039;&#039;&#039; command will not work if the Eden instance has already been set up. To make changes in an already-configured instance, you must edit the configuration files manually.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Once completed, you can undo the setup with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl teardown&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; The &#039;&#039;&#039;teardown&#039;&#039;&#039; command will not drop the Eden database - this must be done manually.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Start and Stop ==&lt;br /&gt;
&lt;br /&gt;
After the setup, you can start the Eden web interface using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To stop the Eden web interface and thereby prevent user access, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl stop&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; the front-end web server is always running, so that it can deliver a maintenance info-page to the web user if Eden is not active - the &#039;&#039;&#039;start&#039;&#039;&#039; and &#039;&#039;&#039;stop&#039;&#039;&#039; commands only start/stop the uWSGI daemon.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Pull ==&lt;br /&gt;
&lt;br /&gt;
It is possible to upgrade your Eden instance directly from GitHub, using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl pull&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; It can be necessary to perform certain database migrations after the &#039;&#039;&#039;pull&#039;&#039;&#039; for Eden to work correctly - always check the release for migration advice.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Shell ==&lt;br /&gt;
&lt;br /&gt;
To open a Python shell in the web2py+Eden environment, you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl shell&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running Scripts ==&lt;br /&gt;
&lt;br /&gt;
To run a Python script in the web2py+Eden shell, use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl run /path/to/script.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clean ==&lt;br /&gt;
&lt;br /&gt;
You can reset the Eden database using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl clean&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will remove all data from the database, and perform a fresh &#039;&#039;&#039;first run&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; This operation is primarily intended for demos, and not recommended for production servers.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Switching Templates ==&lt;br /&gt;
&lt;br /&gt;
You can switch to a different template using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl template &amp;quot;TEMPLATE&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of a single template, you can also specify a template cascade as a comma-separated list of templates:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl template &amp;quot;TEMPLATE,TEMPLATE.SUB,TEMPLATE.SUB.Demo&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; After switching templates, you need to reset the instance using &amp;lt;code&amp;gt;edenctl clean&amp;lt;/code&amp;gt;.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Edenctl&amp;diff=296</id>
		<title>Guidelines:Edenctl</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Edenctl&amp;diff=296"/>
		<updated>2026-10-26T20:27:20Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Commands Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Guidelines:Deployment|All Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Server Administration with Edenctl =&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;edenctl&#039;&#039;&#039; tool is a &#039;&#039;bash&#039;&#039; script for Eden server administration on &#039;&#039;&#039;Debian/Linux&#039;&#039;&#039; that comes with the DEB-Packages of the Eden release. The general usage of this script is (as root user):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl [command] [parameters]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Commands Overview ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Explanation !! Comments&lt;br /&gt;
|-&lt;br /&gt;
| setup || Set up a newly installed Eden instance ||&lt;br /&gt;
|-&lt;br /&gt;
| teardown || Undo a completed setup ||&lt;br /&gt;
|-&lt;br /&gt;
| start || Start the web interface || &lt;br /&gt;
|-&lt;br /&gt;
| stop || Stop the web interface || &lt;br /&gt;
|-&lt;br /&gt;
| shell || Open a Python shell in the web2py+Eden environment || &lt;br /&gt;
|-&lt;br /&gt;
| run || Run a Python script in the web2py+Eden environment || &lt;br /&gt;
|-&lt;br /&gt;
| clean || Reset the Eden instance || &lt;br /&gt;
|-&lt;br /&gt;
| pull || Update Eden from GitHub || new in Eden-6.1&lt;br /&gt;
|-&lt;br /&gt;
| template || Switch to another configuration template || new in Eden-6.2&lt;br /&gt;
|-&lt;br /&gt;
| compile || (Re-)compile models, controllers and views || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Setup and Teardown ==&lt;br /&gt;
&lt;br /&gt;
To set up a newly installed Eden, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl setup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will run you step-by-step through the setup process. Enter your server details as prompted for (or click enter to accept the default value as shown in square brackets).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; The &#039;&#039;&#039;setup&#039;&#039;&#039; command will not work if the Eden instance has already been set up. To make changes in an already-configured instance, you must edit the configuration files manually.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Once completed, you can undo the setup with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl teardown&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; The &#039;&#039;&#039;teardown&#039;&#039;&#039; command will not drop the Eden database - this must be done manually.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Start and Stop ==&lt;br /&gt;
&lt;br /&gt;
After the setup, you can start the Eden web interface using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To stop the Eden web interface and thereby prevent user access, run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl stop&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; the front-end web server is always running, so that it can deliver a maintenance info-page to the web user if Eden is not active - the &#039;&#039;&#039;start&#039;&#039;&#039; and &#039;&#039;&#039;stop&#039;&#039;&#039; commands only start/stop the uWSGI daemon.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Pull ==&lt;br /&gt;
&lt;br /&gt;
It is possible to upgrade your Eden instance directly from GitHub, using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl pull&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; It can be necessary to perform certain database migrations after the &#039;&#039;&#039;pull&#039;&#039;&#039; for Eden to work correctly - always check the release for migration advice.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Shell ==&lt;br /&gt;
&lt;br /&gt;
To open a Python shell in the web2py+Eden environment, you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl shell&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running Scripts ==&lt;br /&gt;
&lt;br /&gt;
To run a Python script in the web2py+Eden shell, use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl run /path/to/script.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clean ==&lt;br /&gt;
&lt;br /&gt;
You can reset the Eden database using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl clean&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will remove all data from the database, and perform a fresh &#039;&#039;&#039;first run&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; This operation is primarily intended for demos, and not recommended for production servers.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Switching Templates ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;new in Eden-6.2 (not yet released)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can switch to a different template using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl template &amp;quot;TEMPLATE&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of a single template, you can also specify a template cascade as a comma-separated list of templates:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl template &amp;quot;TEMPLATE,TEMPLATE.SUB,TEMPLATE.SUB.Demo&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; After switching templates, you need to reset the instance using &amp;lt;code&amp;gt;edenctl clean&amp;lt;/code&amp;gt;.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:DualHost&amp;diff=295</id>
		<title>Guidelines:DualHost</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:DualHost&amp;diff=295"/>
		<updated>2026-10-26T20:25:43Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Dual Host Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Guidelines:Deployment|All Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Dual Host Setup =&lt;br /&gt;
&lt;br /&gt;
In certain situations, you may want to deploy Eden with the database on a separate host. Follow these steps for Debian/Linux:&lt;br /&gt;
&lt;br /&gt;
== Prerequisites and Terminology ==&lt;br /&gt;
&lt;br /&gt;
This guideline assumes that you have two hosts running on Debian/Linux - we will use the &#039;&#039;&#039;App Host&#039;&#039;&#039; and &#039;&#039;&#039;DB Host&#039;&#039;&#039; designations here to distinguish between the two.&lt;br /&gt;
&lt;br /&gt;
Further, we assume that each host has a &#039;&#039;&#039;public IP&#039;&#039;&#039; (exposed to the internet) and a &#039;&#039;&#039;private IP&#039;&#039;&#039; (local network only; in some intranet setups, public IP and private IP may be the same). Make a note  of the IPs, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apphost-public-ip 000.000.000.000&lt;br /&gt;
apphost-private-ip 000.000.000.000&lt;br /&gt;
dbhost-public-ip 000.000.000.000&lt;br /&gt;
dbhost-private-ip 000.000.000.000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...so that you have them readily at hand when walking through this guide. We will use designations like &#039;&#039;&amp;lt;apphost-public-ip&amp;gt;&#039;&#039;, for instance, to refer to the public IP of the App Host. In these places, replace the designation with the respective IP address.&lt;br /&gt;
&lt;br /&gt;
Make sure that you have a &#039;&#039;&#039;DNS A-record&#039;&#039;&#039; set up for the public IP of the App Host, e.g. in the &#039;&#039;&#039;FQDN&#039;&#039;&#039; (fully qualified domain name) &amp;quot;eden.example.com&amp;quot;, the &amp;quot;eden&amp;quot; part constitutes the &#039;&#039;&#039;hostname&#039;&#039;&#039;, and &amp;quot;example.com&amp;quot; the &#039;&#039;&#039;domain&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Eden Account ==&lt;br /&gt;
&lt;br /&gt;
Login to the DB Host and create a user account for Eden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
adduser eden&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;visudo&amp;lt;/code&amp;gt; to add the following lines to the &#039;&#039;sudoers&#039;&#039; configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# User rules for eden&lt;br /&gt;
eden ALL=(ALL) NOPASSWD:ALL&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will allow Eden to become &#039;&#039;root&#039;&#039; without password.&lt;br /&gt;
&lt;br /&gt;
== Configuring Key-based Login ==&lt;br /&gt;
&lt;br /&gt;
On your local machine, generate a new RSA key pair:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh-keygen -t rsa -m PEM -b 4096 -f eden -C &amp;quot;eden&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; Leave the password empty as this key is to be used for script automation&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This will generate two files, &#039;&#039;eden&#039;&#039; (=private key) and &#039;&#039;eden.pub&#039;&#039; (=public key), in the current directory. Install the public key on the DB Host:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat eden.pub | ssh eden@&amp;lt;dbhost-public-ip&amp;gt; &amp;quot;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy the private key to the App Host:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp eden admin@&amp;lt;apphost-public-ip&amp;gt;:/tmp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login to the App Host and store the key in a safe location:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo su -&lt;br /&gt;
cp /tmp/eden ~/.ssh&lt;br /&gt;
chown root.root ~/.ssh/eden&lt;br /&gt;
chmod 600 ~/.ssh/eden&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify that you can use this key to SSH-login from the App Host to the DB Host (via private IP), as user &#039;&#039;eden&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -i ~/.ssh/eden eden@&amp;lt;dbhost-private-ip&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PostgreSQL ==&lt;br /&gt;
&lt;br /&gt;
=== Installing PostgreSQL ===&lt;br /&gt;
&lt;br /&gt;
On the DB Host, make yourself &#039;&#039;root&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo su -&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then install PostgreSQL and PostGIS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y postgresql-17 postgresql-17-postgis-3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring Host-based Access ===&lt;br /&gt;
&lt;br /&gt;
You need to tell PostgreSQL that the App Host is permitted to access the DB server. To do so, edit the file &amp;lt;code&amp;gt;/etc/postgresql/17/main/pg_hba.conf&amp;lt;/code&amp;gt;, adding the following lines at the end (using the private IP of the App Host):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Eden App Host&lt;br /&gt;
host    all    all    &amp;lt;apphost-private-ip&amp;gt;/32   md5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; if your DB Host is behind a firewall, access from this IP/subnet to the port 5432 must be allowed. Adjust your firewall configuration as necessary.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Further, you must tell PostgreSQL to listen on the private IP of the DB Host. For that, edit the file &amp;lt;code&amp;gt;/etc/postgresql/17/main/postgresql.conf&amp;lt;/code&amp;gt;, and modify the &amp;lt;code&amp;gt;listen_address&amp;lt;/code&amp;gt; setting, adding the private IP of the DB Host:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
listen_address = &#039;&amp;lt;dbhost-private-ip&amp;gt;,localhost&#039; # what IP address(es) to listen on;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, restart PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl restart postgresql&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logout from the DB Host, going back to the App Host.&lt;br /&gt;
&lt;br /&gt;
== Eden ==&lt;br /&gt;
&lt;br /&gt;
=== Installing Release Package ===&lt;br /&gt;
&lt;br /&gt;
Copy the Eden DEB-package to the App Host - either using &amp;lt;code&amp;gt;scp&amp;lt;/code&amp;gt; from your local machine, or &amp;lt;code&amp;gt;wget&amp;lt;/code&amp;gt; to fetch it from GitHub, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /tmp&lt;br /&gt;
wget https://github.com/sahana/eden/releases/download/6.2/sahana-eden-debian13_6.2-1_all.deb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039; The actual location and name of the package depends on the release - check on GitHub for the latest available package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Login to the App Host and make yourself &#039;&#039;root&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo su -&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install the package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -f /tmp/sahana-eden-debian13_6.2-1_all.deb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring DB Host ===&lt;br /&gt;
&lt;br /&gt;
Create a file &amp;lt;code&amp;gt;/etc/sahana/dbhost.conf&amp;lt;/code&amp;gt;, with the details of the DB Host, so that &#039;&#039;edenctl&#039;&#039; can login there:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; line&amp;gt;&lt;br /&gt;
DBHOST=&amp;lt;dbhost-private-ip&amp;gt;&lt;br /&gt;
DBHOST_USER=eden&lt;br /&gt;
DBHOST_KEY=/root/.ssh/eden&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup with Edenctl ===&lt;br /&gt;
&lt;br /&gt;
After that, you can set up the Eden instance as usual:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl setup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eventually, start the Eden instance with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
edenctl start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=294</id>
		<title>Blueprint:InlineValueSet</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=294"/>
		<updated>2026-10-23T08:59:32Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Solution Ideas / Proposals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Blueprint:Index|All Blueprints]]&lt;br /&gt;
&lt;br /&gt;
== Inline Components with Specifications from a third Table ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).&lt;br /&gt;
&lt;br /&gt;
One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/permitted ranges:&lt;br /&gt;
&lt;br /&gt;
* Master: &amp;lt;code&amp;gt;med_analysis&amp;lt;/code&amp;gt;&lt;br /&gt;
* Component: &amp;lt;code&amp;gt;med_analysis_result&amp;lt;/code&amp;gt;&lt;br /&gt;
* Specification: &amp;lt;code&amp;gt;med_parameter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems ===&lt;br /&gt;
&lt;br /&gt;
While the current &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; concept can facilitate the inline data entry for components, it cannot be configured to use specifications from a third table to build the sub-form rows. Validation is done against the component table model alone, without taking constraints from a third table into account.&lt;br /&gt;
&lt;br /&gt;
Additionally, &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; does not limit the sub-form to a fixed set of specifications - any number of records, including multiple of the same type, can be added. Selection of sub-form rows from a set of specifications is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Analysis / Requirements ===&lt;br /&gt;
&lt;br /&gt;
We want a SubForm implementation that&lt;br /&gt;
&lt;br /&gt;
* generates a list of specifications (parameters) that can be selected by the user for data entry (and de-select, if necessary), permitting only one sub-record per spec&lt;br /&gt;
* support the display of additional information about the selectable specs (parameters), such as normal ranges or instructions&lt;br /&gt;
* reads these specification from a third table, including validation constraints for each individual parameter, using them to provide a suitable input field (varying SELECT or text-INPUT) and validate the input&lt;br /&gt;
* creates or updates the sub-records upon form submission, de-duplicating them by specification (parameter), so that only one record per spec can exist (or zero)&lt;br /&gt;
* supports at least one value-field, as well as additional fields for status or references (which could be boolean or choice)&lt;br /&gt;
* can be embedded and configured in &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt; declarations, like &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt;&lt;br /&gt;
* (possibly) supports a workflow separation, where the initial planning stage allows the selection of parameters, while a later data entry stage only allows the entry of values into already selected parameters (i.e. hiding the selector); reading the current stage/mode either from the master table, or determining it from user permissions (CREATE+UPDATE vs UPDATE-only), or both&lt;br /&gt;
&lt;br /&gt;
=== Solution Ideas / Proposals ===&lt;br /&gt;
[https://github.com/sahana/eden/blob/dev/modules/core/methods/dseries.py &#039;&#039;&#039;DataSeriesForm&#039;&#039;&#039;] is a draft implementation of a widget that renders a form with selectable specifications for sub-record rows. This design has the widget control the entire form rather than only the sub-record rows, and is tailored to the &#039;&#039;med_analysis&#039;&#039; use-case rather than generic.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DataSeriesForm&amp;lt;/code&amp;gt; design could be morphed into a &amp;lt;code&amp;gt;SubForm&amp;lt;/code&amp;gt; (proposed class name: &#039;&#039;InlineValueSet&#039;&#039;) that can be embedded in a &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt;, where it would only control the sub-record rows, analogous to &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;InlineLink&amp;lt;/code&amp;gt;. The client-side control script could use Ajax to retrieve the specifications and validate input via either an extended &amp;lt;code&amp;gt;BasicCRUD.validate&amp;lt;/code&amp;gt; or a new, specific end-point. Further, it could be generalized to cover use-cases beyond &#039;&#039;med_analysis&#039;&#039;, including supporting configurable secondary fields and workflow separation.&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
=== Feedback ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=293</id>
		<title>Blueprint:InlineValueSet</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=293"/>
		<updated>2026-10-23T08:58:00Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Solution Ideas / Proposals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Blueprint:Index|All Blueprints]]&lt;br /&gt;
&lt;br /&gt;
== Inline Components with Specifications from a third Table ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).&lt;br /&gt;
&lt;br /&gt;
One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/permitted ranges:&lt;br /&gt;
&lt;br /&gt;
* Master: &amp;lt;code&amp;gt;med_analysis&amp;lt;/code&amp;gt;&lt;br /&gt;
* Component: &amp;lt;code&amp;gt;med_analysis_result&amp;lt;/code&amp;gt;&lt;br /&gt;
* Specification: &amp;lt;code&amp;gt;med_parameter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems ===&lt;br /&gt;
&lt;br /&gt;
While the current &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; concept can facilitate the inline data entry for components, it cannot be configured to use specifications from a third table to build the sub-form rows. Validation is done against the component table model alone, without taking constraints from a third table into account.&lt;br /&gt;
&lt;br /&gt;
Additionally, &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; does not limit the sub-form to a fixed set of specifications - any number of records, including multiple of the same type, can be added. Selection of sub-form rows from a set of specifications is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Analysis / Requirements ===&lt;br /&gt;
&lt;br /&gt;
We want a SubForm implementation that&lt;br /&gt;
&lt;br /&gt;
* generates a list of specifications (parameters) that can be selected by the user for data entry (and de-select, if necessary), permitting only one sub-record per spec&lt;br /&gt;
* support the display of additional information about the selectable specs (parameters), such as normal ranges or instructions&lt;br /&gt;
* reads these specification from a third table, including validation constraints for each individual parameter, using them to provide a suitable input field (varying SELECT or text-INPUT) and validate the input&lt;br /&gt;
* creates or updates the sub-records upon form submission, de-duplicating them by specification (parameter), so that only one record per spec can exist (or zero)&lt;br /&gt;
* supports at least one value-field, as well as additional fields for status or references (which could be boolean or choice)&lt;br /&gt;
* can be embedded and configured in &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt; declarations, like &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt;&lt;br /&gt;
* (possibly) supports a workflow separation, where the initial planning stage allows the selection of parameters, while a later data entry stage only allows the entry of values into already selected parameters (i.e. hiding the selector); reading the current stage/mode either from the master table, or determining it from user permissions (CREATE+UPDATE vs UPDATE-only), or both&lt;br /&gt;
&lt;br /&gt;
=== Solution Ideas / Proposals ===&lt;br /&gt;
[https://github.com/sahana/eden/blob/dev/modules/core/methods/dseries.py &#039;&#039;&#039;DataSeriesForm&#039;&#039;&#039;] is a draft implementation of a widget that renders a form with selectable specifications for sub-record rows. This design has the widget control the entire form rather than only the sub-record rows, and is tailored to the med_analysis use-case rather than generic.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DataSeriesForm&amp;lt;/code&amp;gt; design could be morphed into a &amp;lt;code&amp;gt;SubForm&amp;lt;/code&amp;gt; (proposed class name: &#039;&#039;InlineValueSet&#039;&#039;) that can be embedded in a &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt;, where it would only control the sub-record rows, analogous to &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;InlineLink&amp;lt;/code&amp;gt;. The client-side control script could use Ajax to retrieve the specifications and validate input via either an extended &amp;lt;code&amp;gt;BasicCRUD.validate&amp;lt;/code&amp;gt; or a new, specific end-point.&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
=== Feedback ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=292</id>
		<title>Blueprint:InlineValueSet</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=292"/>
		<updated>2026-10-23T08:36:44Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Analysis / Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Blueprint:Index|All Blueprints]]&lt;br /&gt;
&lt;br /&gt;
== Inline Components with Specifications from a third Table ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).&lt;br /&gt;
&lt;br /&gt;
One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/permitted ranges:&lt;br /&gt;
&lt;br /&gt;
* Master: &amp;lt;code&amp;gt;med_analysis&amp;lt;/code&amp;gt;&lt;br /&gt;
* Component: &amp;lt;code&amp;gt;med_analysis_result&amp;lt;/code&amp;gt;&lt;br /&gt;
* Specification: &amp;lt;code&amp;gt;med_parameter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems ===&lt;br /&gt;
&lt;br /&gt;
While the current &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; concept can facilitate the inline data entry for components, it cannot be configured to use specifications from a third table to build the sub-form rows. Validation is done against the component table model alone, without taking constraints from a third table into account.&lt;br /&gt;
&lt;br /&gt;
Additionally, &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; does not limit the sub-form to a fixed set of specifications - any number of records, including multiple of the same type, can be added. Selection of sub-form rows from a set of specifications is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Analysis / Requirements ===&lt;br /&gt;
&lt;br /&gt;
We want a SubForm implementation that&lt;br /&gt;
&lt;br /&gt;
* generates a list of specifications (parameters) that can be selected by the user for data entry (and de-select, if necessary), permitting only one sub-record per spec&lt;br /&gt;
* support the display of additional information about the selectable specs (parameters), such as normal ranges or instructions&lt;br /&gt;
* reads these specification from a third table, including validation constraints for each individual parameter, using them to provide a suitable input field (varying SELECT or text-INPUT) and validate the input&lt;br /&gt;
* creates or updates the sub-records upon form submission, de-duplicating them by specification (parameter), so that only one record per spec can exist (or zero)&lt;br /&gt;
* supports at least one value-field, as well as additional fields for status or references (which could be boolean or choice)&lt;br /&gt;
* can be embedded and configured in &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt; declarations, like &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt;&lt;br /&gt;
* (possibly) supports a workflow separation, where the initial planning stage allows the selection of parameters, while a later data entry stage only allows the entry of values into already selected parameters (i.e. hiding the selector); reading the current stage/mode either from the master table, or determining it from user permissions (CREATE+UPDATE vs UPDATE-only), or both&lt;br /&gt;
&lt;br /&gt;
=== Solution Ideas / Proposals ===&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
=== Feedback ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=291</id>
		<title>Blueprint:InlineValueSet</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=291"/>
		<updated>2026-10-23T08:35:45Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Analysis / Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Blueprint:Index|All Blueprints]]&lt;br /&gt;
&lt;br /&gt;
== Inline Components with Specifications from a third Table ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).&lt;br /&gt;
&lt;br /&gt;
One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/permitted ranges:&lt;br /&gt;
&lt;br /&gt;
* Master: &amp;lt;code&amp;gt;med_analysis&amp;lt;/code&amp;gt;&lt;br /&gt;
* Component: &amp;lt;code&amp;gt;med_analysis_result&amp;lt;/code&amp;gt;&lt;br /&gt;
* Specification: &amp;lt;code&amp;gt;med_parameter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems ===&lt;br /&gt;
&lt;br /&gt;
While the current &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; concept can facilitate the inline data entry for components, it cannot be configured to use specifications from a third table to build the sub-form rows. Validation is done against the component table model alone, without taking constraints from a third table into account.&lt;br /&gt;
&lt;br /&gt;
Additionally, &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; does not limit the sub-form to a fixed set of specifications - any number of records, including multiple of the same type, can be added. Selection of sub-form rows from a set of specifications is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Analysis / Requirements ===&lt;br /&gt;
&lt;br /&gt;
We want a SubForm implementation that&lt;br /&gt;
&lt;br /&gt;
* generates a list of specifications (parameters) that can be selected by the user for data entry (and de-select, if necessary), permitting only one sub-record per spec&lt;br /&gt;
* support the display of additional information about the selectable specs (parameters), such as normal ranges or instructions&lt;br /&gt;
* reads these specification from a third table, including validation constraints for each individual parameter, using them to provide a suitable input field (varying SELECT or text-INPUT) and validate the input&lt;br /&gt;
* creates or updates the sub-records upon form submission, de-duplicating them by specification (parameter), so that only one record per spec can exist (or zero)&lt;br /&gt;
* supports at least one value-field, as well as additional fields for status or references (which could be boolean or choice)&lt;br /&gt;
* can be embedded and configured in &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt; declarations, like &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt;&lt;br /&gt;
* (possibly) supports a stage separation, where the initial planning stage allows the selection of parameters, while a later data entry stage only allows the entry of values into already selected parameters (i.e. hiding the selector); reading the current stage/mode from the master table, or from user permissions (CREATE+UPDATE vs UPDATE-only)&lt;br /&gt;
&lt;br /&gt;
=== Solution Ideas / Proposals ===&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
=== Feedback ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=290</id>
		<title>Blueprint:InlineValueSet</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=290"/>
		<updated>2026-10-23T08:30:32Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Blueprint:Index|All Blueprints]]&lt;br /&gt;
&lt;br /&gt;
== Inline Components with Specifications from a third Table ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).&lt;br /&gt;
&lt;br /&gt;
One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/permitted ranges:&lt;br /&gt;
&lt;br /&gt;
* Master: &amp;lt;code&amp;gt;med_analysis&amp;lt;/code&amp;gt;&lt;br /&gt;
* Component: &amp;lt;code&amp;gt;med_analysis_result&amp;lt;/code&amp;gt;&lt;br /&gt;
* Specification: &amp;lt;code&amp;gt;med_parameter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems ===&lt;br /&gt;
&lt;br /&gt;
While the current &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; concept can facilitate the inline data entry for components, it cannot be configured to use specifications from a third table to build the sub-form rows. Validation is done against the component table model alone, without taking constraints from a third table into account.&lt;br /&gt;
&lt;br /&gt;
Additionally, &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; does not limit the sub-form to a fixed set of specifications - any number of records, including multiple of the same type, can be added. Selection of sub-form rows from a set of specifications is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Analysis / Requirements ===&lt;br /&gt;
&lt;br /&gt;
We want a SubForm implementation that&lt;br /&gt;
&lt;br /&gt;
* generates a list of specifications (parameters) that can be selected by the user for data entry (and de-selected), permitting only one sub-record per spec&lt;br /&gt;
* reads these specification from a third table, including validation constraints for each individual parameter, using them to provide a suitable input field (varying SELECT or text-INPUT) and validate the input&lt;br /&gt;
* creates or updates the sub-records upon form submission, de-duplicating them by specification (parameter), so that only one record per spec can exist (or zero)&lt;br /&gt;
* supports at least one value-field, as well as additional fields for status or references (which could be boolean or choice)&lt;br /&gt;
* can be embedded and configured in &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt; declarations, like &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Solution Ideas / Proposals ===&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
=== Feedback ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=289</id>
		<title>Blueprint:InlineValueSet</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=289"/>
		<updated>2026-10-23T08:29:21Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Blueprint:Index|All Blueprints]]&lt;br /&gt;
&lt;br /&gt;
== Inline Components with Specifications from a third Table ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).&lt;br /&gt;
&lt;br /&gt;
One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/permitted ranges:&lt;br /&gt;
&lt;br /&gt;
* Master: &amp;lt;code&amp;gt;med_analysis&amp;lt;/code&amp;gt;&lt;br /&gt;
* Component: &amp;lt;code&amp;gt;med_analysis_result&amp;lt;/code&amp;gt;&lt;br /&gt;
* Specification: &amp;lt;code&amp;gt;med_parameter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems ===&lt;br /&gt;
&lt;br /&gt;
While the current &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; concept can facilitate the inline data entry for components, it cannot be configured to use specifications from a third table to build the sub-form rows. Validation is done against the component table model alone, without taking constraints from a third table into account.&lt;br /&gt;
&lt;br /&gt;
Additionally, &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; does not limit the sub-form to a fixed set of specifications - any number of records, including multiple of the same type, can be added.&lt;br /&gt;
&lt;br /&gt;
=== Analysis / Requirements ===&lt;br /&gt;
&lt;br /&gt;
We want a SubForm implementation that&lt;br /&gt;
&lt;br /&gt;
* generates a list of specifications (parameters) that can be selected by the user for data entry (and de-selected), permitting only one sub-record per spec&lt;br /&gt;
* reads these specification from a third table, including validation constraints for each individual parameter, using them to provide a suitable input field (varying SELECT or text-INPUT) and validate the input&lt;br /&gt;
* creates or updates the sub-records upon form submission, de-duplicating them by specification (parameter), so that only one record per spec can exist (or zero)&lt;br /&gt;
* supports at least one value-field, as well as additional fields for status or references (which could be boolean or choice)&lt;br /&gt;
* can be embedded and configured in &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt; declarations, like &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Solution Ideas / Proposals ===&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
=== Feedback ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=288</id>
		<title>Blueprint:InlineValueSet</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:InlineValueSet&amp;diff=288"/>
		<updated>2026-10-23T08:27:02Z</updated>

		<summary type="html">&lt;p&gt;Dominic: Created page with &amp;quot;* All Blueprints  == Inline Components with Specifications from a third Table ==  === Background ===  Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).  One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/p...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Blueprint:Index|All Blueprints]]&lt;br /&gt;
&lt;br /&gt;
== Inline Components with Specifications from a third Table ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
Certain data models define semi-abstract components, with concrete specifications and constraints for the component data determined by records in a third table (spec table).&lt;br /&gt;
&lt;br /&gt;
One example are medical analyses (e.g. blood tests), where the concrete analysis results that can be recorded are specified in a third table, including data types and plausible/permitted ranges:&lt;br /&gt;
&lt;br /&gt;
* Master: &amp;lt;code&amp;gt;med_analysis&amp;lt;/code&amp;gt;&lt;br /&gt;
* Component: &amp;lt;code&amp;gt;med_analysis_result&amp;lt;/code&amp;gt;&lt;br /&gt;
* Specification: &amp;lt;code&amp;gt;med_parameter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems ===&lt;br /&gt;
&lt;br /&gt;
Wile the current &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; concept can facilitate the inline data entry for components, it cannot be configured to use specifications from a third table to build the sub-form rows. Validation is done against the component table model alone, without taking constraints from a third table into account.&lt;br /&gt;
&lt;br /&gt;
Additionally, &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt; does not limit the sub-form to a fixed set of specifications - any number of records, including multiple of the same type, can be added.&lt;br /&gt;
&lt;br /&gt;
=== Analysis / Requirements ===&lt;br /&gt;
&lt;br /&gt;
We want a SubForm implementation that&lt;br /&gt;
&lt;br /&gt;
* generates a list of specifications (parameters) that can be selected by the user for data entry (and de-selected), permitting only one sub-record per spec&lt;br /&gt;
* reads these specification from a third table, including validation constraints for each individual parameter, using them to provide a suitable input field (varying SELECT or text-INPUT) and validate the input&lt;br /&gt;
* creates or updates the sub-records upon form submission, de-duplicating them by specification (parameter), so that only one record per spec can exist (or zero)&lt;br /&gt;
* supports at least one value-field, as well as additional fields for status or references (which could be boolean or choice)&lt;br /&gt;
* can be embedded and configured in &amp;lt;code&amp;gt;CustomCRUDForm&amp;lt;/code&amp;gt; declarations, like &amp;lt;code&amp;gt;InlineComponent&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Solution Ideas / Proposals ===&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
&lt;br /&gt;
=== Feedback ===&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Blueprint:Index&amp;diff=287</id>
		<title>Blueprint:Index</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Blueprint:Index&amp;diff=287"/>
		<updated>2026-10-23T08:02:16Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Blueprint Index =&lt;br /&gt;
&lt;br /&gt;
This is a list of Blueprints on this wiki:&lt;br /&gt;
&lt;br /&gt;
== Implemented ==&lt;br /&gt;
&lt;br /&gt;
These blueprints have been implemented, with features currently in productive use. Those marked with an asterisk (*) may need maintenance or an overhaul:&lt;br /&gt;
&lt;br /&gt;
* [[Blueprint:MapViewer]]&lt;br /&gt;
&lt;br /&gt;
== Under Development ==&lt;br /&gt;
&lt;br /&gt;
These are blueprints currently being implemented. The teams implementing them may be looking for additional hands - look out for GitHub issues relating to them, or simply ask on the mailing list:&lt;br /&gt;
&lt;br /&gt;
=== Methodology ===&lt;br /&gt;
* [[Blueprint:Blueprint]] - Purpose and Structure of Blueprints&lt;br /&gt;
&lt;br /&gt;
=== Feature Sets ===&lt;br /&gt;
* [[Blueprint:FailedLogins]] - Handling of failed logins&lt;br /&gt;
* [[Blueprint:InlineValueSet]] - Inline component data entry with constraints set by a third table&lt;br /&gt;
&lt;br /&gt;
== Accepted ==&lt;br /&gt;
&lt;br /&gt;
These are blueprints that have been accepted, and are looking for a team to implement them. If you are interested to take the lead on any of these, you can just start working on it and/or ask on the mailing list for further guidance:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;tbw&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Proposed ==&lt;br /&gt;
&lt;br /&gt;
These blueprints have been proposed but not yet considered for implementation, because they may need more research and refinement. If you want to discuss these, just do so on the mailing list:&lt;br /&gt;
&lt;br /&gt;
* [[Blueprint:ObsTable]] - Observation Tables, a monitoring and decision support tool&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Deployment&amp;diff=286</id>
		<title>Guidelines:Deployment</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Deployment&amp;diff=286"/>
		<updated>2026-09-28T07:48:53Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Installation and Setup =&lt;br /&gt;
&lt;br /&gt;
== Installation from Release Package ==&lt;br /&gt;
&lt;br /&gt;
As of version 6.0, Eden provides packaged releases. This is the recommended setup method for production servers. The packages are available as assets attached to the respective GitHub release.&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:DebianPackages|Installation on Debian/Linux]]&lt;br /&gt;
* [[Guidelines:DualHost|Installation on Debian/Linux with separate DB Host]]&lt;br /&gt;
* [[Guidelines:Edenctl|Server Setup and Management with edenctl]]&lt;br /&gt;
* [[Guidelines:SecureOperation|SSH Setup Recommendations]]&lt;br /&gt;
&lt;br /&gt;
== Installation from GitHub Repository ==&lt;br /&gt;
&lt;br /&gt;
It is also possible to install Eden directly from a GitHub repository. This option is recommended for demos and UAT, where you want to install a development version.&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:InstallationScripts|Installation and Configuration scripts for Debian/Linux]]&lt;br /&gt;
* [[Guidelines:ServiceScripts|Server Setup and Management using traditional Service Scripts]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=285</id>
		<title>Guidelines:AI</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=285"/>
		<updated>2026-09-28T07:48:39Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Guidelines:Index|All Guidelines]]&lt;br /&gt;
&lt;br /&gt;
= Policy for Responsible AI Contributions =&lt;br /&gt;
&lt;br /&gt;
We welcome AI-generated, -assisted, or -embedded contributions, provided they&lt;br /&gt;
adhere to the following criteria:&lt;br /&gt;
&lt;br /&gt;
=== 1. Clear Identification ===&lt;br /&gt;
&lt;br /&gt;
Contributions are explicitly labeled as AI-generated, -assisted, or -embedded, including unambiguous disclosure of the AI systems involved, the organizations providing and operating these systems, and the specific infrastructure used.&lt;br /&gt;
&lt;br /&gt;
=== 2. Legal and Licensing Compliance ===&lt;br /&gt;
&lt;br /&gt;
The organizations responsible for providing and operating the AI technology have signed a &#039;&#039;Contributor License Agreement&#039;&#039; granting the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039; unrestricted and irrevocable licenses over the contributions. These agreements include assurances that such organizations are legally entitled to sublicense their rights.&lt;br /&gt;
&lt;br /&gt;
=== 3. Alignment with Goals and Mission ===&lt;br /&gt;
&lt;br /&gt;
Contributions align with the immediate objectives of the &#039;&#039;&#039;Eden&#039;&#039;&#039; project and support the broader mission of the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 4. Transparent Reasoning ===&lt;br /&gt;
&lt;br /&gt;
Each contribution is accompanied by a sufficiently detailed, human-understandable rationale, which is reviewed, comprehended, and accepted by the human developer community.&lt;br /&gt;
&lt;br /&gt;
=== 5. Fair Recognition and Compensation ===&lt;br /&gt;
&lt;br /&gt;
Contributions transparently credit any human efforts or prior art involved and&lt;br /&gt;
do not undermine fair compensation where such remuneration was initially intended.&lt;br /&gt;
&lt;br /&gt;
=== 6. Respect for Human Contributors and Oversight ===&lt;br /&gt;
&lt;br /&gt;
The scale, pace, or impact of AI contributions must not overwhelm or displace human reviewers and contributors. They should not diminish the capacity for human oversight, scrutiny, and understanding nor undermine human efforts to study, develop, maintain, or implement &#039;&#039;&#039;Eden&#039;&#039;&#039;-based solutions. AI contributions should support, not hinder, meaningful human engagement and the sustainable oversight of the project.&lt;br /&gt;
&lt;br /&gt;
=== 7. Avoidance of Proprietary Dependencies and Ethical Concerns ===&lt;br /&gt;
&lt;br /&gt;
Contributions do not introduce dependencies on proprietary technologies or services, or on such technologies and services that contribute to or exacerbate the humanitarian challenges that the Eden project aims to address.&lt;br /&gt;
&lt;br /&gt;
=== 8. Non-Discrimination ===&lt;br /&gt;
&lt;br /&gt;
Contributions must not introduce or perpetuate discrimination against any group based on background, condition or identity, particularly regarding project accessibility and participation.&lt;br /&gt;
&lt;br /&gt;
=== 9. Alignment with Sustainable Development Goals ===&lt;br /&gt;
&lt;br /&gt;
The resource consumption, structural design, and operational framework of the AI technologies used must be fully verifiable as supporting the [https://sdgs.un.org/goals UN Sustainable Development Goals], ensuring progress in one area does not come at the expense of others.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:Index&amp;diff=284</id>
		<title>Guidelines:Index</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:Index&amp;diff=284"/>
		<updated>2026-09-28T07:48:13Z</updated>

		<summary type="html">&lt;p&gt;Dominic: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Implementer Guidelines ==&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Contributor Guidelines ==&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
* [[Guidelines:AI|Guideline for Responsible AI Contributions]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=283</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=283"/>
		<updated>2026-09-28T07:47:33Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Project Conventions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Sahana Eden&#039;&#039;&#039; is an &#039;&#039;Application Development Kit&#039;&#039; designed to build database-driven web applications tailored for emergency and humanitarian management. It provides a robust foundation for application developers and IT service providers to meet the information management needs of aid organizations and governmental agencies during emergencies, disaster preparedness, and humanitarian operations.&lt;br /&gt;
&lt;br /&gt;
Eden is &#039;&#039;&#039;free and open-source software&#039;&#039;&#039; (FOSS) that can be freely used, modified, extended, and integrated by anyone without restrictions.&lt;br /&gt;
&lt;br /&gt;
As an open project, Eden fosters collaboration and the exchange of knowledge, experiences, and best practices among humanitarian organizations. The project is guided by input from experienced aid organizations worldwide and emphasizes the use of open technology and standards. Nearly all of Eden’s code is developed in close cooperation with humanitarians in the field, ensuring it is directly aligned with real-world needs.&lt;br /&gt;
&lt;br /&gt;
== Implementing Eden ==&lt;br /&gt;
&lt;br /&gt;
Sahana Eden is a multi-purpose &#039;&#039;web application&#039;&#039; written for the [https://web2py.com web2py] framework. &lt;br /&gt;
&lt;br /&gt;
The appearance and business logic of this application can be adjusted to the needs of a particular deployment by altering settings in the &amp;lt;code&amp;gt;models/000_config.py&amp;lt;/code&amp;gt; configuration file on the server. Such adjustments can be minimal, or (more commonly) be extensive customization involving menus, forms, user roles, workflows, data models and even processing logic - so that Eden can be repurposed and adapted for many different use-cases and scenarios.&lt;br /&gt;
&lt;br /&gt;
Rather than putting all these customizations into one server-side configuration file, they would normally be implemented as Python packages which are then imported as &#039;&#039;&#039;configuration templates&#039;&#039;&#039;. This way, complex custom configurations can be developed, tested and maintained away from the server - and can easily be shared and re-used in other deployments.&lt;br /&gt;
&lt;br /&gt;
An &#039;&#039;&#039;Eden application&#039;&#039;&#039; is understood as such a re-usable configuration template (or a combination of templates), and &#039;&#039;&#039;Application Development&#039;&#039;&#039; is focused on these templates. &lt;br /&gt;
&lt;br /&gt;
A small selection of configuration templates is included in the Eden code base. However, downstream projects will often develop their own templates, and may publish and/or market them independently - a business model which we encourage and support.&lt;br /&gt;
&lt;br /&gt;
== Deploying Eden ==&lt;br /&gt;
&lt;br /&gt;
=== Installation and Setup ===&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== How to Contribute ==&lt;br /&gt;
&lt;br /&gt;
=== What to Do ===&lt;br /&gt;
&lt;br /&gt;
==== Code ====&lt;br /&gt;
* [https://github.com/sahana/eden/issues Issues] are a good starting point for  short-term contribution&lt;br /&gt;
* [[Blueprint:Index|Blueprints]] describe more complex feature sets and requirements, best suited for longer-term contribution&lt;br /&gt;
* Many core modules are looking for a maintainer, who takes long-term overall responsibility for their continuous development, support and documentation. Tell us on our [https://groups.google.com/g/eden-asp mailing list] what you would be interested in leading, and we will guide you to the role.&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
* Our [https://eden-asp.readthedocs.io/en/latest Handbook for Application Developers] needs continuous maintenance and improvement. You can work on the handbook in the [https://github.com/sahana/eden/tree/dev/docs/source code base].&lt;br /&gt;
* If you want to contribute to this wiki, you can start by discussing your idea on our [https://groups.google.com/g/eden-asp mailing list] - we will then create a wiki account for you as needed.&lt;br /&gt;
&lt;br /&gt;
=== Information Resources ===&lt;br /&gt;
&lt;br /&gt;
* [[Code Repository]]&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
&lt;br /&gt;
=== Project Conventions ===&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:AI|Policy for Responsible AI Contributions]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=282</id>
		<title>Guidelines:AI</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=282"/>
		<updated>2026-09-28T07:47:09Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Policy for Responsible AI Contributions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Policy for Responsible AI Contributions =&lt;br /&gt;
&lt;br /&gt;
We welcome AI-generated, -assisted, or -embedded contributions, provided they&lt;br /&gt;
adhere to the following criteria:&lt;br /&gt;
&lt;br /&gt;
=== 1. Clear Identification ===&lt;br /&gt;
&lt;br /&gt;
Contributions are explicitly labeled as AI-generated, -assisted, or -embedded, including unambiguous disclosure of the AI systems involved, the organizations providing and operating these systems, and the specific infrastructure used.&lt;br /&gt;
&lt;br /&gt;
=== 2. Legal and Licensing Compliance ===&lt;br /&gt;
&lt;br /&gt;
The organizations responsible for providing and operating the AI technology have signed a &#039;&#039;Contributor License Agreement&#039;&#039; granting the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039; unrestricted and irrevocable licenses over the contributions. These agreements include assurances that such organizations are legally entitled to sublicense their rights.&lt;br /&gt;
&lt;br /&gt;
=== 3. Alignment with Goals and Mission ===&lt;br /&gt;
&lt;br /&gt;
Contributions align with the immediate objectives of the &#039;&#039;&#039;Eden&#039;&#039;&#039; project and support the broader mission of the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 4. Transparent Reasoning ===&lt;br /&gt;
&lt;br /&gt;
Each contribution is accompanied by a sufficiently detailed, human-understandable rationale, which is reviewed, comprehended, and accepted by the human developer community.&lt;br /&gt;
&lt;br /&gt;
=== 5. Fair Recognition and Compensation ===&lt;br /&gt;
&lt;br /&gt;
Contributions transparently credit any human efforts or prior art involved and&lt;br /&gt;
do not undermine fair compensation where such remuneration was initially intended.&lt;br /&gt;
&lt;br /&gt;
=== 6. Respect for Human Contributors and Oversight ===&lt;br /&gt;
&lt;br /&gt;
The scale, pace, or impact of AI contributions must not overwhelm or displace human reviewers and contributors. They should not diminish the capacity for human oversight, scrutiny, and understanding nor undermine human efforts to study, develop, maintain, or implement &#039;&#039;&#039;Eden&#039;&#039;&#039;-based solutions. AI contributions should support, not hinder, meaningful human engagement and the sustainable oversight of the project.&lt;br /&gt;
&lt;br /&gt;
=== 7. Avoidance of Proprietary Dependencies and Ethical Concerns ===&lt;br /&gt;
&lt;br /&gt;
Contributions do not introduce dependencies on proprietary technologies or services, or on such technologies and services that contribute to or exacerbate the humanitarian challenges that the Eden project aims to address.&lt;br /&gt;
&lt;br /&gt;
=== 8. Non-Discrimination ===&lt;br /&gt;
&lt;br /&gt;
Contributions must not introduce or perpetuate discrimination against any group based on background, condition or identity, particularly regarding project accessibility and participation.&lt;br /&gt;
&lt;br /&gt;
=== 9. Alignment with Sustainable Development Goals ===&lt;br /&gt;
&lt;br /&gt;
The resource consumption, structural design, and operational framework of the AI technologies used must be fully verifiable as supporting the [https://sdgs.un.org/goals UN Sustainable Development Goals], ensuring progress in one area does not come at the expense of others.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=281</id>
		<title>Guidelines:AI</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=281"/>
		<updated>2026-09-16T16:00:44Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* 9. Alignment with Sustainable Development Goals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Policy for Responsible AI Contributions (Draft Version) =&lt;br /&gt;
&lt;br /&gt;
We welcome AI-generated, -assisted, or -embedded contributions, provided they&lt;br /&gt;
adhere to the following criteria:&lt;br /&gt;
&lt;br /&gt;
=== 1. Clear Identification ===&lt;br /&gt;
&lt;br /&gt;
Contributions are explicitly labeled as AI-generated, -assisted, or -embedded, including unambiguous disclosure of the AI systems involved, the organizations providing and operating these systems, and the specific infrastructure used.&lt;br /&gt;
&lt;br /&gt;
=== 2. Legal and Licensing Compliance ===&lt;br /&gt;
&lt;br /&gt;
The organizations responsible for providing and operating the AI technology have signed a &#039;&#039;Contributor License Agreement&#039;&#039; granting the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039; unrestricted and irrevocable licenses over the contributions. These agreements include assurances that such organizations are legally entitled to sublicense their rights.&lt;br /&gt;
&lt;br /&gt;
=== 3. Alignment with Goals and Mission ===&lt;br /&gt;
&lt;br /&gt;
Contributions align with the immediate objectives of the &#039;&#039;&#039;Eden&#039;&#039;&#039; project and support the broader mission of the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 4. Transparent Reasoning ===&lt;br /&gt;
&lt;br /&gt;
Each contribution is accompanied by a sufficiently detailed, human-understandable rationale, which is reviewed, comprehended, and accepted by the human developer community.&lt;br /&gt;
&lt;br /&gt;
=== 5. Fair Recognition and Compensation ===&lt;br /&gt;
&lt;br /&gt;
Contributions transparently credit any human efforts or prior art involved and&lt;br /&gt;
do not undermine fair compensation where such remuneration was initially intended.&lt;br /&gt;
&lt;br /&gt;
=== 6. Respect for Human Contributors and Oversight ===&lt;br /&gt;
&lt;br /&gt;
The scale, pace, or impact of AI contributions must not overwhelm or displace human reviewers and contributors. They should not diminish the capacity for human oversight, scrutiny, and understanding nor undermine human efforts to study, develop, maintain, or implement &#039;&#039;&#039;Eden&#039;&#039;&#039;-based solutions. AI contributions should support, not hinder, meaningful human engagement and the sustainable oversight of the project.&lt;br /&gt;
&lt;br /&gt;
=== 7. Avoidance of Proprietary Dependencies and Ethical Concerns ===&lt;br /&gt;
&lt;br /&gt;
Contributions do not introduce dependencies on proprietary technologies or services, or on such technologies and services that contribute to or exacerbate the humanitarian challenges that the Eden project aims to address.&lt;br /&gt;
&lt;br /&gt;
=== 8. Non-Discrimination ===&lt;br /&gt;
&lt;br /&gt;
Contributions must not introduce or perpetuate discrimination against any group based on background, condition or identity, particularly regarding project accessibility and participation.&lt;br /&gt;
&lt;br /&gt;
=== 9. Alignment with Sustainable Development Goals ===&lt;br /&gt;
&lt;br /&gt;
The resource consumption, structural design, and operational framework of the AI technologies used must be fully verifiable as supporting the [https://sdgs.un.org/goals UN Sustainable Development Goals], ensuring progress in one area does not come at the expense of others.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=280</id>
		<title>Guidelines:AI</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Guidelines:AI&amp;diff=280"/>
		<updated>2026-09-16T15:59:07Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* 8. Non-Discrimination */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Policy for Responsible AI Contributions (Draft Version) =&lt;br /&gt;
&lt;br /&gt;
We welcome AI-generated, -assisted, or -embedded contributions, provided they&lt;br /&gt;
adhere to the following criteria:&lt;br /&gt;
&lt;br /&gt;
=== 1. Clear Identification ===&lt;br /&gt;
&lt;br /&gt;
Contributions are explicitly labeled as AI-generated, -assisted, or -embedded, including unambiguous disclosure of the AI systems involved, the organizations providing and operating these systems, and the specific infrastructure used.&lt;br /&gt;
&lt;br /&gt;
=== 2. Legal and Licensing Compliance ===&lt;br /&gt;
&lt;br /&gt;
The organizations responsible for providing and operating the AI technology have signed a &#039;&#039;Contributor License Agreement&#039;&#039; granting the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039; unrestricted and irrevocable licenses over the contributions. These agreements include assurances that such organizations are legally entitled to sublicense their rights.&lt;br /&gt;
&lt;br /&gt;
=== 3. Alignment with Goals and Mission ===&lt;br /&gt;
&lt;br /&gt;
Contributions align with the immediate objectives of the &#039;&#039;&#039;Eden&#039;&#039;&#039; project and support the broader mission of the &#039;&#039;&#039;Sahana Software Foundation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== 4. Transparent Reasoning ===&lt;br /&gt;
&lt;br /&gt;
Each contribution is accompanied by a sufficiently detailed, human-understandable rationale, which is reviewed, comprehended, and accepted by the human developer community.&lt;br /&gt;
&lt;br /&gt;
=== 5. Fair Recognition and Compensation ===&lt;br /&gt;
&lt;br /&gt;
Contributions transparently credit any human efforts or prior art involved and&lt;br /&gt;
do not undermine fair compensation where such remuneration was initially intended.&lt;br /&gt;
&lt;br /&gt;
=== 6. Respect for Human Contributors and Oversight ===&lt;br /&gt;
&lt;br /&gt;
The scale, pace, or impact of AI contributions must not overwhelm or displace human reviewers and contributors. They should not diminish the capacity for human oversight, scrutiny, and understanding nor undermine human efforts to study, develop, maintain, or implement &#039;&#039;&#039;Eden&#039;&#039;&#039;-based solutions. AI contributions should support, not hinder, meaningful human engagement and the sustainable oversight of the project.&lt;br /&gt;
&lt;br /&gt;
=== 7. Avoidance of Proprietary Dependencies and Ethical Concerns ===&lt;br /&gt;
&lt;br /&gt;
Contributions do not introduce dependencies on proprietary technologies or services, or on such technologies and services that contribute to or exacerbate the humanitarian challenges that the Eden project aims to address.&lt;br /&gt;
&lt;br /&gt;
=== 8. Non-Discrimination ===&lt;br /&gt;
&lt;br /&gt;
Contributions must not introduce or perpetuate discrimination against any group based on background, condition or identity, particularly regarding project accessibility and participation.&lt;br /&gt;
&lt;br /&gt;
=== 9. Alignment with Sustainable Development Goals ===&lt;br /&gt;
&lt;br /&gt;
The resource consumption, structural design, and operational framework of the AI technologies used must be fully verifiable as supporting the UN Sustainable Development Goals, ensuring progress in one area does not come at the expense of others.&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=279</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=279"/>
		<updated>2026-09-16T15:56:52Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* Project Conventions and Policies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Sahana Eden&#039;&#039;&#039; is an &#039;&#039;Application Development Kit&#039;&#039; designed to build database-driven web applications tailored for emergency and humanitarian management. It provides a robust foundation for application developers and IT service providers to meet the information management needs of aid organizations and governmental agencies during emergencies, disaster preparedness, and humanitarian operations.&lt;br /&gt;
&lt;br /&gt;
Eden is &#039;&#039;&#039;free and open-source software&#039;&#039;&#039; (FOSS) that can be freely used, modified, extended, and integrated by anyone without restrictions.&lt;br /&gt;
&lt;br /&gt;
As an open project, Eden fosters collaboration and the exchange of knowledge, experiences, and best practices among humanitarian organizations. The project is guided by input from experienced aid organizations worldwide and emphasizes the use of open technology and standards. Nearly all of Eden’s code is developed in close cooperation with humanitarians in the field, ensuring it is directly aligned with real-world needs.&lt;br /&gt;
&lt;br /&gt;
== Implementing Eden ==&lt;br /&gt;
&lt;br /&gt;
Sahana Eden is a multi-purpose &#039;&#039;web application&#039;&#039; written for the [https://web2py.com web2py] framework. &lt;br /&gt;
&lt;br /&gt;
The appearance and business logic of this application can be adjusted to the needs of a particular deployment by altering settings in the &amp;lt;code&amp;gt;models/000_config.py&amp;lt;/code&amp;gt; configuration file on the server. Such adjustments can be minimal, or (more commonly) be extensive customization involving menus, forms, user roles, workflows, data models and even processing logic - so that Eden can be repurposed and adapted for many different use-cases and scenarios.&lt;br /&gt;
&lt;br /&gt;
Rather than putting all these customizations into one server-side configuration file, they would normally be implemented as Python packages which are then imported as &#039;&#039;&#039;configuration templates&#039;&#039;&#039;. This way, complex custom configurations can be developed, tested and maintained away from the server - and can easily be shared and re-used in other deployments.&lt;br /&gt;
&lt;br /&gt;
An &#039;&#039;&#039;Eden application&#039;&#039;&#039; is understood as such a re-usable configuration template (or a combination of templates), and &#039;&#039;&#039;Application Development&#039;&#039;&#039; is focused on these templates. &lt;br /&gt;
&lt;br /&gt;
A small selection of configuration templates is included in the Eden code base. However, downstream projects will often develop their own templates, and may publish and/or market them independently - a business model which we encourage and support.&lt;br /&gt;
&lt;br /&gt;
== Deploying Eden ==&lt;br /&gt;
&lt;br /&gt;
=== Installation and Setup ===&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== How to Contribute ==&lt;br /&gt;
&lt;br /&gt;
=== What to Do ===&lt;br /&gt;
&lt;br /&gt;
==== Code ====&lt;br /&gt;
* [https://github.com/sahana/eden/issues Issues] are a good starting point for  short-term contribution&lt;br /&gt;
* [[Blueprint:Index|Blueprints]] describe more complex feature sets and requirements, best suited for longer-term contribution&lt;br /&gt;
* Many core modules are looking for a maintainer, who takes long-term overall responsibility for their continuous development, support and documentation. Tell us on our [https://groups.google.com/g/eden-asp mailing list] what you would be interested in leading, and we will guide you to the role.&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
* Our [https://eden-asp.readthedocs.io/en/latest Handbook for Application Developers] needs continuous maintenance and improvement. You can work on the handbook in the [https://github.com/sahana/eden/tree/dev/docs/source code base].&lt;br /&gt;
* If you want to contribute to this wiki, you can start by discussing your idea on our [https://groups.google.com/g/eden-asp mailing list] - we will then create a wiki account for you as needed.&lt;br /&gt;
&lt;br /&gt;
=== Information Resources ===&lt;br /&gt;
&lt;br /&gt;
* [[Code Repository]]&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
&lt;br /&gt;
=== Project Conventions ===&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:AI|Policy for Responsible AI Contributions (Draft)]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=278</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=278"/>
		<updated>2026-09-16T15:56:34Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* How to Do It */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Sahana Eden&#039;&#039;&#039; is an &#039;&#039;Application Development Kit&#039;&#039; designed to build database-driven web applications tailored for emergency and humanitarian management. It provides a robust foundation for application developers and IT service providers to meet the information management needs of aid organizations and governmental agencies during emergencies, disaster preparedness, and humanitarian operations.&lt;br /&gt;
&lt;br /&gt;
Eden is &#039;&#039;&#039;free and open-source software&#039;&#039;&#039; (FOSS) that can be freely used, modified, extended, and integrated by anyone without restrictions.&lt;br /&gt;
&lt;br /&gt;
As an open project, Eden fosters collaboration and the exchange of knowledge, experiences, and best practices among humanitarian organizations. The project is guided by input from experienced aid organizations worldwide and emphasizes the use of open technology and standards. Nearly all of Eden’s code is developed in close cooperation with humanitarians in the field, ensuring it is directly aligned with real-world needs.&lt;br /&gt;
&lt;br /&gt;
== Implementing Eden ==&lt;br /&gt;
&lt;br /&gt;
Sahana Eden is a multi-purpose &#039;&#039;web application&#039;&#039; written for the [https://web2py.com web2py] framework. &lt;br /&gt;
&lt;br /&gt;
The appearance and business logic of this application can be adjusted to the needs of a particular deployment by altering settings in the &amp;lt;code&amp;gt;models/000_config.py&amp;lt;/code&amp;gt; configuration file on the server. Such adjustments can be minimal, or (more commonly) be extensive customization involving menus, forms, user roles, workflows, data models and even processing logic - so that Eden can be repurposed and adapted for many different use-cases and scenarios.&lt;br /&gt;
&lt;br /&gt;
Rather than putting all these customizations into one server-side configuration file, they would normally be implemented as Python packages which are then imported as &#039;&#039;&#039;configuration templates&#039;&#039;&#039;. This way, complex custom configurations can be developed, tested and maintained away from the server - and can easily be shared and re-used in other deployments.&lt;br /&gt;
&lt;br /&gt;
An &#039;&#039;&#039;Eden application&#039;&#039;&#039; is understood as such a re-usable configuration template (or a combination of templates), and &#039;&#039;&#039;Application Development&#039;&#039;&#039; is focused on these templates. &lt;br /&gt;
&lt;br /&gt;
A small selection of configuration templates is included in the Eden code base. However, downstream projects will often develop their own templates, and may publish and/or market them independently - a business model which we encourage and support.&lt;br /&gt;
&lt;br /&gt;
== Deploying Eden ==&lt;br /&gt;
&lt;br /&gt;
=== Installation and Setup ===&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== How to Contribute ==&lt;br /&gt;
&lt;br /&gt;
=== What to Do ===&lt;br /&gt;
&lt;br /&gt;
==== Code ====&lt;br /&gt;
* [https://github.com/sahana/eden/issues Issues] are a good starting point for  short-term contribution&lt;br /&gt;
* [[Blueprint:Index|Blueprints]] describe more complex feature sets and requirements, best suited for longer-term contribution&lt;br /&gt;
* Many core modules are looking for a maintainer, who takes long-term overall responsibility for their continuous development, support and documentation. Tell us on our [https://groups.google.com/g/eden-asp mailing list] what you would be interested in leading, and we will guide you to the role.&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
* Our [https://eden-asp.readthedocs.io/en/latest Handbook for Application Developers] needs continuous maintenance and improvement. You can work on the handbook in the [https://github.com/sahana/eden/tree/dev/docs/source code base].&lt;br /&gt;
* If you want to contribute to this wiki, you can start by discussing your idea on our [https://groups.google.com/g/eden-asp mailing list] - we will then create a wiki account for you as needed.&lt;br /&gt;
&lt;br /&gt;
=== Information Resources ===&lt;br /&gt;
&lt;br /&gt;
* [[Code Repository]]&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
&lt;br /&gt;
=== Project Conventions and Policies ===&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:AI|Policy for Responsible AI Contributions (Draft)]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
	<entry>
		<id>https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=277</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://eden.sahanafoundation.org/index.php?title=Main_Page&amp;diff=277"/>
		<updated>2026-09-16T15:53:56Z</updated>

		<summary type="html">&lt;p&gt;Dominic: /* How to Contribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Sahana Eden&#039;&#039;&#039; is an &#039;&#039;Application Development Kit&#039;&#039; designed to build database-driven web applications tailored for emergency and humanitarian management. It provides a robust foundation for application developers and IT service providers to meet the information management needs of aid organizations and governmental agencies during emergencies, disaster preparedness, and humanitarian operations.&lt;br /&gt;
&lt;br /&gt;
Eden is &#039;&#039;&#039;free and open-source software&#039;&#039;&#039; (FOSS) that can be freely used, modified, extended, and integrated by anyone without restrictions.&lt;br /&gt;
&lt;br /&gt;
As an open project, Eden fosters collaboration and the exchange of knowledge, experiences, and best practices among humanitarian organizations. The project is guided by input from experienced aid organizations worldwide and emphasizes the use of open technology and standards. Nearly all of Eden’s code is developed in close cooperation with humanitarians in the field, ensuring it is directly aligned with real-world needs.&lt;br /&gt;
&lt;br /&gt;
== Implementing Eden ==&lt;br /&gt;
&lt;br /&gt;
Sahana Eden is a multi-purpose &#039;&#039;web application&#039;&#039; written for the [https://web2py.com web2py] framework. &lt;br /&gt;
&lt;br /&gt;
The appearance and business logic of this application can be adjusted to the needs of a particular deployment by altering settings in the &amp;lt;code&amp;gt;models/000_config.py&amp;lt;/code&amp;gt; configuration file on the server. Such adjustments can be minimal, or (more commonly) be extensive customization involving menus, forms, user roles, workflows, data models and even processing logic - so that Eden can be repurposed and adapted for many different use-cases and scenarios.&lt;br /&gt;
&lt;br /&gt;
Rather than putting all these customizations into one server-side configuration file, they would normally be implemented as Python packages which are then imported as &#039;&#039;&#039;configuration templates&#039;&#039;&#039;. This way, complex custom configurations can be developed, tested and maintained away from the server - and can easily be shared and re-used in other deployments.&lt;br /&gt;
&lt;br /&gt;
An &#039;&#039;&#039;Eden application&#039;&#039;&#039; is understood as such a re-usable configuration template (or a combination of templates), and &#039;&#039;&#039;Application Development&#039;&#039;&#039; is focused on these templates. &lt;br /&gt;
&lt;br /&gt;
A small selection of configuration templates is included in the Eden code base. However, downstream projects will often develop their own templates, and may publish and/or market them independently - a business model which we encourage and support.&lt;br /&gt;
&lt;br /&gt;
== Deploying Eden ==&lt;br /&gt;
&lt;br /&gt;
=== Installation and Setup ===&lt;br /&gt;
* [[Guidelines:Deployment|Deployment Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== How to Contribute ==&lt;br /&gt;
&lt;br /&gt;
=== What to Do ===&lt;br /&gt;
&lt;br /&gt;
==== Code ====&lt;br /&gt;
* [https://github.com/sahana/eden/issues Issues] are a good starting point for  short-term contribution&lt;br /&gt;
* [[Blueprint:Index|Blueprints]] describe more complex feature sets and requirements, best suited for longer-term contribution&lt;br /&gt;
* Many core modules are looking for a maintainer, who takes long-term overall responsibility for their continuous development, support and documentation. Tell us on our [https://groups.google.com/g/eden-asp mailing list] what you would be interested in leading, and we will guide you to the role.&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
* Our [https://eden-asp.readthedocs.io/en/latest Handbook for Application Developers] needs continuous maintenance and improvement. You can work on the handbook in the [https://github.com/sahana/eden/tree/dev/docs/source code base].&lt;br /&gt;
* If you want to contribute to this wiki, you can start by discussing your idea on our [https://groups.google.com/g/eden-asp mailing list] - we will then create a wiki account for you as needed.&lt;br /&gt;
&lt;br /&gt;
=== Information Resources ===&lt;br /&gt;
&lt;br /&gt;
* [[Code Repository]]&lt;br /&gt;
* [[Guidelines:ContributorWorkflow|Git Workflow for Code Contributions]]&lt;br /&gt;
&lt;br /&gt;
=== How to Do It ===&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines:AI|Policy for Responsible AI Contributions (Draft)]]&lt;/div&gt;</summary>
		<author><name>Dominic</name></author>
	</entry>
</feed>