.. _customization: Portal Customization ******************** Portal customization requires profound knowledge of the Python programming language. Customization is part of the portal deployment process. It can only be done by the custom package manager and activated by the system administrator, who is allowed to update/upgrade the package on the server and restart the portal. Usually, custom packages are not designed for regular reconfiguration. Due to the complexity of school fee computation at Nigerian universities, however, a lot of configuration had to be done in the Python code and can thus not be subject to online configuration. Technically speaking, the parameters are only loaded and registered once during start-up and are not stored in the database like the configuration parameters described in :ref:`configuration`. Kofa must not be customized by manipulating original Kofa code, i.e. by editing Python files, Zope page templates or ZCML configuration files in the Kofa base package. Customization is done by deploying a custom package which can inherit all the Python classes from the base package, in order to override distinct attributes and methods and register these customized classes instead of the orginal classes during start-up. It would go beyond the scope of the user handbook to explain, how to build such a Kofa custom package. This will be done in the :ref:`developer_handbook`. Here we roughly describe the three different customization approaches with a focus on the third approach, the customization of utility attributes and methods. Localization ============ The base language of the Kofa User Interface (Kofa UI) is English. The English language regime has been specified by WAeUP's first customer, the University of Benin in Nigeria. Kofa is language-aware, which means it has been translated into different languages (German and French so far), and the preferred language can be selected via the UI. The Kofa UI translations and also the English language regime can be localized in custom packages by overriding single entries of the language files. Headlines, field labels, field descriptions, navigation tabs, buttons, page comments, flash messages etc. can be easily adjusted to the needs of the institution which wants to deploy Kofa. Kofa is using the `GNU gettext utilities `_ for translation and localization. Translation is done via ``po`` text files which are located in the ``locales`` folder of a package. Each language has its own subfolder. Localized English Kofa terms, for instance, can be found in ``locales/en/LC_MESSAGES/waeup.kofa.po``. A single entry/message consists of two lines. Example:: msgid "Login" msgstr "Let me in" ``msgid`` contains the original term from the base package, ``msgstr`` contains its localized/translated version, which results into a renamed login tab on the right side of the navigation bar. ``po`` files must be compiled before restarting the portal. Editing and compilation of ``po`` files can be done with a nice tool called 'Poedit' which is `available `_ for various operating systems. Zope Interfaces =============== Adding further schema field attributes to content components can be done by inheriting Zope interfaces from the base package and adding new schema fields to these custom interfaces, see :ref:`note `. This sounds simple, but it isn't. There are many things to think about, when customizing interfaces: 1. A customized interface alone doesn't have any effect, beause the content classes still implement the original interfaces. Thus, also all content classes, which are supposed to implement the extended interfaces, must be customized, and must be registered instead of the orginal classes which they inherit from. Drawback is, that this must be done before the first start-up of the portal. Otherwise, instances of the original content classes might have been created which cannot be changed afterwards. 2. Also the forms which are being auto-generated by `grok.AutoFields` (see :ref:`views_pages`), must be customized and use the new and extended interfaces. Otherwise added fields won't appear on form pages. 3. The same holds for exporters and importers. They also consider the fields from interfaces when processing the data. If we forget to customize exporter or batch processor classes, only the fields from the original interfaces will be exported or reimported. Zope Utilities ============== Kofa's global utilities are perfectly suited for customization. Their attributes and methods can be easily overridden in custom packages. Kofa Utils ---------- The central `KofaUtils` utility contains not only most dictionaries used for sources (see :py:class:`API `) but also **configuration attributes** like: .. autoattribute:: waeup.kofa.utils.utils.KofaUtils.PORTAL_LANGUAGE :noindex: .. autoattribute:: waeup.kofa.utils.utils.KofaUtils.tzinfo :noindex: .. autoattribute:: waeup.kofa.utils.utils.KofaUtils.SYSTEM_MAX_LOAD :noindex: Customizable **utility methods** are: .. automethod:: waeup.kofa.utils.utils.KofaUtils.sendContactForm :noindex: .. automethod:: waeup.kofa.utils.utils.KofaUtils.fullname :noindex: .. automethod:: waeup.kofa.utils.utils.KofaUtils.genPassword :noindex: .. automethod:: waeup.kofa.utils.utils.KofaUtils.sendCredentials :noindex: .. automethod:: waeup.kofa.utils.utils.KofaUtils.getPaymentItem :noindex: Students Utilities ------------------ `StudentsUtils` contains the following **configuration attributes**: .. autoattribute:: waeup.kofa.students.utils.StudentsUtils.STUDENT_ID_PREFIX :noindex: .. autoattribute:: waeup.kofa.students.utils.StudentsUtils.SKIP_UPLOAD_VIEWLETS :noindex: .. autoattribute:: waeup.kofa.students.utils.StudentsUtils.PORTRAIT_CHANGE_STATES :noindex: .. autoattribute:: waeup.kofa.students.utils.StudentsUtils.SEPARATORS_DICT :noindex: .. autoattribute:: waeup.kofa.students.utils.StudentsUtils.STUDENT_EXPORTER_NAMES :noindex: .. autoattribute:: waeup.kofa.students.utils.StudentsUtils.STUDENT_BACKUP_EXPORTER_NAMES :noindex: Customizable **utility methods** are: .. automethod:: waeup.kofa.students.utils.StudentsUtils.getReturningData :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.setReturningData :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.setPaymentDetails :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.setBalanceDetails :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.increaseMatricInteger :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.constructMatricNumber :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.setMatricNumber :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.getAccommodationDetails :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.selectBed :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.getPDFCreator :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.renderPDF :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.renderPDFAdmissionLetter :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.renderPDFCourseticketsOverview :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.renderPDFTranscript :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.getDegreeClassNumber :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.warnCreditsOOR :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.getBedCoordinates :noindex: .. automethod:: waeup.kofa.students.utils.StudentsUtils.clearance_disabled_message :noindex: Applicants Utililties --------------------- `ApplicantsUtils` contains the following **configuration attributes**: .. autoattribute:: waeup.kofa.applicants.utils.ApplicantsUtils.APP_TYPES_DICT :noindex: .. autoattribute:: waeup.kofa.applicants.utils.ApplicantsUtils.SEPARATORS_DICT :noindex: Customizable **utility methods** are: .. automethod:: waeup.kofa.applicants.utils.ApplicantsUtils.setPaymentDetails :noindex: .. automethod:: waeup.kofa.applicants.utils.ApplicantsUtils.getApplicantsStatistics :noindex: .. automethod:: waeup.kofa.applicants.utils.ApplicantsUtils.sortCertificates :noindex: .. automethod:: waeup.kofa.applicants.utils.ApplicantsUtils.getCertTitle :noindex: