Stringer Zestaw przydatnych helperów językowych

Avris Stringer to otwarta biblioteka PHP upraszczająca wiele operacji na stringach związanych z tworzeniem interfejsu użytkownika, a przede wszystkim z dostosowywaniem form gramatycznych języka polskiego do dynamicznych danych.

Oprócz samej biblioteki udostępniony jest również Bundle Symfony2, rozszerzający Twiga o odpowiednie filtry.

Logo

Logo dzięki Proletkult Graphik

Instalacja

Standalone

W konsoli wykonaj polecenie:

php composer.phar require avris/stringer

Teraz możesz w swoim kodzie stworzyć instancję obiektu Avris\Stringer\Stringer i używać jej.

Uwaga: w dalszej części dokumentacji wszystkie funkcje są opisywane jako filtry Twiga, ale wcale nie trzeba ich tak używać. Przykładowo kod:

Zdobyłeś {{ points }} punkt{{ points|decline('','y','ów') }}

jest równoważny temu:

$stringer = new \Avris\Stringer\Stringer;
echo 'Zdobyłeś ' . $points . ' punkt' . $stringer->decline($points,'','y','ów');

Symfony

W konsoli wykonaj polecenie:

php composer.phar require avris/stringer-bundle

Zarejestruj bundle w pliku app/AppKernel.php

$bundles = array(
    // ...
    new Avris\StringerBundle\AvrisStringerBundle(),
);

Jeśli chcesz przyjrzeć się przykładowemu użyciu biblioteki, dodaj do pliku app/config/routing_dev.yml linijki:

avris_stringer:
    resource: "@AvrisStringerBundle/Resources/config/routing.yml"

Teraz przykładowe użycie jest dostępne w przeglądarce pod adresem /app_dev.php/avris/stringer/demo. Kod możesz obejrzeć w pliku vendor/avris/stringer-bundle/Resources/views/Default/demo.html.twig.

Micrus

W konsoli wykonaj polecenie:

php composer.phar require avris/stringer-micrus

Dostęp nie tylko przez Twiga

Wszystkie funkcje biblioteki są dostępne zarówno w widoku jako filtry Twiga, jak i w innych miejscach kodu – jako serwis.

$vocative = $this->get('avris.stringer')->vocative('Michał');

Odmiana ze względu na liczbę (decline)

"Zdobyłeś 1 punkt", ale "2 punkty" oraz "5 punktów". Dzięki Stringerowi nie musisz się martwić o odpowiednią odmianę. Wystarczy że napiszesz:

Zdobyłeś {{ points }} punkt{{ points|decline('','y','ów') }}

podając jako argumenty kolejno mianownik l.poj., mianownik l.mn. oraz dopełniacz l.mn. - i voilà! Filtr decline sam zajmie się dobraniem odpowiedniej końcówki/słowa.

Wołacze imion (vocative)

Miło, gdy czytelnika komunikatu czy mailingu powitają słowa "Drogi Andrzeju!" albo "Droga Renato!". Stringer umożliwia automatyczną odmianę imion do wołacza, niewymagającą odwołań do bazy i przetestowaną na tysiącu imion, polskich i nie tylko (lista).

{{ user.firstName|vocative }}

Zwroty zależne od płci (genderify)

Do mężczyzny powiemy "chciałbyś", do kobiety "chciałabyś". Podobnych przykładów jest wiele. Niestety, trudne i żmudne jest redagowanie osobnych tekstów dla kobiet i mężczyzn, a teksty unisex brzmią nienaturalnie. Znacznie lepiej i prościej jest wykorzystać filtr genderify:

{{ "Czy {_CHCIALBY}ś wziąć udział w..."|genderify(user.gender) }}

Powyższy kod dla user.gender='m' zwróci napis Czy chciałbyś wziąć udział, natomiast dla user.gender='k' - Czy chciałabyś wziąć udział. Oczywiście można użyć genderify dla całego bloku oraz zagnieździć w nim inne filtry. Przykładowo:

{% filter genderify(user.gender) %}
<p>
    Drog{_I_A} {{ user.firstName|vocative|capitalize }}!<br/>
    Chcielibyśmy Cię poinformować, że zdobył{_ES_AS} {{ user.points }} {{ user.points|decline('punkt','punkty','punktów') }}!<br/>
</p>
<p>
    Pozdrawiamy,<br/>
    xyz
</p>
{% endfilter %}

może zwrócić dla pewnego użytkownika na przykład taki tekst:

Drogi Tomku!

Chcielibyśmy Cię poinformować, że zdobyłeś 932 punkty!

Pozdrawiamy,

xyz

Lista dostępnych tagów:

Tag Mężczyzna Kobieta
{_A} a
{_I_A} i a
{_ES_AS}
{_Y_A} y a
{_AL_ELA} ął ęła
{_CHCIALBY} chciałby chciałaby
{_POWINIEN} powinien powinna
{_MOGL} mógł mogła
{_WSZEDL} wszedł weszła
{_PAN_PANI_M} Pan Pani
{_PAN_PANI_C} Panu Pani
{_PAN_PANI_D} Pana Pani
{_PAN_PANI_B} Pana Panią
{_PAN_PANI_N} Panem Panią
{_PAN_PANI_W} Panie Pani

Wyświetlanie liczb w polskiej notacji (polishNumber)

Filtr polishNumber otrzymuje zwykłego integera lub floata i zwraca odpowiedni string, w którym tysiące są oddzielone spacjami, a całość od części dziesiętnej – przecinkiem. Jest zatem lukrem składniowym dla funkcji number_format().

Przykładowo 123456 zostanie zmienione na 123 456, a 9298.3409 na 9 298,3409

Kwoty w złotówkach (pln)

Filtr pln również jest lukrem składniowym dla number_format() – zwraca liczbę w formacie z dwoma miejscami po przecinku i sufiksem .

Przykładowo {{ 123456.789|pln }} zostanie zmienione na 123 456,79 zł

Liczby słownie (numberInWords)

Co tu dużo tłumaczyć – filtr numberInWords pobiera liczbę i zwraca string z jej zapisem słownym. W mianowniku. Można zmienić rodzaj na żeński, podając jako pierwszy parametr 'k'.

375 → trzysta siedemdziesiąt pięć
-279 → minus dwieście siedemdziesiąt dziewięć
146 → sto czterdzieści sześć
10000000 → dziesięć milionów
5371.18 → pięć tysięcy trzysta siedemdziesiąt jeden i osiemnaście setnych
5678 → pięć i sześćset siedemdziesiąt osiem tysięcznych
0.1 → jedna dziesiąta
0.000908 → zero komma zero zero zero dziewięć zero osiem  

Godzina słownie (timeInWords)

Filtr pobiera godzinę (albo jako string, albo obiekt DateTime) i zwraca string z jej zapisem słownym. Dostępne są trzy tryby/formaty:

Tryb podaje się jako pierwszy parametr, np.: Jest {{ "20:23"|timeInWords(0) }}.

Tryb 0:
14:15:16 → Jest czternasta piętnaście. 
05:13:32 → Jest piąta trzynaście. 
19:49:20 → Jest dziewiętnasta czterdzieści dziewięć. 
11:53:11 → Jest jedenasta pięćdziesiąt trzy. 

Tryb 1:
14:15:16 → Jest czternasta piętnaście i szesnaście sekund. 
05:13:32 → Jest piąta trzynaście i trzydzieści dwie sekundy. 
19:49:20 → Jest dziewiętnasta czterdzieści dziewięć i dwadzieścia sekund. 
11:53:11 → Jest jedenasta pięćdziesiąt trzy i jedenaście sekund. 

Tryb 2:
14:15:16 → Jest kwadrans po czternastej. 
05:13:32 → Jest trzynaście po piątej. 
19:49:20 → Jest za jedenaście dwudziesta. 
11:53:11 → Jest za siedem południe. 

Formatowanie numeru telefonu (phone)

Filtr phone umożliwia proste sformatowanie stringa z numerem telefonu:

Czyszczenie adresu URL (clearUrl)

Adres URL przepuszczony przez filtr clearUrl zostanie obcięty ze zbędnych (zbędnych do wyświetlania userowi) elementów.

<a href="{{ post.source }}" target="_blank">{{ post.source|clearUrl }}</a> 

Powyższy kod dla adresu http://9gag.com/gag/aVOBPxn?ref=fsidebar zwróci link do poprawnego URL-a, ale wyświetlony jako 9gag.com/gag/aVOBPxn.

Ładne wyliczanie elementów tablicy (listify)

Ten filtr najlepiej pokazać na przykładzie działania:

// controller   
'commentators' => array('A','B','C','D','E','F'),

// view
{% set desc = ['osoba skomentowała','osoby skomentowały','osób skomentowało','inne','innych','skomentował','skomentowali'] %}
{% for i in range(1,8) %}
    {{ commentators|listify(i, desc) }}<br/>
{% endfor %}
{{ commentators|listify(0, desc) }}<br/>
{{ ['A']|listify(0, desc) }}<br/>
{{ ['A','B']|listify(0, desc) }}<br/>

Da następujący efekt:

6 osób skomentowało
A i 5 innych osób skomentowało
A, B i 4 inne osoby skomentowały
A, B, C i 3 inne osoby skomentowały
A, B, C, D i 2 inne osoby skomentowały
A, B, C, D, E i F skomentowali
A, B, C, D, E i F skomentowali
A, B, C, D, E i F skomentowali
A, B, C, D, E i F skomentowali
A skomentował
A i B skomentowali

Pierwszy parametr to maksymalna długość wyświetlonej listy (licząc wraz z elementem "i X innych"). Zero (domyślne) oznacza brak ograniczenia.

Drugi parametr to tablica stringów, które mają być doklejone w odpowiednich miejscach, domyślnie pusta.

Elementami tablicy mogą być zarówno stringi, jak i obiekty, o ile mają zdefiniowaną metodę __toString()

Słowny zapis różnicy dat (relativeDate)

Filtr relativeDate zwraca stringa z czytelnym dla człowieka, przybliżonym opisem różnicy między podaną datą a chwilą obecną, jak na przykład:

Jeśli podamy dodatkowy argument, będzie on uważany za punkt odniesienia zamiast domyślnego "teraz".

Obie daty mogą być podane zarówno w formie obiektu DateTime, jak i stringa.

Konwersja liczb arabskich na rzymskie (arabicToRoman)

Filtr arabicToRoman umożliwia konwersję liczb naturalnych z zakresu 1-3999 do liczb rzymskich.

Konwersja wielkości liter (convertCase i guessCase)

Filtr convertCase konwertuje napisy do różnych konwencji programistycznych:

Credits to Avro

Autor i licencja

WordStringer

Odmiana ze względu na liczbę (decline)

Mówimy "zdobyłeś 1 punkt", ale już "2 punkty" oraz "5 punktów". Dzięki Stringerowi nie musisz się martwić o odpowiednią odmianę. Wystarczy że napiszesz:

Zdobyłeś {{ points }} punkt{{ points|decline('','y','ów') }}

podając jako argumenty kolejno mianownik l.poj., mianownik l.mn. oraz dopełniacz l.mn. - i voilà! Filtr decline sam zajmie się dobraniem odpowiedniej końcówki/słowa.

Wołacze imion (vocative)

Miło, gdy czytelnika komunikatu czy mailingu powitają słowa "Drogi Andrzeju!" albo "Droga Renato!". Stringer umożliwia automatyczną odmianę imion do wołacza, niewymagającą odwołań do bazy i przetestowaną na tysiącu imion, polskich i nie tylko.

{{ user.firstName|vocative }}

Zwroty zależne od płci (genderify i guessGender)

Do mężczyzny powiemy "chciałbyś", do kobiety "chciałabyś". Podobnych przykładów jest wiele. Niestety, trudne i żmudne jest redagowanie osobnych tekstów dla kobiet i mężczyzn, a teksty unisex brzmią nienaturalnie. Znacznie lepiej i prościej jest wykorzystać filtr genderify:

{{ "Czy {_CHCIALBY}ś wziąć udział w..."|genderify(user.gender) }}

Powyższy kod dla user.gender='m' zwróci napis Czy chciałbyś wziąć udział, natomiast dla user.gender='k'Czy chciałabyś wziąć udział. Oczywiście można użyć genderify dla całego bloku oraz zagnieździć w nim inne filtry. Przykładowo:

{% filter genderify(user.gender) %}
<p>
    Drog{_I_A} {{ user.firstName|vocative|capitalize }}!<br/>
    Chcielibyśmy Cię poinformować, że zdobył{_ES_AS} {{ user.points }}
    {{ user.points|decline('punkt','punkty','punktów') }}!<br/>
</p>
<p>
    Pozdrawiamy,<br/>
    xyz
</p>
{% endfilter %}

może zwrócić dla pewnego użytkownika na przykład taki tekst:

Drogi Tomku!

Chcielibyśmy Cię poinformować, że zdobyłeś 932 punkty!

Pozdrawiamy,

xyz

Lista dostępnych tagów:

Tag Mężczyzna Kobieta
{_A} a
{_I_A} i a
{_ES_AS}
{_Y_A} y a
{_AL_ELA} ął ęła
{_CHCIALBY} chciałby chciałaby
{_POWINIEN} powinien powinna
{_MOGL} mógł mogła
{_WSZEDL} wszedł weszła
{_PAN_PANI_M} Pan Pani
{_PAN_PANI_C} Panu Pani
{_PAN_PANI_D} Pana Pani
{_PAN_PANI_B} Pana Panią
{_PAN_PANI_N} Panem Panią
{_PAN_PANI_W} Panie Pani

NumberStringer

Wyświetlanie liczb w polskiej notacji (polishNumber)

Filtr polishNumber otrzymuje zwykłego integera lub floata i zwraca odpowiedni string, w którym tysiące są oddzielone spacjami, a całość od części dziesiętnej – przecinkiem. Jest zatem lukrem składniowym dla funkcji number_format().

Przykładowo 123456 zostanie zmienione na 123 456, a 9298.3409 na 9 298,3409

Kwoty w złotówkach (pln)

Filtr pln również jest lukrem składniowym dla number_format() – zwraca liczbę w formacie z dwoma miejscami po przecinku i sufiksem .

Przykładowo {{ 123456.789|pln }} zostanie zmienione na 123 456,79 zł

Liczby słownie (numberInWords)

Co tu dużo tłumaczyć –- filtr numberInWords pobiera liczbę i zwraca string z jej zapisem słownym. W mianowniku. Można zmienić rodzaj na żeński, podając jako pierwszy parametr 'k'.

375 → trzysta siedemdziesiąt pięć
-279 → minus dwieście siedemdziesiąt dziewięć
146 → sto czterdzieści sześć
10000000 → dziesięć milionów
5371.18 → pięć tysięcy trzysta siedemdziesiąt jeden i osiemnaście setnych
5678 → pięć i sześćset siedemdziesiąt osiem tysięcznych
0.1 → jedna dziesiąta
0.000908 → zero komma zero zero zero dziewięć zero osiem

Formatowanie numeru telefonu (phone)

Filtr phone umożliwia proste sformatowanie stringa z numerem telefonu:

TimeStringer

Godzina słownie (timeInWords)

Filtr pobiera godzinę (albo jako string, albo obiekt DateTime) i zwraca string z jej zapisem słownym. Dostępne są trzy tryby/formaty:

Tryb podaje się jako pierwszy parametr, np.: Jest {{ "20:23"|timeInWords(0) }}.

Tryb 0:
14:15:16 → Jest czternasta piętnaście.
05:13:32 → Jest piąta trzynaście.
19:49:20 → Jest dziewiętnasta czterdzieści dziewięć.
11:53:11 → Jest jedenasta pięćdziesiąt trzy.

Tryb 1:
14:15:16 → Jest czternasta piętnaście i szesnaście sekund.
05:13:32 → Jest piąta trzynaście i trzydzieści dwie sekundy.
19:49:20 → Jest dziewiętnasta czterdzieści dziewięć i dwadzieścia sekund.
11:53:11 → Jest jedenasta pięćdziesiąt trzy i jedenaście sekund.

Tryb 2:
14:15:16 → Jest kwadrans po czternastej.
05:13:32 → Jest trzynaście po piątej.
19:49:20 → Jest za jedenaście dwudziesta.
11:53:11 → Jest za siedem południe.

Słowny zapis różnicy dat (relativeDate)

Filtr relativeDate zwraca stringa z czytelnym dla człowieka, przybliżonym opisem różnicy między podaną datą a chwilą obecną, jak na przykład:

Jeśli podamy dodatkowy argument, będzie on uważany za punkt odniesienia zamiast domyślnego "teraz".

Obie daty mogą być podane zarówno w formie obiektu DateTime, jak i stringa.

UrlStringer

Czyszczenie adresu URL (clearUrl)

Adres URL przepuszczony przez filtr clearUrl zostanie obcięty ze zbędnych (zbędnych do wyświetlania userowi) elementów.

<a href="{{ post.source }}" target="_blank">{{ post.source|clearUrl }}</a>

Powyższy kod dla adresu http://9gag.com/gag/aVOBPxn?ref=fsidebar zwróci link do poprawnego URL-a, ale wyświetlony jako 9gag.com/gag/aVOBPxn.

ListStringer

Ładne wyliczanie elementów tablicy (listify)

Ten filtr najlepiej pokazać na przykładzie działania:

// controller
'commentators' => array('A','B','C','D','E','F'),

// view
{% set desc = [
    'osoba skomentowała',
    'osoby skomentowały',
    'osób skomentowało',
    'inne',
    'innych',
    'skomentował',
    'skomentowali'
] %}
{% for i in range(1,8) %}
    {{ commentators|listify(i, desc) }}<br/>
{% endfor %}
{{ commentators|listify(0, desc) }}<br/>
{{ ['A']|listify(0, desc) }}<br/>
{{ ['A','B']|listify(0, desc) }}<br/>

Da następujący efekt:

6 osób skomentowało
A i 5 innych osób skomentowało
A, B i 4 inne osoby skomentowały
A, B, C i 3 inne osoby skomentowały
A, B, C, D i 2 inne osoby skomentowały
A, B, C, D, E i F skomentowali
A, B, C, D, E i F skomentowali
A, B, C, D, E i F skomentowali
A, B, C, D, E i F skomentowali
A skomentował
A i B skomentowali

Pierwszy parametr to maksymalna długość wyświetlonej listy (licząc wraz z elementem "i X innych"). Zero (domyślne) oznacza brak ograniczenia.

Drugi parametr to tablica stringów, które mają być doklejone w odpowiednich miejscach, domyślnie pusta.

Elementami tablicy mogą być zarówno stringi, jak i obiekty, o ile mają zdefiniowaną metodę __toString()

RomanStringer

Konwersja liczb arabskich na rzymskie (arabicToRoman)

Filtr arabicToRoman umożliwia konwersję liczb naturalnych z zakresu 1-3999 do liczb rzymskich.

CaseStringer

Konwersja wielkości liter (convertCase i guessCase)

Filtr convertCase konwertuje napisy do różnych konwencji programistycznych:

Credits to Avro