Download the PHP package gtbabel/core without Composer

On this page you can find all versions of the php package gtbabel/core. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package core

Build Status

🌐 Gtbabel 🌐

Gtbabel automatically translates your HTML/PHP pages – server sided.

Basic idea

Features

Requirements

Installation

Install once with composer:

Then add this to your files:

Usage

Configuration

If you don't provide an initial configuration, Gtbabel starts with reasonable default settings.\ You also can provide settings directly as an array or pass a path to a json file to overwrite (parts) of the default settings:

The default configuration is:

Other usage

Gtbabel catches the content between start() and stop() with output buffering.\ However, you can also use Gtbabel more directly:

WordPress plugin

wordpress.org/plugins/gtbabel

You don't have to change any code in the frontend at all: If you already have functions like __() in your code, just either remove them or simply leave them (since WordPress internally only knows about the source language and __() has no effect); if not, don't add them. Gtbabel acts on the output (like on any other page).

The following features are included:

Permissions

Gtbabel for WordPress uses the following capabilities:

By default, administrators have all capabilities (except gtbabel__email_notifications).\ You can add these capabilities to your WordPress user roles individually

The following example gives the role "Editor" translation permissions for the languages English and Français in the translation assistant:

Email notifications

With the wp_mail_notifications option you can instruct Gtbabel to send regular status e-mails to all translators (that have both the gtbabel__translation_assistant and gtbabel__email_notifications role):

Make sure that WP-Cron is enabled and running regularly and mails can be sent properly from your server.

Database and Gettext

JavaScript

Gtbabel itself is based on PHP and works for static pages or pages rendered via PHP.

However, if you enable detect_dom_changes, Gtbabel monitors dom changes and translates suitable parts.

To get translations directly in JavaScript, Gtbabel also provides a small helper function to hotload your translations in the header that works in every environment. For this purpose the option localize_js_strings must be filled with content. You then can access those strings easily inside JavaScript with:

If you are on WordPress, you might already use the wp_localize_script function. Keep doing that and simply use gtbabel__() via PHP to translate the strings you want to be provided in JavaScript:

Another way of doing this is using the translate_wp_localize_script option: Populate translate_wp_localize_script_include with key chained paths to (possibly nested) strings and Gtbabel translates whem automatically.

Modified nodes

By default Gtbabel translates all text and tag nodes with the following reasonable default rules:

css selector text attribute context
body * βœ“ βœ— auto
body a βœ— href^="mailto" email
body a βœ— href 'slug'\|'file'\|'url'
body form βœ— action 'slug'\|'file'\|'url'
iframe βœ— src 'slug'\|'file'\|'url'
body img βœ— alt auto
body * βœ— title auto
body * βœ— placeholder auto
body input[type="submit"] βœ— value auto
body input[type="reset"] βœ— value auto
head title βœ“ βœ— 'title'
head meta[name="description"] βœ— content 'description'
head link[rel="canonical"] βœ— href 'slug'
head meta[property="og:title"] βœ— content 'title'
head meta[property="og:site_name"] βœ— content 'title'
head meta[property="og:description"] βœ— content 'description'
head meta[property="og:url"] βœ— content 'slug'\|'file'\|'url'
body img βœ— src 'file'
body img βœ— srcset 'file'
body picture source βœ— srcset 'file'
body * βœ— style 'file'
body * βœ— label auto
body * βœ— *text* auto

You can modify or add new tag node transformations via the translate_html_include option.

For example if you want to translate all data attributes, add this rule:

Or if you want to translate a specific data attribute (and want to use css selectors instead of xpath), you can use:

Be aware that the rules are processed sequentially and attribute names are never transformed twice.

Gtbabel automatically groups together reasonable parts.\ The following code gets converted to 1 token (not 3):

<p>This is a <a href="#">link</a> inside a text.</p>

If you want to influence that behaviour, use the translate_html_force_tokenize option and provide the selector of the parent element in order to not tokenize its children.

If you want to influence that special tags should not be auto translated by the Google/Microsoft/DeepL Translation API, use a special class:

<p>Das ist das <span class="notranslate">Haus</span> vom Nikolaus</p>

The part before and after the span-tag gets translated (and added to the database).\ If you want to exclude a complete node of being translated (and not added to the database), add a class with the value notranslate (or any other value defined in translate_html_exclude) to the parent node:

<p class="notranslate">Das ist das <span>Haus</span> vom Nikolaus</p>

Note that attributes of ignored nodes are also not translated (the href-attribute and the text Link does not get translated):

<a href="/home" class="notranslate">Link</a>

However, if you want the href-attribute to be modified, do something like

<a href="/home"><span class="notranslate">Link</span></a>

HTML

Gtbabel preserves inline HTML-tags and leaves them inside your translations.\ However, attributes are automatically stripped. So

<a href="https://tld.com" class="foo" data-bar="baz">Hallo</a> Welt!

gets converted to

<a>Hallo</a> Welt!

and that string is e.g. stored in a translation as

<a>Hello</a> world!

so that your translators are not confused with unnecessary clutter.\ The translated version has of course the attributes back again:

<a href="https://tld.com" class="foo" data-bar="baz">Hello</a> world!

However, if ordering is crucial, Gtbabel provides a mechanism to determine order (and duplication).\ So for example

Das deutsche <a href="https://1.com">Brot</a> <a href="https://2.com">vermisse</a> ich am meisten.

is stored in the database as

Das deutsche <a>Brot</a> <a>vermisse</a> ich am meisten.

If your translations don't reflect the original order, in the database they include hints like

I <a p="2">miss</a> German <a p="1">bread</a> the most.

where "2" stands for the second tag of the original string.

The string then finally gets correctly translated to

I <a href="https://2.com">miss</a> German <a href="https://1.com">bread</a> the most..

Note that in the following example, these hints are not necessary (Gtbabel can match the tags despite a different order):

Das deutsche <a href="https://1.com">Brot</a> <span>vermisse</span> ich am meisten.

Ambiguous translations and plural forms

Consider the following example:

Normally Gtbabel would create 2 translations from this and cannot distinguish between ambiguous translations and singular/plural forms.

In order to get that use the special data-context-attribute to force sensible contexts:

This way you can provide different translations.

Multiple source languages

Gtbabel is not restricted to use one single source language for the whole content.\ In fact, parts of the content can be marked language-specific:

This all gets translated correctly to the target language (in our case de):

In WordPress there is a convenient way of defining a different source language\ for whole posts or pages or even on block level.

Hiding content

Besides providing content in different source languages, you can hide specific dom nodes entirely:

Note that rendered means completely missing from the DOM.

This is (in conjunction with the css classes notranslate to prevent translation and force-tokenize to force tokenization and the lang-attribute) an attempt to get around the intended limitation of Gtbabel that all content is always translated into all languages.

In WordPress you individually can configure in which languages a specific page should be translated. An exclusive view for logged-in users is also possible – this allows you to prepare translations in quietly before they are available to the public.

Router

The router automatically modifies the $_SERVER['REQUEST_URI'] variable to catch translated urls.\ Unknown translations of urls are picked up from the current url and from links that are on the page.\ These urls are automatically added to the database (ajax requested urls are excluded).

Domain schema

Gtbabel by default uses a path based approach for your url structure.\ That means: The language code is always appended to your main url:

https://www.tld.com/de/

You can change this behaviour in any way you like.\ Just extend the languages-option with url_base and url_prefix.\ The following configuration is the same as if no option isset:

In order to not prefix your source language (which is often common), just provide a special rule for it\ (see we didn't specify url_base and any option for the other languages, because Gtbabel still uses the default there):

With this technique we can use custom language codes in our urls:

Or we can easily setup a subdomain based approach:

Even a multidomain based approach is possible:

If you have hosted your website on a subpath, you should provide something like:

And if you don\'t even use pretty links, leave all prefixes empty (the url query argument lang decides then):

The configuration is totally up to you (you can even mix approaches).\ You only have to make sure that all top level domains point to the same root path.

Dealing with assets

Although Gtbabel leaves static files untouched, it adds them to the template file (with context file). This gives you the possibility to output images, downloads and other media individually per language.

JSON Responses

JSON responses can also be translated by Gtbabel when setting translate_json to true and populating translate_json_include.\ If your json endpoint is not targeted via a language specific url, you can get the language via gtbabel_referer_lng().

Translation management

With the unchecked_strings option you can control what happens with unchecked strings:

This way you can build an approval system in your backend, where translators can check strings before they are published.

One common approach is to dynamically override this setting if a user is logged in:

Flow diagram

Language picker

To output a language picker, just use this snippet:

Make sure that the container class is excluded from your translations.

Helper functions

Always surround these helper functions with if( function_exists('...') ) { }.

As you can see, these helper functions are static functions, so in a normal environment route based settings are derived when you call these functions and every time implicitly a new instance of Gtbabel is created. However, if you want to use a previous instance again, declare it as global:

Echoing strings

Don't use gtbabel__() in your templates for echoing strings, just output them in the source language. Gtbabel will take care of the rest. However, there are some places (for example in very specific cases in your frontend or also in your backend logic), where you need to translate strings. This is what this function is intended for.

One example would be a dynamically generated facebook share link, where Gtbabels parser is powerless. You can help out with:

You also can set the target and source language manually to get some specific translation. Because translations are not injective, the following two calls create two database entries (with different source languages):

You can provide any html to gtbabel__():

The function is smart enough to detect urls or even root relative urls and returns appropriate translations:

However, you can also get a translation in a specific context:

Dynamic data

Gtbabel translates your frontend, json responses and watches dom changes.\ Nevertheless, one has to manually take care of how multilingual input data should be further processed.

Search

Doing search on translated content is hard, but can be addressed with different approaches:

Approach 1: Translating the search term

A quite effective and easy approach is to translate all incoming search queries into your source language\ before actually querying your content (provided in source language):

As you can see, such search queries get the special context search_term so they can be filtered out or garbage collected later on.

The caveat here is that you essentially translate all incoming queries, so be aware of that and use the throttle_chars_per_month option.

The results are also not accurate, because previously unseen queries are always translated ad-hoc. Also it does not work for content in multiple source languages.

Approach 2: Searching in parsed html

Another approach is to search generated cached html pages.\ Since Gtbabel does not cache pages, you have to have your caching system running.

Translated pages can be basically treated like pages in source language,\ since they are both just html, which can be searched.

Also evaluate if you can try to use the Google Programmable Search Engine, which follows the same idea.

Approach 3: Building a custom search index

In this approach you build a search index for every object\ you want to include into the search results.

You collect and permanently store all strings in the source language,\ translate them (once) by Gtbabel and also permanently store these translations.

This way you can combine the best of the above approaches,\ although it involves the largest integration effort.

Approach 4: Searching in translations

One approach is to use the search term (not in source language) and\ search inside the translated content instead.

You have to modify your search queries manually – in SQL this could look like this:

Before:

After:

This idea can be expanded significantly (e.g. by using regex patterns).\ Note that this also works for content in different source languages.\ In WordPress this approach is implemented and works automatically – providing full text search on all meta fields.

URL query arguments

As for url query arguments, you have fine grained control over whether arguments should be kept, translated or discarded via the url_query_args-option.

Be aware: If you set a key to translate, external content potentially gets automatically translated.

Furthermore url hashes (beginning with #) are always kept.

Note that query arguments for email links get automatically translated:

<a href="mailto:?subject=Dies%20ist%20ein%20Test&amp;body=Das%20funktioniert">E-Mail senden</a>

gets transformed to

<a href="mailto:?subject=This%20is%20a%20test&amp;body=That%20work%27s">Send email</a>

Mails

If you send mails from the backend, ensure to translate the subject and body properly:

If the mails consist of personal data, make sure to send these emails as html and properly exclude dynamic content:

Gtbabel automatically translates all mails sent in WordPress and has built in support for\ popular plugins like Contact Form 7 and WooCommerce to ensure the above guidelines.

Comments

If you offer a comment function on your website, just save the incoming comments in the input language (that can be determined via gtbabel_current_lng() or gtbabel_referer_lng()). Then output just those comments that match your current input language or even auto translate all of them using the lang-tag (see Multiple source languages).

Language codes

It is recommended to use iso language codes in lowercase.\ But you can use any language code you want (even i-klingon).\ For every language, you should provide language codes that are used for auto translation. If a language is not supported in your translation service, use null.\ Country/region codes (like "BR" in "pt_BR") should be used in the (unique) code-attribute with a dash: pt-br. Gtbabel by default does not distinct between English (British) and English (American), however you can simply add a new language or instruct Gtbabel to use a specific language code (e.g. for automatic translation).\ Hreflang codes must be in ISO 639-1, so some languages don't have an official hreflang code in the settings array.

Google Translation API

API usage costs

The translation apis of Google, Microsoft or DeepL can be costly. Try to keep track of your current usage stats. Gtbabel helps you by tracking the total amount of translated chars. You can also provide multiple api keys, Gtbabel then distributes the calls uniformly.

You can throttle the amount of chars with the option throttle_chars_per_month.

Custom translation providers

If you don't want to use the big three in translation, you can specify a special API URL in the auto_translation_service field instead. An example entry would look like this:

Gtbabel then fires a GET-request to that url and fills in the placeholders automatically.\ It can then accept and process common JSON request responses.

Development setup

Unit tests

Integration tests

Build pipeline

Caveats

Credits

Greetings to my coworker, without whom this project would not have been initiated.


All versions of core with dependencies

PHP Build Version
Package Version
Requires gettext/gettext Version *
vlucas/phpdotenv Version *
cocur/slugify Version *
vielhuber/stringhelper Version *
vielhuber/dbhelper Version *
vielhuber/excelhelper Version *
symfony/polyfill-mbstring Version 1.20.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package gtbabel/core contains the following files

Loading the files please wait ....