• Publicity: Public Only All

locale-procs.tcl

Localization procedures for OpenACS

This is free software distributed under the terms of the GNU Public License. Full text of the license is available from the GNU Project: http://www.fsf.org/copyleft/gpl.html

Location:
packages/acs-lang/tcl/locale-procs.tcl
Created:
28 September 2000
Authors:
Henry Minsky <hqm@mit.edu>
Lars Pind <lars@pinds.com>
CVS Identification:
$Id: locale-procs.tcl,v 1.53 2024/09/11 06:15:48 gustafn Exp $

Procedures in this file

Detailed information

lang::conn::charset (public)

 lang::conn::charset

Returns the MIME charset name corresponding to the current connection's locale.

Returns:
IANA MIME character set name
Author:
Lars Pind <lars@pinds.com>

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::conn::charset lang::conn::charset test_test_get_locales->lang::conn::charset lang::conn::locale lang::conn::locale (public) lang::conn::charset->lang::conn::locale lang::util::charset_for_locale lang::util::charset_for_locale (public) lang::conn::charset->lang::util::charset_for_locale

Testcases:
test_get_locales

lang::conn::language (public)

 lang::conn::language [ -package_id package_id ] [ -user_id user_id ] \
    [ -site_wide ] [ -iso6392 ] [ -locale locale ]

Get the language for this request, perhaps for a given package instance.

Switches:
-package_id (optional)
The package for which you want to get the language (used only when, no locale is provided).
-user_id (optional)
The user_id for whom you want to get the language (used only when, no locale is provided).
-site_wide (optional, boolean)
Set this if you want to get the site-wide language (used only when, no locale is provided).
-iso6392 (optional, boolean)
Set this if you want to force the iso-639-2 code
-locale (optional)
obtain language from provided locale
Returns:
3 chars language code if iso6392 is set, left part of locale otherwise

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::conn::language lang::conn::language test_test_get_locales->lang::conn::language lang::conn::locale lang::conn::locale (public) lang::conn::language->lang::conn::locale lang::util::iso6392_from_language lang::util::iso6392_from_language (public) lang::conn::language->lang::util::iso6392_from_language richtext::ckeditor4::initialize_widget richtext::ckeditor4::initialize_widget (public) richtext::ckeditor4::initialize_widget->lang::conn::language richtext::ckeditor5::initialize_widget richtext::ckeditor5::initialize_widget (public) richtext::ckeditor5::initialize_widget->lang::conn::language richtext::xinha::initialize_widget richtext::xinha::initialize_widget (public) richtext::xinha::initialize_widget->lang::conn::language rp_filter rp_filter (private) rp_filter->lang::conn::language

Testcases:
test_get_locales

lang::conn::locale (public)

 lang::conn::locale [ -package_id package_id ] [ -site_wide ] \
    [ -user_id user_id ]

Get the locale for this request, perhaps for a given package instance.

Switches:
-package_id (optional)
The package for which you want to get the locale.
-site_wide (optional, boolean)
Set this if you want to get the site-wide locale.
-user_id (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::conn::locale lang::conn::locale test_test_get_locales->lang::conn::locale lang::conn::locale_not_cached lang::conn::locale_not_cached (private) lang::conn::locale->lang::conn::locale_not_cached lang::conn::charset lang::conn::charset (public) lang::conn::charset->lang::conn::locale lang::conn::language lang::conn::language (public) lang::conn::language->lang::conn::locale rp_filter rp_filter (private) rp_filter->lang::conn::locale xo::ConnectionContext proc require xo::ConnectionContext proc require xo::ConnectionContext proc require->lang::conn::locale xowiki::locales xowiki::locales (private) xowiki::locales->lang::conn::locale

Testcases:
test_get_locales

lang::conn::timezone (public)

 lang::conn::timezone

Get this connection's timezone. This is the user timezone, if set, otherwise the system timezone.

Returns:
a timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)

Partial Call Graph (max 5 caller/called nodes):
%3 test_a_foreign_calendar_user a_foreign_calendar_user (test calendar) lang::conn::timezone lang::conn::timezone test_a_foreign_calendar_user->lang::conn::timezone test_lang_test__lc_procs lang_test__lc_procs (test acs-lang) test_lang_test__lc_procs->lang::conn::timezone test_lc_time_fmt_Z_timezone lc_time_fmt_Z_timezone (test acs-lang) test_lc_time_fmt_Z_timezone->lang::conn::timezone test_set_get_timezone set_get_timezone (test acs-lang) test_set_get_timezone->lang::conn::timezone test_set_timezone_not_logged_in set_timezone_not_logged_in (test acs-lang) test_set_timezone_not_logged_in->lang::conn::timezone ad_conn ad_conn (public) lang::conn::timezone->ad_conn lang::system::timezone lang::system::timezone (public) lang::conn::timezone->lang::system::timezone lang::user::timezone lang::user::timezone (public) lang::conn::timezone->lang::user::timezone lc_time_conn_to_system lc_time_conn_to_system (public) lc_time_conn_to_system->lang::conn::timezone lc_time_local_to_utc lc_time_local_to_utc (public) lc_time_local_to_utc->lang::conn::timezone lc_time_system_to_conn lc_time_system_to_conn (public) lc_time_system_to_conn->lang::conn::timezone lc_time_utc_to_local lc_time_utc_to_local (public) lc_time_utc_to_local->lang::conn::timezone packages/acs-lang/tcl/localization-data-init.tcl packages/acs-lang/ tcl/localization-data-init.tcl packages/acs-lang/tcl/localization-data-init.tcl->lang::conn::timezone

Testcases:
lang_test__lc_procs, set_get_timezone, set_timezone_not_logged_in, lc_time_fmt_Z_timezone, a_foreign_calendar_user

lang::system::get_locale_options (public)

 lang::system::get_locale_options

Return all enabled locales in the system in a format suitable for the options argument of a form.

Author:
Lars Pind

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::system::get_locale_options lang::system::get_locale_options test_test_get_locales->lang::system::get_locale_options lang::system::get_locale_options_not_cached lang::system::get_locale_options_not_cached (private) lang::system::get_locale_options->lang::system::get_locale_options_not_cached util_memoize util_memoize (public) lang::system::get_locale_options->util_memoize packages/acs-lang/www/admin/message-list.tcl packages/acs-lang/ www/admin/message-list.tcl packages/acs-lang/www/admin/message-list.tcl->lang::system::get_locale_options packages/categories/lib/tree-form.tcl packages/categories/ lib/tree-form.tcl packages/categories/lib/tree-form.tcl->lang::system::get_locale_options packages/categories/www/cadmin/category-form.tcl packages/categories/ www/cadmin/category-form.tcl packages/categories/www/cadmin/category-form.tcl->lang::system::get_locale_options packages/categories/www/cadmin/master.tcl packages/categories/ www/cadmin/master.tcl packages/categories/www/cadmin/master.tcl->lang::system::get_locale_options packages/categories/www/cadmin/synonym-form.tcl packages/categories/ www/cadmin/synonym-form.tcl packages/categories/www/cadmin/synonym-form.tcl->lang::system::get_locale_options

Testcases:
test_get_locales

lang::system::get_locales (public)

 lang::system::get_locales [ -all ]

Return all locales defined in the system. Per default only the enabled locales are returned. When the optional flag "-all" is specified, all defined locales are returned. This value is cached per thread and needs currently a server restart, when the system locales are changed.

Switches:
-all (optional, boolean)
Author:
Peter Marklund

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::system::get_locales lang::system::get_locales test_test_get_locales->lang::system::get_locales test_xowiki_test_cases xowiki_test_cases (test xowiki) test_xowiki_test_cases->lang::system::get_locales db_list db_list (public) lang::system::get_locales->db_list lang::conn::browser_locale lang::conn::browser_locale (private) lang::conn::browser_locale->lang::system::get_locales lang::conn::locale_not_cached lang::conn::locale_not_cached (private) lang::conn::locale_not_cached->lang::system::get_locales lang::system::site_wide_locale lang::system::site_wide_locale (public) lang::system::site_wide_locale->lang::system::get_locales lang::user::site_wide_locale_not_cached lang::user::site_wide_locale_not_cached (private) lang::user::site_wide_locale_not_cached->lang::system::get_locales packages/acs-admin/www/posture-overview.tcl packages/acs-admin/ www/posture-overview.tcl packages/acs-admin/www/posture-overview.tcl->lang::system::get_locales

Testcases:
test_get_locales, xowiki_test_cases

lang::system::language (public)

 lang::system::language [ -package_id package_id ] [ -site_wide ] \
    [ -iso6392 ]

Get system language setting for a given package instance.

Switches:
-package_id (optional)
The package for which you want to get the language setting.
-site_wide (optional, boolean)
Set this if you want to get the site-wide language setting.
-iso6392 (optional, boolean)
Set this if you want to force iso-639-2 code (3 digits)
Returns:
3 chars language code if iso6392 is set, left part of locale otherwise

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::system::language lang::system::language test_test_get_locales->lang::system::language lang::system::locale lang::system::locale (public) lang::system::language->lang::system::locale lang::util::iso6392_from_language lang::util::iso6392_from_language (public) lang::system::language->lang::util::iso6392_from_language

Testcases:
test_get_locales

lang::system::locale (public)

 lang::system::locale [ -package_id package_id ] [ -site_wide ]

Get system locale setting for a given package instance.

Switches:
-package_id (optional)
The package for which you want to get the locale setting.
-site_wide (optional, boolean)
Set this if you want to get the site-wide locale setting.

Partial Call Graph (max 5 caller/called nodes):
%3 test_create_composite_test_item create_composite_test_item (test xowf) lang::system::locale lang::system::locale test_create_composite_test_item->lang::system::locale test_create_folder_with_page create_folder_with_page (test xowf) test_create_folder_with_page->lang::system::locale test_create_form_with_form_instance create_form_with_form_instance (test xowiki) test_create_form_with_form_instance->lang::system::locale test_create_form_with_numeric create_form_with_numeric (test xowiki) test_create_form_with_numeric->lang::system::locale test_create_test_items create_test_items (test xowf) test_create_test_items->lang::system::locale ad_conn ad_conn (public) lang::system::locale->ad_conn lang::system::package_level_locale lang::system::package_level_locale (public) lang::system::locale->lang::system::package_level_locale lang::system::site_wide_locale lang::system::site_wide_locale (public) lang::system::locale->lang::system::site_wide_locale acs_user::promote_person_to_user acs_user::promote_person_to_user (public) acs_user::promote_person_to_user->lang::system::locale category::get_name category::get_name (public) category::get_name->lang::system::locale lang::conn::get_accept_language_header lang::conn::get_accept_language_header (private) lang::conn::get_accept_language_header->lang::system::locale lang::message::lookup lang::message::lookup (public) lang::message::lookup->lang::system::locale lang::system::language lang::system::language (public) lang::system::language->lang::system::locale

Testcases:
dt_localized_procs, locale__test_system_package_setting, test_get_locales, create_test_items, create_composite_test_item, create_folder_with_page, create_workflow_with_instance, link_tests, path_resolve, create_form_with_form_instance, create_form_with_numeric, form_validate

lang::system::locale_set_enabled (public)

 lang::system::locale_set_enabled -locale locale -enabled_p enabled_p

Enables or disables a locale.

Switches:
-locale (required)
-enabled_p (required)
Should be t or f
Author:
Peter Marklund

Partial Call Graph (max 5 caller/called nodes):
%3 test_lang_test__lc_procs lang_test__lc_procs (test acs-lang) lang::system::locale_set_enabled lang::system::locale_set_enabled test_lang_test__lc_procs->lang::system::locale_set_enabled test_locale__test_lang_conn_browser_locale locale__test_lang_conn_browser_locale (test acs-lang) test_locale__test_lang_conn_browser_locale->lang::system::locale_set_enabled test_locale_language_fallback locale_language_fallback (test acs-lang) test_locale_language_fallback->lang::system::locale_set_enabled test_upgrade upgrade (test acs-lang) test_upgrade->lang::system::locale_set_enabled db_dml db_dml (public) lang::system::locale_set_enabled->db_dml util_memoize_flush_regexp util_memoize_flush_regexp (public) lang::system::locale_set_enabled->util_memoize_flush_regexp install::xml::action::disable-locale install::xml::action::disable-locale (private) install::xml::action::disable-locale->lang::system::locale_set_enabled install::xml::action::enable-locale install::xml::action::enable-locale (private) install::xml::action::enable-locale->lang::system::locale_set_enabled packages/acs-lang/www/admin/locale-set-enabled-p.tcl packages/acs-lang/ www/admin/locale-set-enabled-p.tcl packages/acs-lang/www/admin/locale-set-enabled-p.tcl->lang::system::locale_set_enabled

Testcases:
lang_test__lc_procs, locale__test_lang_conn_browser_locale, locale_language_fallback, upgrade

lang::system::package_level_locale (public)

 lang::system::package_level_locale package_id
Parameters:
package_id (required)
Returns:
empty string if not use_package_level_locales_p, or the package locale from apm_packages table.

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::system::package_level_locale lang::system::package_level_locale test_test_get_locales->lang::system::package_level_locale lang::system::package_level_locale_not_cached lang::system::package_level_locale_not_cached (private) lang::system::package_level_locale->lang::system::package_level_locale_not_cached lang::system::use_package_level_locales_p lang::system::use_package_level_locales_p (public) lang::system::package_level_locale->lang::system::use_package_level_locales_p util_memoize util_memoize (public) lang::system::package_level_locale->util_memoize lang::conn::locale_not_cached lang::conn::locale_not_cached (private) lang::conn::locale_not_cached->lang::system::package_level_locale lang::system::locale lang::system::locale (public) lang::system::locale->lang::system::package_level_locale

Testcases:
test_get_locales

lang::system::set_locale (public)

 lang::system::set_locale [ -package_id package_id ] locale

Set system locale setting for a given package instance, or the site-wide system locale.

Switches:
-package_id (optional)
The package for which you want to set the locale setting, if you want to set system setting for one package only. Leave blank for site-wide setting.
Parameters:
locale (required)
The new locale that you want to use as your system locale.

Partial Call Graph (max 5 caller/called nodes):
%3 test_dt_localized_procs dt_localized_procs (test acs-datetime) lang::system::set_locale lang::system::set_locale test_dt_localized_procs->lang::system::set_locale test_link_tests link_tests (test xowiki) test_link_tests->lang::system::set_locale test_locale__test_system_package_setting locale__test_system_package_setting (test acs-lang) test_locale__test_system_package_setting->lang::system::set_locale test_path_resolve path_resolve (test xowiki) test_path_resolve->lang::system::set_locale test_slot_interactions slot_interactions (test xowiki) test_slot_interactions->lang::system::set_locale apm_package_id_from_key apm_package_id_from_key (public) lang::system::set_locale->apm_package_id_from_key db_dml db_dml (public) lang::system::set_locale->db_dml parameter::set_value parameter::set_value (public) lang::system::set_locale->parameter::set_value util_memoize_flush util_memoize_flush (public) lang::system::set_locale->util_memoize_flush install::xml::action::set-system-locale install::xml::action::set-system-locale (private) install::xml::action::set-system-locale->lang::system::set_locale

Testcases:
dt_localized_procs, locale__test_system_package_setting, test_get_locales, link_tests, slot_interactions, path_resolve

lang::system::set_timezone (public)

 lang::system::set_timezone timezone

Tell OpenACS what timezone we think it's running in.

Parameters:
timezone (required)
name from acs-reference package (e.g., Asia/Tokyo, America/New_York)

Partial Call Graph (max 5 caller/called nodes):
%3 test_lang_test__lc_procs lang_test__lc_procs (test acs-lang) lang::system::set_timezone lang::system::set_timezone test_lang_test__lc_procs->lang::system::set_timezone test_set_get_timezone set_get_timezone (test acs-lang) test_set_get_timezone->lang::system::set_timezone apm_package_id_from_key apm_package_id_from_key (public) lang::system::set_timezone->apm_package_id_from_key parameter::set_value parameter::set_value (public) lang::system::set_timezone->parameter::set_value packages/acs-lang/www/admin/set-system-timezone.tcl packages/acs-lang/ www/admin/set-system-timezone.tcl packages/acs-lang/www/admin/set-system-timezone.tcl->lang::system::set_timezone

Testcases:
lang_test__lc_procs, set_get_timezone

lang::system::site_wide_locale (public)

 lang::system::site_wide_locale

Get the site-wide system locale setting.

Partial Call Graph (max 5 caller/called nodes):
%3 test_ad_context_bar_multirow ad_context_bar_multirow (test acs-tcl) lang::system::site_wide_locale lang::system::site_wide_locale test_ad_context_bar_multirow->lang::system::site_wide_locale test_locale__test_system_package_setting locale__test_system_package_setting (test acs-lang) test_locale__test_system_package_setting->lang::system::site_wide_locale apm_package_id_from_key apm_package_id_from_key (public) lang::system::site_wide_locale->apm_package_id_from_key lang::system::get_locales lang::system::get_locales (public) lang::system::site_wide_locale->lang::system::get_locales parameter::get parameter::get (public) lang::system::site_wide_locale->parameter::get auth::local::registration::Register auth::local::registration::Register (private) auth::local::registration::Register->lang::system::site_wide_locale callback::search::datasource::impl::forums_message callback::search::datasource::impl::forums_message (private) callback::search::datasource::impl::forums_message->lang::system::site_wide_locale forum::format::reply_subject forum::format::reply_subject (public) forum::format::reply_subject->lang::system::site_wide_locale forum::message::datasource forum::message::datasource (private, deprecated) forum::message::datasource->lang::system::site_wide_locale lang::conn::locale_not_cached lang::conn::locale_not_cached (private) lang::conn::locale_not_cached->lang::system::site_wide_locale

Testcases:
locale__test_system_package_setting, ad_context_bar_multirow

lang::system::timezone (public)

 lang::system::timezone

Ask OpenACS what it thinks our timezone is.

Returns:
a timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)

Partial Call Graph (max 5 caller/called nodes):
%3 test_a_foreign_calendar_user a_foreign_calendar_user (test calendar) lang::system::timezone lang::system::timezone test_a_foreign_calendar_user->lang::system::timezone test_set_get_timezone set_get_timezone (test acs-lang) test_set_get_timezone->lang::system::timezone test_set_timezone_not_logged_in set_timezone_not_logged_in (test acs-lang) test_set_timezone_not_logged_in->lang::system::timezone test_test_timezone_offset test_timezone_offset (test acs-lang) test_test_timezone_offset->lang::system::timezone apm_package_id_from_key apm_package_id_from_key (public) lang::system::timezone->apm_package_id_from_key parameter::get parameter::get (public) lang::system::timezone->parameter::get fs::rss::datasource fs::rss::datasource (private) fs::rss::datasource->lang::system::timezone lang::conn::timezone lang::conn::timezone (public) lang::conn::timezone->lang::system::timezone lang::system::timezone_utc_offset lang::system::timezone_utc_offset (public) lang::system::timezone_utc_offset->lang::system::timezone lc_time_conn_to_system lc_time_conn_to_system (public) lc_time_conn_to_system->lang::system::timezone lc_time_system_to_conn lc_time_system_to_conn (public) lc_time_system_to_conn->lang::system::timezone

Testcases:
set_get_timezone, set_timezone_not_logged_in, test_timezone_offset, a_foreign_calendar_user

lang::system::timezone_utc_offset (public)

 lang::system::timezone_utc_offset
Returns:
number of hours to subtract from local (database) time to get UTC

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_timezone_offset test_timezone_offset (test acs-lang) lang::system::timezone_utc_offset lang::system::timezone_utc_offset test_test_timezone_offset->lang::system::timezone_utc_offset db_string db_string (public) lang::system::timezone_utc_offset->db_string lang::system::timezone lang::system::timezone (public) lang::system::timezone_utc_offset->lang::system::timezone packages/acs-lang/www/admin/set-system-timezone.tcl packages/acs-lang/ www/admin/set-system-timezone.tcl packages/acs-lang/www/admin/set-system-timezone.tcl->lang::system::timezone_utc_offset

Testcases:
test_timezone_offset

lang::system::use_package_level_locales_p (public)

 lang::system::use_package_level_locales_p

Returns whether we're using package level locales.

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::system::use_package_level_locales_p lang::system::use_package_level_locales_p test_test_get_locales->lang::system::use_package_level_locales_p apm_package_id_from_key apm_package_id_from_key (public) lang::system::use_package_level_locales_p->apm_package_id_from_key parameter::get parameter::get (public) lang::system::use_package_level_locales_p->parameter::get lang::system::package_level_locale lang::system::package_level_locale (public) lang::system::package_level_locale->lang::system::use_package_level_locales_p lang::user::package_level_locale lang::user::package_level_locale (public) lang::user::package_level_locale->lang::system::use_package_level_locales_p packages/acs-lang/www/change-locale-include.tcl packages/acs-lang/ www/change-locale-include.tcl packages/acs-lang/www/change-locale-include.tcl->lang::system::use_package_level_locales_p

Testcases:
test_get_locales

lang::user::language (public)

 lang::user::language [ -package_id package_id ] [ -user_id user_id ] \
    [ -site_wide ] [ -iso6392 ]

Get user language preference for a given package instance. This preliminary implementation only has one site-wide setting, though.

Switches:
-package_id (optional)
The package for which you want to get the language setting.
-user_id (optional)
The user we wish to get the language for, defaults to connection user.
-site_wide (optional, boolean)
Set this if you want to get the site-wide language setting.
-iso6392 (optional, boolean)
Set this if you want to force iso-639-2 code (3 digits)
Returns:
3 chars language code if iso6392 is set, left part of locale otherwise

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::user::language lang::user::language test_test_get_locales->lang::user::language lang::user::locale lang::user::locale (public) lang::user::language->lang::user::locale lang::util::iso6392_from_language lang::util::iso6392_from_language (public) lang::user::language->lang::util::iso6392_from_language packages/acs-lang/www/index.tcl packages/acs-lang/ www/index.tcl packages/acs-lang/www/index.tcl->lang::user::language

Testcases:
test_get_locales

lang::user::locale (public)

 lang::user::locale [ -package_id package_id ] [ -site_wide ] \
    [ -user_id user_id ]

Get user locale preference for a given package instance.

Switches:
-package_id (optional)
The package for which you want to get the locale preference.
-site_wide (optional, boolean)
Set this if you want to get the site-wide locale preference.
-user_id (optional)
Set this to the user you want to get the locale of, defaults to current user.

Partial Call Graph (max 5 caller/called nodes):
%3 test_create_form_with_numeric create_form_with_numeric (test xowiki) lang::user::locale lang::user::locale test_create_form_with_numeric->lang::user::locale test_test_get_locales test_get_locales (test acs-lang) test_test_get_locales->lang::user::locale ad_conn ad_conn (public) lang::user::locale->ad_conn lang::user::package_level_locale lang::user::package_level_locale (public) lang::user::locale->lang::user::package_level_locale lang::user::site_wide_locale lang::user::site_wide_locale (public) lang::user::locale->lang::user::site_wide_locale auth::local::registration::Register auth::local::registration::Register (private) auth::local::registration::Register->lang::user::locale lang::user::language lang::user::language (public) lang::user::language->lang::user::locale packages/acs-lang/www/index.tcl packages/acs-lang/ www/index.tcl packages/acs-lang/www/index.tcl->lang::user::locale packages/acs-subsite/www/members/member-state-change.tcl packages/acs-subsite/ www/members/member-state-change.tcl packages/acs-subsite/www/members/member-state-change.tcl->lang::user::locale

Testcases:
test_get_locales, create_form_with_numeric

lang::user::package_level_locale (public)

 lang::user::package_level_locale [ -user_id user_id ] package_id

Get the user's preferred package level locale for a package given by its package id.

Switches:
-user_id (optional)
Parameters:
package_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_test_get_locales test_get_locales (test acs-lang) lang::user::package_level_locale lang::user::package_level_locale test_test_get_locales->lang::user::package_level_locale ad_conn ad_conn (public) lang::user::package_level_locale->ad_conn lang::system::use_package_level_locales_p lang::system::use_package_level_locales_p (public) lang::user::package_level_locale->lang::system::use_package_level_locales_p lang::user::package_level_locale_not_cached lang::user::package_level_locale_not_cached (private) lang::user::package_level_locale->lang::user::package_level_locale_not_cached sec_session_timeout sec_session_timeout lang::user::package_level_locale->sec_session_timeout util_memoize util_memoize (public) lang::user::package_level_locale->util_memoize lang::conn::locale_not_cached lang::conn::locale_not_cached (private) lang::conn::locale_not_cached->lang::user::package_level_locale lang::user::locale lang::user::locale (public) lang::user::locale->lang::user::package_level_locale packages/acs-lang/www/change-locale-include.tcl packages/acs-lang/ www/change-locale-include.tcl packages/acs-lang/www/change-locale-include.tcl->lang::user::package_level_locale

Testcases:
test_get_locales

lang::user::set_locale (public)

 lang::user::set_locale [ -package_id package_id ] [ -user_id user_id ] \
    locale

Set user locale setting for a given package instance.

Switches:
-package_id (optional)
The package for which you want to set the locale setting, if you want to set it for a specific package, as opposed to a site-wide setting.
-user_id (optional)
Parameters:
locale (required)
The new locale that you want to use as your system locale.

Partial Call Graph (max 5 caller/called nodes):
%3 test_create_form_with_numeric create_form_with_numeric (test xowiki) lang::user::set_locale lang::user::set_locale test_create_form_with_numeric->lang::user::set_locale test_lang_test__lang_user_site_wide_locale lang_test__lang_user_site_wide_locale (test acs-lang) test_lang_test__lang_user_site_wide_locale->lang::user::set_locale test_test_get_locales test_get_locales (test acs-lang) test_test_get_locales->lang::user::set_locale ad_conn ad_conn (public) lang::user::set_locale->ad_conn ad_set_cookie ad_set_cookie (public) lang::user::set_locale->ad_set_cookie db_dml db_dml (public) lang::user::set_locale->db_dml db_string db_string (public) lang::user::set_locale->db_string security::cookie_name security::cookie_name (public) lang::user::set_locale->security::cookie_name acs::test::user::create acs::test::user::create (public) acs::test::user::create->lang::user::set_locale packages/acs-lang/www/change-locale-include.tcl packages/acs-lang/ www/change-locale-include.tcl packages/acs-lang/www/change-locale-include.tcl->lang::user::set_locale packages/acs-lang/www/change-locale.tcl packages/acs-lang/ www/change-locale.tcl packages/acs-lang/www/change-locale.tcl->lang::user::set_locale packages/acs-subsite/lib/user-info.tcl packages/acs-subsite/ lib/user-info.tcl packages/acs-subsite/lib/user-info.tcl->lang::user::set_locale packages/acs-subsite/lib/user-new.tcl packages/acs-subsite/ lib/user-new.tcl packages/acs-subsite/lib/user-new.tcl->lang::user::set_locale

Testcases:
lang_test__lang_user_site_wide_locale, test_get_locales, create_form_with_numeric

lang::user::set_timezone (public)

 lang::user::set_timezone timezone

Set the user's timezone setting.

Parameters:
timezone (required)
name from acs-reference package (e.g., Asia/Tokyo, America/New_York)

Partial Call Graph (max 5 caller/called nodes):
%3 test_set_get_timezone set_get_timezone (test acs-lang) lang::user::set_timezone lang::user::set_timezone test_set_get_timezone->lang::user::set_timezone test_set_timezone_not_logged_in set_timezone_not_logged_in (test acs-lang) test_set_timezone_not_logged_in->lang::user::set_timezone ad_conn ad_conn (public) lang::user::set_timezone->ad_conn db_dml db_dml (public) lang::user::set_timezone->db_dml util_memoize_flush util_memoize_flush (public) lang::user::set_timezone->util_memoize_flush packages/acs-lang/www/change-locale-include.tcl packages/acs-lang/ www/change-locale-include.tcl packages/acs-lang/www/change-locale-include.tcl->lang::user::set_timezone packages/acs-subsite/lib/user-info.tcl packages/acs-subsite/ lib/user-info.tcl packages/acs-subsite/lib/user-info.tcl->lang::user::set_timezone

Testcases:
set_get_timezone, set_timezone_not_logged_in

lang::user::site_wide_locale (public)

 lang::user::site_wide_locale [ -user_id user_id ]

Get the user's preferred site-wide locale.

Switches:
-user_id (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 test_lang_test__lang_user_site_wide_locale lang_test__lang_user_site_wide_locale (test acs-lang) lang::user::site_wide_locale lang::user::site_wide_locale test_lang_test__lang_user_site_wide_locale->lang::user::site_wide_locale ad_conn ad_conn (public) lang::user::site_wide_locale->ad_conn lang::user::site_wide_locale_not_cached lang::user::site_wide_locale_not_cached (private) lang::user::site_wide_locale->lang::user::site_wide_locale_not_cached sec_session_timeout sec_session_timeout lang::user::site_wide_locale->sec_session_timeout util_memoize util_memoize (public) lang::user::site_wide_locale->util_memoize lang::conn::locale_not_cached lang::conn::locale_not_cached (private) lang::conn::locale_not_cached->lang::user::site_wide_locale lang::user::locale lang::user::locale (public) lang::user::locale->lang::user::site_wide_locale notification::email::send notification::email::send (public) notification::email::send->lang::user::site_wide_locale packages/acs-lang/www/change-locale-include.tcl packages/acs-lang/ www/change-locale-include.tcl packages/acs-lang/www/change-locale-include.tcl->lang::user::site_wide_locale

Testcases:
lang_test__lang_user_site_wide_locale

lang::user::timezone (public)

 lang::user::timezone

Get the user's timezone. Returns the empty string if the user has no timezone set.

Returns:
a timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)

Partial Call Graph (max 5 caller/called nodes):
%3 test_set_get_timezone set_get_timezone (test acs-lang) lang::user::timezone lang::user::timezone test_set_get_timezone->lang::user::timezone ad_conn ad_conn (public) lang::user::timezone->ad_conn lang::user::timezone_no_cache lang::user::timezone_no_cache (private) lang::user::timezone->lang::user::timezone_no_cache util_memoize util_memoize (public) lang::user::timezone->util_memoize lang::conn::timezone lang::conn::timezone (public) lang::conn::timezone->lang::user::timezone packages/acs-lang/www/change-locale-include.tcl packages/acs-lang/ www/change-locale-include.tcl packages/acs-lang/www/change-locale-include.tcl->lang::user::timezone packages/acs-subsite/lib/user-info.tcl packages/acs-subsite/ lib/user-info.tcl packages/acs-subsite/lib/user-info.tcl->lang::user::timezone

Testcases:
set_get_timezone
[ hide source ] | [ make this the default ]

Content File Source

ad_library {

    Localization procedures for OpenACS
    <p>
    This is free software distributed under the terms of the GNU Public
    License.  Full text of the license is available from the GNU Project:
    http://www.fsf.org/copyleft/gpl.html

    @creation-date 28 September 2000
    @author Henry Minsky (hqm@mit.edu)
    @author Lars Pind (lars@pinds.com)
    @cvs-id $Id: locale-procs.tcl,v 1.53 2024/09/11 06:15:48 gustafn Exp $
}

namespace eval lang::system {}
namespace eval lang::user {}
namespace eval lang::conn {}



#####
#
# lang::system
#
#####

ad_proc -public lang::system::use_package_level_locales_p {} {
    Returns whether we're using package level locales.
} {
    return [parameter::get -parameter UsePackageLevelLocalesP -package_id [apm_package_id_from_key "acs-lang"] -default 0]
}

d_proc -public lang::system::site_wide_locale {
} {
    Get the site-wide system locale setting.
} {
    set parameter_locale [parameter::get \
                -package_id [apm_package_id_from_key "acs-lang"] \
                -parameter "SiteWideLocale" \
                -default "en_US"]

    # Check validity of parameter setting
    set valid_locales [lang::system::get_locales]
    if {$parameter_locale ni $valid_locales} {
        ns_log Error "The parameter setting acs-lang.SiteWideLocale=\"$parameter_locale\" is invalid. Valid locales are: \"$valid_locales\". Defaulting to en_US locale"
        return en_US
    }

    return $parameter_locale
}

d_proc -private lang::system::package_level_locale_not_cached {
    package_id
} {
    return [db_string get_package_locale {} -default {}]
}

d_proc -public lang::system::package_level_locale {
    package_id
} {
    @return empty string if not use_package_level_locales_p, or the package locale from apm_packages table.
} {
    if { ![use_package_level_locales_p] } {
        return {}
    }

    return [util_memoize [list lang::system::package_level_locale_not_cached $package_id]]
}

d_proc -public lang::system::locale {
    {-package_id ""}
    {-site_wide:boolean}
} {
    Get system locale setting for a given package instance.

    @param package_id The package for which you want to get the locale setting.
    @param site_wide Set this if you want to get the site-wide locale setting.
} {
    if { $site_wide_p } {
        return [site_wide_locale]
    }

    if { $package_id eq "" && [ns_conn isconnected] } {
        set package_id [ad_conn package_id]
    }

    # Get locale for package

    set locale [package_level_locale $package_id]

    # If there's no package setting, use the site-wide setting
    if { $locale eq "" } {
        set locale [site_wide_locale]
    }
    return $locale
}

d_proc -public lang::system::set_locale {
    {-package_id ""}
    locale
} {
    Set system locale setting for a given package instance, or the
    site-wide system locale.

    @param package_id The package for which you want to set the locale setting, if you want to set system setting for one package only. Leave blank for site-wide setting.
    @param locale The new locale that you want to use as your system locale.
} {
    if { $package_id eq "" } {

        parameter::set_value \
            -package_id [apm_package_id_from_key "acs-lang"] \
            -parameter SiteWideLocale \
            -value $locale

    } else {
        # Update the setting
        db_dml update_system_locale {}

        # Flush the cache
        util_memoize_flush [list lang::system::package_level_locale_not_cached $package_id]

        # TODO: We will need to have site-map inheritance for this, so packages under a subsite/dotlrn inherit the subsite's/dotlrn's setting
    }
}

d_proc -public lang::system::language {
    {-package_id ""}
    {-site_wide:boolean}
    {-iso6392:boolean}
} {
    Get system language setting for a given package instance.

    @param package_id The package for which you want to get the language setting.
    @param site_wide Set this if you want to get the site-wide language setting.
    @param iso6392   Set this if you want to force iso-639-2 code (3 digits)

    @return 3 chars language code if iso6392 is set, left part of locale otherwise

} {
    set locale [locale -package_id $package_id -site_wide=$site_wide_p]
    set sys_lang [lindex [split $locale "_"] 0]

    if { $iso6392_p } {
        return [lang::util::iso6392_from_language -language $sys_lang]
    } else {
        return $sys_lang
    }
}

ad_proc -public lang::system::timezone {} {
    Ask OpenACS what it thinks our timezone is.

    @return  a timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)
} {
    set package_id [apm_package_id_from_key "acs-lang"]
    return [parameter::get -package_id $package_id -parameter SystemTimezone -default "Etc/UTC"]
}

d_proc -public lang::system::set_timezone {
    timezone
}  {
    Tell OpenACS what timezone we think it's running in.

    @param timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)
} {
    set package_id [apm_package_id_from_key "acs-lang"]
    parameter::set_value -package_id $package_id -parameter SystemTimezone -value $timezone
}

ad_proc -public lang::system::timezone_utc_offset { } {
    @return number of hours to subtract from local (database) time to get UTC
} {
    set system_timezone [timezone]
    return [db_string system_utc_offset {}]
}

d_proc -public lang::system::get_locales {
    {-all:boolean}
} {

    Return all locales defined in the system. Per default only the
    enabled locales are returned. When the optional flag "-all" is
    specified, all defined locales are returned.
    
    This value is cached per thread and needs currently a server
    restart, when the system locales are changed.

    @author Peter Marklund
} {
    return [acs::per_thread_cache eval -key acs-lang.system_get_locales-$all_p {
        if {$all_p} {
            db_list select_defined_system_locales { select locale from ad_locales }
        } else {
            db_list select_enabled_system_locales {
                select locale
                from   ad_locales
                where  enabled_p = 't'
            }
        }
    }]
}

ad_proc -public lang::system::get_locale_options {} {
    Return all enabled locales in the system in a format suitable for the options argument of a form.

    @author Lars Pind
} {
    return [util_memoize lang::system::get_locale_options_not_cached]
}

d_proc -public lang::system::locale_set_enabled {
    {-locale:required}
    {-enabled_p:required}
} {
    Enables or disables a locale.

    @param enabled_p Should be t or f

    @author Peter Marklund
} {
    db_dml set_enabled_p { update ad_locales set enabled_p = :enabled_p where locale = :locale }

    # Flush caches
    acs::per_thread_cache flush -pattern acs-lang.system_get_locales-*
    util_memoize_flush_regexp {^lang::util::default_locale_from_lang_not_cached}
    util_memoize_flush_regexp {^lang::system::get_locales}
    util_memoize_flush_regexp {^lang::system::get_locale_options}
}


ad_proc -private lang::system::get_locale_options_not_cached {} {
    Return all enabled locales in the system in a format suitable for the options argument of a form.

    @author Lars Pind
} {
    return [db_list_of_lists select_locales {}]
}


#####
#
# lang::user
#
#####

d_proc -private lang::user::package_level_locale_not_cached {
    user_id
    package_id
} {
    Get the user's preferred package level locale for a package
    given by its package id. Will return the empty string if the
    user has not preference for the package.
} {
    return [db_string get_user_locale {} -default ""]
}

d_proc -public lang::user::package_level_locale {
    {-user_id ""}
    package_id
} {
    Get the user's preferred package level locale for a package
    given by its package id.
} {
    # default to current user
    if { $user_id eq "" } {
        set user_id [ad_conn untrusted_user_id]
    }

    # If package-level locales are turned off, or the user isn't logged in, return the empty string
    if { ![lang::system::use_package_level_locales_p] || $user_id == 0 } {
        return {}
    }

    # Cache for the lifetime of sessions (7 days)
    return [util_memoize [list lang::user::package_level_locale_not_cached $user_id $package_id] [sec_session_timeout]]
}

d_proc -public lang::user::site_wide_locale {
    {-user_id ""}
} {
    Get the user's preferred site-wide locale.
} {
    # default to current user
    if { $user_id eq "" } {
        set user_id [ad_conn untrusted_user_id]
    }

    # For all the users with a user_id of 0 don't cache.
    if { $user_id == 0} {
        return [lang::user::site_wide_locale_not_cached $user_id]
    }

    # Cache for the lifetime of sessions (7 days)
    return [util_memoize [list lang::user::site_wide_locale_not_cached $user_id] [sec_session_timeout]]
}

d_proc -private lang::user::site_wide_locale_not_cached {
    user_id
} {
    Get the user's preferred site-wide locale.
} {
    set system_locale [lang::system::site_wide_locale]

    if { $user_id == 0 } {
        set cookie_name [security::cookie_name locale]
        set locale [ad_get_cookie $cookie_name]
        if {$locale ne ""} {
            #
            # Check, if someone hacked the cookie
            #
            if {$locale ni [lang::system::get_locales]} {
                ns_log warning "ignoring invalid ad_locale cookie '$locale'"
                set locale ""
                #
                # The cookie was invalid, so get rid of it.
                #
                ad_unset_cookie $cookie_name
            }
        }
    } else {
        set locale [db_string get_user_site_wide_locale {} -default ""]
    }

    #
    # When no locale cookie is set, or the locale is invalid or empty,
    # fall back to system locale.
    #
    if { $locale eq "" } {
        set locale $system_locale
    }

    return $locale
}

d_proc -public lang::user::locale {
    {-package_id ""}
    {-site_wide:boolean}
    {-user_id ""}
} {
    Get user locale preference for a given package instance.

    @param package_id The package for which you want to get the locale preference.
    @param site_wide Set this if you want to get the site-wide locale preference.
    @param user_id Set this to the user you want to get the locale of, defaults to current user.
} {
    # default to current user
    if { $user_id eq "" } {
        set user_id [ad_conn untrusted_user_id]
    }

    # default to current connection package
    if { $package_id eq "" } {
        set package_id [ad_conn package_id]
    }

    if {$site_wide_p} {
        set locale [site_wide_locale -user_id $user_id]
    } else {
        #
        # Try package level locale first unless site_wide_p was
        # specified.
        #
        set locale [package_level_locale -user_id $user_id $package_id]
        #
        # If there's no package setting, then use the site-wide
        # setting.
        #
        if { $locale eq "" } {
            set locale [site_wide_locale -user_id $user_id]
        }
    }

    return $locale
}

d_proc -public lang::user::set_locale {
    {-package_id ""}
    {-user_id ""}
    locale
} {
    Set user locale setting for a given package instance.

    @param package_id The package for which you want to set the locale setting, if you want to set it for a specific package, as opposed to a site-wide setting.
    @param locale The new locale that you want to use as your system locale.
} {
    if { $user_id eq "" } {
        set user_id [ad_conn user_id]
    }

    if { $user_id == 0 } {
        # Not logged in, use a cookie-based client locale
        set cookie_name [security::cookie_name locale]
        ad_set_cookie -replace t -max_age inf -samesite strict $cookie_name $locale

        # Flush the site-wide user preference cache
        util_memoize_flush [list lang::user::site_wide_locale_not_cached $user_id]
        return
    }

    if { $package_id eq "" } {
        # Set site-wide locale in user_preferences table
        db_dml set_user_site_wide_locale {}

        # Flush the site-wide user preference cache
        util_memoize_flush [list lang::user::site_wide_locale_not_cached $user_id]
        return
    }

    # The rest is for package level locale settings only
    # Even if package level locales are disabled, we'll still do this

    set user_locale_exists_p [db_string user_locale_exists_p {}]
    if { $user_locale_exists_p } {
        if { $locale ne "" } {
            db_dml update_user_locale {}
        } else {
            db_dml delete_user_locale {}
        }
    } else {
        if { $locale ne "" } {
            db_dml insert_user_locale {}
        }
    }

    # Flush the user locale preference cache
    util_memoize_flush [list lang::user::package_level_locale_not_cached $user_id $package_id]
}

d_proc -public lang::user::language {
    {-package_id ""}
    {-user_id ""}
    {-site_wide:boolean}
    {-iso6392:boolean}
} {
    Get user language preference for a given package instance.
    This preliminary implementation only has one site-wide setting, though.

    @param package_id The package for which you want to get the language setting.
    @param user_id The user we wish to get the language for, defaults to connection user.
    @param site_wide Set this if you want to get the site-wide language setting.
    @param iso6392   Set this if you want to force iso-639-2 code (3 digits)

    @return 3 chars language code if iso6392 is set, left part of locale otherwise

} {
    set locale [locale -package_id $package_id -user_id $user_id -site_wide=$site_wide_p]
    set user_lang [lindex [split $locale "_"] 0]

    if { $iso6392_p } {
        return [lang::util::iso6392_from_language -language $user_lang]
    } else {
        return $user_lang
    }
}


ad_proc -private lang::user::timezone_no_cache {user_id} {
    return [db_string select_user_timezone {} -default ""]
}

ad_proc -public lang::user::timezone {} {
    Get the user's timezone. Returns the empty string if the user
    has no timezone set.

    @return  a timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)
} {
    set user_id [ad_conn user_id]
    if { $user_id == 0 } {
        return ""
    }

    return [util_memoize [list lang::user::timezone_no_cache $user_id]]
}

d_proc -public lang::user::set_timezone {
    timezone
}  {
    Set the user's timezone setting.

    @param timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)
} {
    set user_id [ad_conn user_id]

    if { $user_id == 0 } {
        error "User not logged in"
    } else {
        db_dml set_user_timezone {}
        util_memoize_flush [list lang::user::timezone_no_cache $user_id]
    }
}





#####
#
# lang::conn
#
#####

d_proc -private lang::conn::locale_not_cached {
    {-package_id ""}
    {-site_wide:boolean}
    {-user_id ""}
} {
    Get the locale for this request, perhaps for a given package instance.

    This is the not-cached version.

    @param package_id The package for which you want to get the locale.
    @param site_wide Set this if you want to get the site-wide locale.
} {
    if { $site_wide_p } {
        set locale [lang::user::site_wide_locale]

        if { $locale eq "" } {
            set locale [lang::system::site_wide_locale]
        }

        #
        # Fallback to en_US when no locale is found or is not one of
        # those we support.
        #
        if { $locale eq "" || $locale ni [lang::system::get_locales]} {
            set locale en_US
        }

        return $locale
    }

    # default value for package_id

    if { $package_id eq "" } {
        set package_id [ad_conn package_id]
    }

    # use user's package level locale

    set locale [lang::user::package_level_locale -user_id $user_id $package_id]

    # if that does not exist use system's package level locale

    if { $locale eq "" } {
        set locale [lang::system::package_level_locale $package_id]
    }

    # if that does not exist use user's site-wide locale

    if { $locale eq "" } {
        set locale [lang::user::site_wide_locale -user_id $user_id]
    }

    # Use the accept-language browser heading

    if { $locale eq "" && [ns_conn isconnected]} {
        set locale [lang::conn::browser_locale]
    }

    # if that does not exist use system's site-wide locale

    if { $locale eq "" } {
        set locale [lang::system::site_wide_locale]
    }

    # if that does not exist, or is not supported, then we are back to
    # just another language let's pick uhmm... en_US

    if { $locale eq "" || $locale ni [lang::system::get_locales]} {
        set locale en_US
    }

    return $locale
}

d_proc -public lang::conn::locale {
    {-package_id ""}
    {-site_wide:boolean}
    {-user_id ""}
} {
    Get the locale for this request, perhaps for a given package instance.

    @param package_id The package for which you want to get the locale.
    @param site_wide Set this if you want to get the site-wide locale.
} {
    # Notice that caching for longer than the single request would be
    # more complex, e.g. defaults coming from ad_conn in the various
    # procs and flushing.
    return [acs::per_request_cache eval \
                -key acs-lang.lang.conn.locale($package_id,$site_wide_p,$user_id) {
                    lang::conn::locale_not_cached \
                        -package_id $package_id \
                        -site_wide=$site_wide_p \
                        -user_id $user_id
                }]
}

ad_proc -private lang::conn::browser_locale {} {
    Get the users preferred locale from the accept-language
    HTTP header.

    @return A locale or an empty string if no locale can be found that
            is supported by the system

    @author Lars Pind
    @author Peter Marklund
} {
    set conn_locales [lang::conn::get_accept_language_header]

    set system_locales [lang::system::get_locales]

    foreach locale $conn_locales {
        regexp {^([^_]+)(?:_([^_]+))?$} $locale locale language region

        if { [info exists region] && $region ne "" } {
            # We have both language and region, e.g. en_US
            if {$locale in $system_locales} {
                # The locale was found in the system, a perfect match
                set perfect_match $locale
                break
            } else {
                # We don't have the full locale in the system but check if
                # we have a different locale with matching language,
                # i.e. a tentative match
                if { ![info exists tentative_match] } {
                    set default_locale [lang::util::default_locale_from_lang $language]
                    if { $default_locale ne "" } {
                        set tentative_match $default_locale
                    }
                } else {
                    # We already have a tentative match with higher priority so
                    # continue searching for a perfect match
                    continue
                }
            }
        } else {
            # We have just a language, e.g. en
            set default_locale [lang::util::default_locale_from_lang $locale]
            if { $default_locale ne "" } {
                set perfect_match $default_locale
                break
            }
        }
    }

    if { [info exists perfect_match] && $perfect_match ne "" } {
        return $perfect_match
    } elseif { [info exists tentative_match] && $tentative_match ne "" } {
        return $tentative_match
    } else {
        # We didn't find a match
        return ""
    }
}

ad_proc -private lang::conn::valid_locale_p {locale} {
    Check, of the provided locale is syntactically correct
} {
    return [regexp {^[a-zA-Z]+(_[a-zA-Z0-9]+)?$} $locale]
}

ad_proc -private lang::conn::get_accept_language_header {} {
    Obtain a list of locals from the request headers.
    @return a list of locales in the syntax used by OpenACS (ISO codes)
} {
    set acclang [ns_set iget [ns_conn headers] "Accept-Language"]

    # Split by comma, and get rid of any ;q=0.5 parts
    # acclang is something like 'da,en-us;q=0.8,es-ni;q=0.5,de;q=0.3'
    set acclangv [list]
    foreach elm [split $acclang ","] {
        # Get rid of trailing ;q=0.5 part and trim spaces
        set elm [string trimleft [lindex [split $elm ";"] 0] " "]
        # Ignore the default catchall setting "*"
        if {$elm eq "*"} {
            continue
        }
        # elm is now either like 'da' or 'en-us'
        # make it into something like 'da' or 'en_US'
        set elmv [split $elm "-"]
        set elm [lindex $elmv 0]
        if { [llength $elmv] > 1 } {
            append elm "_[string toupper [lindex $elmv 1]]"
        }
        if {[lang::conn::valid_locale_p $elm]} {
            lappend acclangv $elm
        } else {
            # It is usually bots or other kinds of not-canonical web
            # browsers which set this wrong. We tolerate it by
            # assuming our default language.
            ns_log warning "Invalid locale '$elm' in provided Accept-Language header field. Defaulting to system locale."
            return [lang::system::locale]
        }
    }

    return $acclangv
}

d_proc -public lang::conn::language {
    {-package_id ""}
    {-user_id ""}
    {-site_wide:boolean}
    {-iso6392:boolean}
    {-locale ""}
} {
    Get the language for this request, perhaps for a given package instance.

    @param package_id The package for which you want to get the language
           (used only when, no locale is provided).
    @param user_id The user_id for whom you want to get the language
           (used only when, no locale is provided).
    @param site_wide Set this if you want to get the site-wide language
               (used only when, no locale is provided).
    @param iso6392   Set this if you want to force the iso-639-2 code
    @param locale    obtain language from provided locale

    @return 3 chars language code if iso6392 is set, left part of locale otherwise
} {
    if {$locale eq ""} {
        set locale [locale -package_id $package_id -user_id $user_id -site_wide=$site_wide_p]
    }
    set conn_lang [lindex [split $locale "_"] 0]

    if { $iso6392_p } {
        return [lang::util::iso6392_from_language -language $conn_lang]
    } else {
        return $conn_lang
    }
}

d_proc -public lang::conn::charset {
} {
    Returns the MIME charset name corresponding to the current connection's locale.

    @author        Lars Pind (lars@pinds.com)

    @return        IANA MIME character set name
} {
    return [lang::util::charset_for_locale [lang::conn::locale]]
}

ad_proc -public lang::conn::timezone {} {
    Get this connection's timezone. This is the user timezone, if
    set, otherwise the system timezone.

    @return  a timezone name from acs-reference package (e.g., Asia/Tokyo, America/New_York)
} {
    set timezone {}
    if { [ad_conn isconnected] } {
        set timezone [lang::user::timezone]
    }

    if { $timezone eq "" } {
        # No user timezone, return the system timezone
        set timezone [lang::system::timezone]
    }
    return $timezone
}

# Local variables:
#    mode: tcl
#    tcl-indent-level: 4
#    indent-tabs-mode: nil
# End: