Blog

Pola metadanych PDF, wyjaśnione: title, language, author, subject, creator, producer

Przejście pole po polu przez sześć standardowych pól metadanych PDF udostępnianych przez gPdf — title, language, author, subject, creator, producer. Do czego służą, kto je czyta, częste błędy i jak zweryfikować to, co poszło.

Towarzysz wpisu Właściwości PDF powinny pokazywać Twoją markę, a nie cudze narzędzie — tamten wpis budował argumentację za tym, dlaczego w ogóle przejmować się metadanymi PDF. Ten jest podręcznikiem operacyjnym: do czego służy każde pole w specyfikacji PDF, kto je czyta, częste błędy i jak zweryfikować, że Twoje wyjście rzeczywiście dostarczyło to, co zamierzałeś.

gPdf udostępnia sześć standardowych pól, które specyfikacja PDF definiuje dla metadanych na poziomie dokumentu. Żyją one pod settings.metadata w JSON-ie DocumentRequest. Każde pole jest opcjonalne — jeśli go nie ustawisz, gPdf wraca albo do default_metadata tokenu (funkcja polityki Enterprise), albo do domyślnej wartości systemowej.

{
  "settings": {
    "metadata": {
      "title":    "...",
      "language": "...",
      "author":   "...",
      "subject":  "...",
      "creator":  "...",
      "producer": "..."
    }
  }
}

Reszta tego wpisu to jedna sekcja na pole. Każda sekcja podąża za tym samym schematem: czym jest pole, gdzie się pojawia, częste błędy, zasada kciuka. Kolejność to: co wypełnić w pierwszej → drugiej → … → ostatniej kolejności.

title — czym jest dokument

Specyfikacja PDF opisuje to jako „tytuł dokumentu“.

Gdzie się pojawia:

  • Pasek tytułu w przeglądarkach PDF (Adobe Reader, Preview, Foxit, przeglądarka PDF Chromium — wszystkie pokazują).
  • Karta przeglądarki, gdy PDF otwiera się inline (Content-Disposition: inline).
  • Indeksy wyszukiwania — Spotlight, Outlook, SharePoint, indekser full-text Google Drive wszystkie czytają title i nadają mu sporą wagę.

Częste błędy:

  • Ustawianie title równe nazwie pliku. invoice-20260318.pdf to nazwa pliku. Title powinno być czymś, co czyta człowiek, np. Invoice INV-2026-3401. Nazwa pliku i title to różne sprawy; nazwa pliku jest dla systemu plików, title dla przeglądarek i wyszukiwania.
  • Pozostawianie title pustego. Przeglądarki wracają do nazwy pliku. Wynik czyta się jak autogenerowany i wypluty przez maszynę.
  • Wpisywanie marki w title. Acme Logistics — Invoice INV-2026-3401 zaśmieca pasek tytułu. Marka należy do author, nie do title.

Zasada kciuka: title powinno odpowiadać H1 wyrenderowanej strony. Jeśli górny wiersz Twojego szablonu faktury to „Invoice INV-2026-3401“, to jest tytuł.

language — dla dostępności, wyszukiwania i zgodności

language to etykieta językowa BCP-47: en, de, zh-Hans, pt-BR, ar-SA. Ustaw ją dla każdego dokumentu. Spośród sześciu pól ma najbardziej konkretne konsekwencje w dalszych systemach przy najmniejszym koszcie implementacji — dlatego stoi na pozycji 2, a nie jest zakopane niżej.

Gdzie się pojawia:

  • Czytniki ekranu — JAWS, NVDA, VoiceOver używają go, by wybrać właściwy zestaw fonemów. Angielski czytnik ekranu czytający PDF z language: "de" wymówi niemieckie słowa poprawnie; bez etykiety prozodia wychodzi źle.
  • Wyszukiwarki i indekserzy — wpływa na to, które reguły stemmingu i lista stopwords danego locale są stosowane. Faktura z language: "zh-Hans" jest indeksowana z chińską segmentacją; brak etykiety często wraca do angielskiego, a indeks staje się bezużyteczny.
  • Zgodność z PDF/A — PDF/A-2a i PDF/A-3a (profile dostępności) wymagają etykiety językowej. Bez niej walidacja veraPDF nie przechodzi.

Częste błędy:

  • Pozostawianie nieustawionym. Domyślnie używaj „locale odbiorcy“, a nie „domyślnego locale platformy“. Większość nieszczelnych stosów po prostu nie zapisuje tego pola; wynikiem są czytniki ekranu, które źle wymawiają, i indeksy wyszukiwania, które stosują niewłaściwe reguły odmiany.
  • Używanie łańcucha spoza BCP-47 jak "english" czy "EN-US". Specyfikacja PDF oczekuje tagów RFC 5646: en, en-US, de, pt-BR.
  • Twarde zakodowanie domyślnego locale platformy (np. zawsze "en") niezależnie od rzeczywistego języka treści dokumentu. Faktura po portugalsku oznaczona jako "en" jest gorsza niż dokument bez etykiety — aktywnie wprowadza indeksera w błąd.

Zasada kciuka: etykieta powinna odpowiadać rzeczywistemu językowi treści. Dla klienta w Brazylii otrzymującego fakturę po portugalsku ustaw "language": "pt-BR", nie "en". Dla dokumentów wielojęzycznych wybierz dominujący język, a dla reszty użyj atrybutu Lang na pojedynczych elementach treści — to funkcja dostępności tagged-PDF, wykraczająca poza pole language na poziomie dokumentu.

author — do kogo należy dokument

W specyfikacji PDF author to „nazwa osoby lub organizacji, która stworzyła dokument“. Dla biznesowych PDF-ów wysyłanych do odbiorców odpowiedź to niemal zawsze organizacja — ale właściwa forma naprawdę zależy od kontekstu.

Gdzie się pojawia:

  • Okno właściwości w każdej przeglądarce PDF, widocznie oznaczone jako „Author“.
  • Indekserzy DMS / archiwów, często używany jako filtr.
  • Strumień metadanych XMP w PDF/A, gdzie przenoszony jest do długoterminowych archiwów.

Częste błędy:

  • "author": "[email protected]" — przypadkowo wypuszcza e-mail operatora w każdym PDF-ie, ląduje w każdym indeksie wyszukiwania, staje się długoterminowym problemem PII.
  • "author": "PDF Generator Service" — wewnętrzna nazwa narzędzia; nic nie znaczy dla odbiorcy.
  • ❌ Puste — Preview i większość przeglądarek dosłownie pokazują „(no author)“ w oknie właściwości, co czyta się jako „nikt nie jest właścicielem tego“.

Formy, które działają:

  • "author": "Acme Logistics, Inc." — zwykła organizacja.
  • "author": "Acme Logistics — Billing" — organizacja + dział, dla dokumentów trafiających do konkretnego biurka.
  • "author": "Bridge Capital Partners — Fund III" — przydatne w finansach/prawie, gdzie atrybucja dotyczy konkretnego podmiotu.
  • "author": "Maria López, RICS Surveyor" — dla jednoautorskich publikacji (raporty, wyceny, opinie prawne), gdzie osoba JEST atrybucją redakcyjną.

Zasada kciuka: author to podmiot, z którym odbiorca powinien skojarzyć dokument. W multi-tenant SaaS, w którym platforma generuje PDF-y w imieniu klientów, author powinien być nazwą organizacji klienta, a nie nazwą platformy. (Nazwa platformy należy do creator — patrz niżej.) Dla kontekstów konsultingowych / wydawniczych / prawnych, w których to osoby są marką, osoby są w porządku.

subject — jaki to typ dokumentu

subject to krótki-opis-dokumentu. Przeglądarki nie eksponują go widocznie — większość użytkowników nigdy go nie zobaczy, chyba że otworzy okno właściwości. Ale systemy zarządzania dokumentami, systemy archiwizacji i regułowy routing maila/plików używają go.

Gdzie się pojawia:

  • Okno właściwości, drugorzędna pozycja.
  • Reguły routingu DMS, logika bucketowania w archiwum.
  • Strumień metadanych XMP (PDF/A).

Częste błędy:

  • "subject": "Invoice for Acme on 2026-03-18 for $4,532.10" — to opis instancji dokumentu, nie typu. Należy do title.
  • ❌ Puste — tracisz darmowy punkt zaczepienia dla routingu w dalszych systemach.
  • ❌ Mieszanie klas niespójnie ("Invoice" vs "Invoice/2026-03" vs "Monthly invoice") — filtry DMS nie potrafią bucketować po ruchomym celu.

Formy, które działają:

  • "subject": "Invoice"
  • "subject": "Monthly account statement"
  • "subject": "Shipping label — 4×6 thermal"
  • "subject": "Q3 2026 board pack"

Zasada kciuka: właściwa granulacja to klasa dokumentu, nie instancja. DMS z tysiącami przychodzących PDF-ów może routować po subject, jeśli dasz mu spójne słownictwo. Wybierz skończony zbiór klas dla swojej platformy i nigdy nie odbiegaj — każda faktura, którą Twoja platforma generuje, powinna mieć dokładnie "subject": "Invoice".

creator vs producer — najczęściej mylona para

To tu większość zespołów przestaje czytać specyfikację PDF i zaczyna zgadywać. Specyfikacja jest precyzyjna; te dwa pola znaczą różne rzeczy.

  • creator — aplikacja, która wytworzyła treść źródłową (system upstream, który zdecydował, co dokument ma mówić).
  • producer — aplikacja, która wytworzyła bajty PDF (silnik renderujący, który zamienił tę treść w plik PDF).

Dla biznesowej platformy SaaS generującej faktury przez API JSON-to-PDF jak gPdf:

  • creator = biznesowa platforma SaaS z wersją. To aplikacja, która zdecydowała, że to ma być faktura dla Acme na 4532,10 $.
  • producer = silnik, który wytworzył PDF. Domyślnie to „gPdf“. Ale ponieważ warstwa renderowania to infrastruktura, którą wybrał SaaS, SaaS może zasadnie ustawić producer na nazwę własnej platformy — jego platforma w realnym sensie wyprodukowała bajty PDF, delegując do gPdf jako do infrastruktury.
{
  "creator":  "Acme Billing Platform v7.2",
  "producer": "Acme Billing Platform"
}

Gdzie się pojawiają:

  • Okno właściwości, oba oznaczone.
  • Wyjście pdfinfo, obok siebie.
  • Strumień XMP w PDF/A (w PDF/A oba pola muszą być niepuste).

Częste błędy:

  • creator ustawiony na łańcuch user-agent Chromium / Mozilla. Zdarza się, gdy stos PDF oparty na headless browserze automatycznie przekazuje User-Agent do creator. To wersja przeglądarki, a nie system będący źródłem odniesienia. Nadpisz.
  • producer pozostawiony jako nazwa domyślnego generatora. Większość zespołów nigdy go nie nadpisuje, więc każdy PDF mówi „Skia/PDF m120“ lub „wkhtmltopdf“ — zobacz wpis o PDF pod własną marką, dlaczego to ma znaczenie w B2B.
  • Wstawianie tej samej wartości w oba. Akceptowalne, ale marnotrawstwo — te dwa pola istnieją właśnie po to, by przeglądarka mogła odróżnić „aplikację źródłową“ od „silnika renderowania“. Używaj ich.

Zasada kciuka: creator to nazwa Twojej aplikacji z wersją (np. "Acme Billing Platform v7.2"); producer to marka lub nazwa platformy Twojej aplikacji bez wersji (np. "Acme Billing Platform"). Oba powinny być wartościami, które odbiorca by rozpoznał.

Puste pola, wartości domyślne tokenu, niespodzianki w dalszym potoku

Trzy szczegóły implementacyjne warte poznania zanim wypuścisz:

  1. Puste lub złożone wyłącznie z białych znaków łańcuchy są traktowane jako nieprzekazane. Wysłanie "title": "" to to samo, co pominięcie title — nie zapisuje pustego łańcucha w PDF-ie, tylko przechodzi łańcuch wartości zastępczych (wartość domyślna tokenu → wartość domyślna systemu). To przyczyna najczęstszego zgłoszenia bugu „ustawiłem, nie zadziałało“.
  2. Polityki tokenu mogą usuwać lub domyślnie wypełniać pola metadanych. Multi-tenant SaaS używający gPdf może ustawić default_metadata na każdym tokenie API, tak by każdy PDF generowany przez ten token niósł author i producer klienta, bez ufania, że każdy deweloper ustawi je w każdym żądaniu. Wartość domyślna na poziomie tokenu to właściwa warstwa egzekwowania dla „każdy PDF Acme musi mówić Acme“.
  3. Dalsze potoki przetwarzania mogą przepisać Twoje metadane. Narzędzia obrabiające PDF-y po zwróceniu ich przez gPdf — Ghostscript bez jawnych flag zachowania metadanych, niektóre korporacyjne narzędzia DRM, niektóre „optymalizatory PDF“ — mogą nadpisać Producer własną nazwą i cofnąć branding, który właśnie ustawiłeś. Weryfikuj względem rzeczywistego potoku produkcyjnego, a nie tylko surowej odpowiedzi gPdf.

Zweryfikuj swoje metadane

Po wdrożeniu powyższych zmian trzy szybkie sposoby sprawdzenia, że PDF naprawdę dostarczył to, co zamierzałeś:

Linia komend (macOS / Linux, wymaga poppler-utils):

$ pdfinfo your-output.pdf | head -10
Title:           Invoice INV-2026-3401
Subject:         Monthly invoice 2026-03
Author:          Acme Logistics, Inc.
Creator:         Acme Billing Platform v7.2
Producer:        Acme Billing Platform
Language:        en

Acrobat / Adobe Reader: Plik → Właściwości → zakładka Opis. Pojawiają się wszystkie sześć pól, z Title pokazanym na pasku tytułu przeglądarki na górze.

Preview na macOS: ⌘+I (Informacje). Panel inspektora „PDF“ pokazuje te same pola.

Jeśli któreś pole pojawia się puste, blankowe lub z nazwą narzędzia, której nie ustawiłeś, prześledź ponownie ciało żądania — najczęstszą przyczyną jest wysłanie "" (pustego łańcucha), które API traktuje jako „nieprzekazane“ i przechodzi łańcuch wartości zastępczych aż do wartości domyślnej. Drugą najczęstszą przyczyną jest dalszy potok przetwarzania (Ghostscript, DRM, optymalizator) nadpisujący pole po zwróceniu przez gPdf; testuj na produkcji, a nie tylko na surowej odpowiedzi renderu.

Metadane w archiwizacji PDF/A

Jeśli renderujesz do długoterminowej archiwizacji z settings.profile: "pdfa-2b" (lub -2a, -3a, -3b), metadane przestają być opcjonalne i stają się nośne:

  • Pole producer nie może być puste w pliku zgodnym z PDF/A — co najmniej zostaje wysłany default systemowy.
  • language jest wymagane dla profili dostępności (PDF/A-2a, PDF/A-3a). Bez niego walidacja veraPDF zwyczajnie nie przechodzi.
  • Strumień metadanych XMP, którego wymaga PDF/A, jest generowany automatycznie z sześciu powyższych pól; nie musisz konstruować go samodzielnie.
  • title, author, subject, creator, producer i language — wszystkie trafiają do strumienia XMP, dzięki czemu indekser metadanych w dalszym archiwum (Preservica, Archivematica) może zbudować swój katalog na ich podstawie bez ponownego parsowania ciała dokumentu.

Dla dokumentu archiwalnego oznakowane metadane to nie tylko polor marki — to część trwałości artefaktu. Niemiecki urząd celny, brazylijska administracja skarbowa lub jakiekolwiek długoterminowe archiwum, które otworzy Twój PDF za dziesięć lat, zobaczy to, co było w tych polach w dniu, w którym go wyrenderowałeś. Świadome ustawienie ich w czasie renderu to jedyna szansa, jaką masz.

Czego gPdf nie udostępnia (jeszcze)

Żeby być szczerym co do dzisiejszej powierzchni: specyfikacja PDF definiuje także Keywords (swobodne hasła wyszukiwawcze) oraz strumień metadanych XMP wspierający dowolne pary klucz-wartość. gPdf nie udostępnia żadnego z nich w obecnym API.

Jeśli musisz ukryć dowolne dane biznesowe wewnątrz PDF-a (UUID zamówienia, kod magazynu, wersję szablonu), dzisiejsze obejścia to:

  • Ustawić subject na ustrukturyzowany krótki łańcuch, który dalsze systemy potrafią sparsować.
  • Trzymać dane biznesowe we własnej bazie, indeksowane po nazwie pliku lub hashu treści.
  • Czekać — niestandardowe pola XMP są na roadmapie i kiedy zostaną udostępnione, będą właściwą odpowiedzią dla ukrytego, czytanego maszynowo kontekstu procesu.

Mylenie „oznakowanych metadanych“ (sześć standardowych pól, dostępnych już teraz) z „niestandardowymi metadanymi biznesowymi“ (niestandardowe pola XMP, w przyszłości) to najłatwiejszy sposób, by przeobiecać to, co dziś możliwe. Warto trzymać te dwie rzeczy oddzielnie we własnym planowaniu.

Pełny przykład

Biznesowa platforma SaaS (Acme Billing Platform) generująca fakturę dla niemieckiego klienta (Müller Versand GmbH), gotowa do archiwizacji jako PDF/A:

{
  "settings": {
    "profile": "pdfa-3b",
    "metadata": {
      "title":    "Rechnung RE-2026-0412",
      "language": "de",
      "author":   "Müller Versand GmbH",
      "subject":  "Monatsrechnung — März 2026",
      "creator":  "Acme Billing Platform v7.2",
      "producer": "Acme Billing Platform"
    }
  }
}

pdfinfo na powstałym PDF-ie:

$ pdfinfo invoice-2026-0412.pdf | head -10
Title:           Rechnung RE-2026-0412
Subject:         Monatsrechnung — März 2026
Author:          Müller Versand GmbH
Creator:         Acme Billing Platform v7.2
Producer:        Acme Billing Platform
Language:        de

Title po niemiecku, author jako Müller Versand (podmiot GmbH klienta, odbiorca dokumentu), creator jako Acme Billing Platform (system redakcyjny, który zdecydował, co umieścić na stronie), producer jako marka Acme Billing Platform, język oznaczony poprawnie dla niemieckiego czytnika ekranu i dla niemieckiego indeksera full-text, który później podchwyci to w DMS-ie Müllera. Profil PDF/A-3b oznacza, że ten zestaw metadanych jest również serializowany do strumienia XMP do długoterminowej archiwizacji.

Nic we właściwościach pliku nie nazywa gPdf, Chromium ani żadnego narzędzia, którego klient nie wybrał. O to właśnie chodzi.

Najmniejsza możliwa poprawa

Jeśli już wysyłasz POST na /api/v1/pdf/render, a Twoje obecne wywołanie nie ma settings.metadata, najmniejszą poprawą są trzy linie dodane do JSON-a, który już wysyłasz:

 {
   "pages": [...],
   "settings": {
+    "metadata": {
+      "author":   "Your customer's organisation",
+      "producer": "Your platform"
+    }
   }
 }

Dwa pola, jeden nowy klucz. Weryfikowalne pdfinfo w sekundy. Gdy to wjedzie, uzupełnij title, language, subject i creator w wolnej chwili.

Gdzie to ląduje