Documentation ¶
Overview ¶
Package lpax is a strong keyed string repository implementation supporting internationalisation and separation of text definition from usage.
Applications and library packages typically embed string and error messages within the code. Placing strings inline within the code can make it harder to internationalise the code or to extract a list of all error messages generated by an application. `lpax` provides method of registering strings that can be accessed via decentralised keys. The key system uses Go's strong typing to allow each package to create its own key system without risking overlapping with other packages keys. multiple languages can be supported for key, with fallback logic to us the default `english` language.
The example below shows how to implement a typical language package.
Example ¶
package main import ( "fmt" "github.com/nehemming/lpax" "golang.org/x/text/language" ) type ( // PackID is the local package id. // Each package should implement its own PackID type. // They are typically derived from the `int` type. PackID int // TextID is the id type for all messages defined by this package. // the TextID type must implement the lpax.TextID interface, but is typically // based on a `int` type. As the package defines its own TextID it is // unique from other package types, and thus so are the ids. TextID int ) // Single returns the id of for a single version of a message. // Typical implementations use the lpax helper functions to implement the id system. // Positive id's are used for single messages while -ve id's areused for plural versions. func (id TextID) Single() lpax.TextID { return TextID(lpax.IntTypeSingle(int(id))) } // Plural returns the plural version of the id. func (id TextID) Plural() lpax.TextID { return TextID(lpax.IntTypePlural(int(id))) } // String implements stringer function. // ReflectCoderString reflects the package name used // by the parent package along with the +ve integer id of the key. func (id TextID) String() string { return lpax.ReflectCoderString(id.Single(), 1) } const ( // ExamplePackID is the unique typed id for this pack. ExamplePackID = PackID(1) // None is a default empty message (id 0). None = TextID(iota) // Hello is an example message. Hello ) var pack = lpax.TextMap{ Hello: "Hello World", -Hello: "Hello Worlds", } // register is the text registry callback function used to return the text mappings. func register(packID lpax.PackID, langTag lpax.Tag) lpax.TextMap { return pack } func init() { // register the text mappings with the share test registry. lpax.Default().Register(ExamplePackID, register, lpax.DefaultPriority, language.English) } func main() { fmt.Println(lpax.Sprintf(Hello)) fmt.Println(lpax.Sprintf(Hello.Plural())) }
Output: Hello World Hello Worlds
Index ¶
- Constants
- func CtxErrorf(ctx context.Context, id TextID, args ...interface{}) error
- func CtxSprintf(ctx context.Context, id TextID, args ...interface{}) string
- func DetectLocaleLanguage() (language.Tag, error)
- func Errorf(id TextID, args ...interface{}) error
- func IntTypePlural(id int) int
- func IntTypeSingle(id int) int
- func MustDetectLocaleLanguage(fallback string) language.Tag
- func ReflectCoderString(v interface{}, level ...int) string
- func Sprintf(id TextID, args ...interface{}) string
- func WithContext(ctx context.Context, tf TextFinder) context.Context
- type OnRegister
- type PackID
- type Priority
- type Tag
- type TextFinder
- type TextID
- type TextMap
- type TextRegistry
Examples ¶
Constants ¶
const ( // AdditionalPacks are added after the original packs. AdditionalPacks = Priority(iota) // Package standard priority when a language included // its own messages, these are treated as the default. Package // Override use when registration wants preference over // the default implementation. // This should only be done by applications (package main's). Override // DefaultPriority default type priority. DefaultPriority = Package )
const DefaultLanguage = "en"
DefaultLanguage is the default fallback language.
Variables ¶
This section is empty.
Functions ¶
func CtxErrorf ¶
CtxErrorf is identical to fmt.Errorf except the format string is taken from the text finder linked to the passed context. If the context has no finder the default finder is used. If the string is not found the string version of the id is printed along with a space separated %v version of each arg.
func CtxSprintf ¶
CtxSprintf is identical to fmt.Sprintf except the format string is taken from the text finder linked to the passed context. If the context has no finder the default finder is used. If the string is not found the string version of the id is printed along with a space separated %v version of each arg.
func DetectLocaleLanguage ¶
DetectLocaleLanguage returns the language of the current process or an error if it cannot be found.
func Errorf ¶
Errorf is identical to fmt.Errorf except the format string is taken from the default text finder. If the string is not found the string version of the id is printed along with a space separated %v version of each arg.
func IntTypePlural ¶
IntTypePlural returns the integer id for a plural message. This is a helper function for implementors of TextID.
func IntTypeSingle ¶
IntTypeSingle returns the integer id for a single message. This is a helper function for implementors of TextID.
func MustDetectLocaleLanguage ¶
MustDetectLocaleLanguage attempts to get the current the users language. If this is not discoverable the fallback language string will be tried. If this also fails or is not provided the function panics.
func ReflectCoderString ¶
ReflectCoderString supports the Coder interface by generating a description for an error code from its package path. v must be a int value kind, otherwise v is returned as a "%v" formatted string level is a single variadic value optionally specifying how many levels to traverse to get the path name. eg. package/path/here/place would return 0 - place, 1 - here etc.
func Sprintf ¶
Sprintf is identical to fmt.Sprintf except the format string is taken from the default text finder. If the string is not found the string version of the id is printed along with a space separated %v version of each arg.
func WithContext ¶
func WithContext(ctx context.Context, tf TextFinder) context.Context
WithContext creates a new context based off the passed ctx with the textFinder bound into the new context.
Types ¶
type OnRegister ¶
OnRegister is the a callback function signature used to locate a registered language pack and return a TextMap containing its contents. The callback will only be called for pack IDs and languages that were registered with the registry. OnRegister may be called each time Registry New is called.
type PackID ¶
type PackID = interface{}
PackID uses Go's strong typing system to create a unique identifier for a collection of string resources The pack ID is used to link different language version of the same pack together.
type Priority ¶
type Priority int
Priority type to specify pack registration priority Priority is used by Text Registration types to prioritize their stored items. Items registered by an implementing package should register with Package priority If registering additional languages can use AdditionalPacks priority There packs will not take priority over the package implementors text map for a language defined in both. However AdditionalPacks priority allows extra languages to be added. Override priority can (and should only) be used by main application registrations where there is a need to replace a package registrations.
type TextFinder ¶
type TextFinder interface { // Text looks up a text ID and returns the string associated with it or an empty string. Text(textID TextID) string // Find looks up the passed textID key and returns true if found Find(textID TextID) (t string, found bool) }
TextFinder looks up a text ID and returns the string associated with it or an empty string, found.
func FromContext ¶
func FromContext(ctx context.Context) TextFinder
FromContext returns the TextFinder bound into the context or if none if sound returns the Default TextFinder.
type TextID ¶
type TextID interface { fmt.Stringer // Single is the id for the singular version of the text. Single() TextID // Plural is the id for the plural version of the text. Plural() TextID }
TextID is a unique identifier for a text message. Source/package family should use a unique type to identify its messages valid types must be of an integer (intX or UIntX) type, a string or a struct The provider will panic if any other type is used If the identifier supports exterr.ErrorCoder or fmt.Stringer these interfaces will be used when rasing errors using Errorf or Sprintf.
type TextMap ¶
TextMap maps TextID keys to strings.
func NewTextMap ¶
NewTextMap creates a new text map by merging zero or more exiting maps.
type TextRegistry ¶
type TextRegistry interface { TextFinder // Register maintains a collection of supported language packs by language. // The callback OnRegister function will be called if one of the registered language packs // needs to be loaded // The priority allows multiple overlapping TextMaps to be multiply registered for the same // language, giving increasing priority registrations in the order AdditionalPacks, Package and finally Override. // langTags is a list of languages that are being registered. The first language has highest priority. Register(packID PackID, callback OnRegister, priority Priority, langTags ...Tag) TextRegistry // New returns a new text finder created from the registry. Each call creates a new finder // options can be language Tags and additional TextMaps // language Tags must be supplied with the fallback language being first language in the list, if no language is provided the // DefaultLanguage is used. New(options ...interface{}) TextFinder }
TextRegistry maintains a list of registered resource TextMaps by language. The registries New function builds language specifc TextProviders from the registered resource strings THe registry also creates a shared runtime TextProvider using the process owners detected language.