{"id":32990,"date":"2026-01-30T10:40:18","date_gmt":"2026-01-30T09:40:18","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=32990"},"modified":"2026-01-30T10:40:22","modified_gmt":"2026-01-30T09:40:22","slug":"aem-sites-konfiguracja-z-uzyciem-sling-context%e2%80%91aware-configuration","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/aem-sites-konfiguracja-z-uzyciem-sling-context%e2%80%91aware-configuration\/","title":{"rendered":"AEM Sites \u2013 konfiguracja z u\u017cyciem Sling Context\u2011Aware Configuration"},"content":{"rendered":"\n<p>Przy tworzeniu jakiegokolwiek bardziej z\u0142o\u017conego projektu w AEM pr\u0119dzej czy p\u00f3\u017aniej pojawia si\u0119 temat przechowywania i dost\u0119pu do r\u00f3\u017cnych danych konfiguracyjnych. Mog\u0105 to by\u0107 zar\u00f3wno informacje platformowe, klucze API, konfiguracje komponent\u00f3w, jak i inne parametry.<\/p>\n\n\n\n<p>W projektach dane te zazwyczaj przechowuje si\u0119 z u\u017cyciem jednego lub kilku spo\u015br\u00f3d poni\u017cszych mechanizm\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Run Mode,<\/li>\n\n\n\n<li>konfiguracje OSGi,<\/li>\n\n\n\n<li>w\u0142a\u015bciwo\u015bci stron (Page Properties),<\/li>\n\n\n\n<li>niestandardowe strony konfiguracji,<\/li>\n\n\n\n<li>Sling Context\u2011Aware Configuration.<\/li>\n<\/ul>\n\n\n\n<p>Nale\u017cy pami\u0119ta\u0107, \u017ce ka\u017cdy z nich zosta\u0142 stworzony do konkretnego celu i zgodnie z dobrymi praktykami nie powinien by\u0107 u\u017cywany w spos\u00f3b niezgodny z przeznaczeniem.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Run Modes \u2013 <\/strong>powinny by\u0107 wykorzystywane do danych zwi\u0105zanych ze \u015brodowiskiem, np. konfiguracje autora lub publish.<\/li>\n\n\n\n<li><strong>Konfiguracje OSGi \u2013 <\/strong>najlepiej stosowa\u0107 je do nieedytowalnych przez autor\u00f3w systemowych konfiguracji, takich jak: schedulery, serwisy, cache, integracje.<\/li>\n\n\n\n<li><strong>Page Properties \u2013 <\/strong>dobrze nadaj\u0105 si\u0119 do konfiguracji zachowania pojedynczej strony, ale s\u0142abo si\u0119 skaluj\u0105 i s\u0105 trudne w zarz\u0105dzaniu przy du\u017cych projektach. Nie powinno si\u0119 tam przechowywa\u0107 informacji technicznych.<\/li>\n\n\n\n<li><strong>Niestandardowe strony konfiguracji \u2013 <\/strong>zwykle s\u0105 elastyczne, ale wymagaj\u0105 dodatkowego rozwoju i dalszego utrzymania.<\/li>\n\n\n\n<li><strong>Sling Context\u2011Aware Configuration \u2013 <\/strong>w t\u0119 opcj\u0119 zag\u0142\u0119bimy si\u0119 dok\u0142adniej w dalszej cz\u0119\u015bci artyku\u0142u.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Sling Context\u2011Aware Configuration<\/strong><\/h2>\n\n\n\n<p>Zgodnie z dokumentacj\u0105, Context\u2011Aware Configurations (CAC) to konfiguracje powi\u0105zane z konkretnym zasobem lub drzewem zasob\u00f3w, np.: stron\u0105, stron\u0105 g\u0142\u00f3wn\u0105 witryny czy tenantem. Obs\u0142uguj\u0105 one:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>dziedziczenie \u2013 nie trzeba ustawia\u0107 warto\u015bci na ka\u017cdej stronie poddrzewa,<\/li>\n\n\n\n<li>fallback \u2013 warto\u015bci s\u0105 wyszukiwane a\u017c do korzenia konfiguracji.<\/li>\n<\/ul>\n\n\n\n<p>Domy\u015blna implementacja przechowuje dane pod \u015bcie\u017ck\u0105\/conf, zapewniaj\u0105c dodatkowe fallbacki. Konfiguracja jest powi\u0105zana z poddrzewem tre\u015bci poprzez w\u0142a\u015bciwo\u015b\u0107 sling:configRef, wskazuj\u0105c\u0105 na odpowiedni w\u0119ze\u0142 konfiguracji. Wszystkie zasoby pod tym poddrzewem pr\u00f3buj\u0105 znale\u017a\u0107 odpowiednie konfiguracje, przechodz\u0105c w g\u00f3r\u0119 hierarchii, je\u015bli to konieczne.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n\/content\n   \/tenant1\n      @sling:configRef=&quot;\/conf\/tenant1&quot;\n      \/region1\n         @sling:configRef=&quot;\/conf\/tenant1\/region1&quot;\n\t     \/site1\n         @sling:configRef=&quot;\/conf\/tenant1\/region1\/site1&quot;\n         \n\/conf\n   \/tenant1\n      \/sling:configs\n         \/x.y.z.MyConfig\n            @prop1 = &#039;tenant1&quot;\n      \/region1\n         \/sling:configs\n            \/x.y.z.MyConfig\n               @prop1 = &#039;region1&quot;\n\t     \/site1\n            \/sling:configs\n               \/x.y.z.MyConfig\n                 @prop1 = &#039;site1&#039;\n<\/pre><\/div>\n\n\n<p>Dane konfiguracyjne s\u0105 przechowywane pod w\u0119z\u0142em sling:configs, a same w\u0119z\u0142y konfiguracji s\u0105 nazwane zgodnie z nazwami klas, np. <code>x.y.z.MyConfig<\/code>, i zawieraj\u0105 pola, np. prop1.<\/p>\n\n\n\n<p>Jak zobaczymy w dalszej cz\u0119\u015bci, mechanizm ten jest bardzo elastyczny.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Interfejsy konfiguracji<\/strong><\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n@Configuration(label=&quot;Configuration&quot;, description=&quot;Sample configuration&quot;)\npublic @interface MyConfig {\n\n    @Property(label=&quot;Parameter #1&quot;, description=&quot;Describe me&quot;)\n    String param1();\n}\n<\/pre><\/div>\n\n\n<p>S\u0105 to zwyk\u0142e interfejsy z adnotacjami @Configuration i @Property. Mo\u017cliwe jest r\u00f3wnie\u017c tworzenie konfiguracji zagnie\u017cd\u017conych oraz tablic:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n@Configuration(label=&quot;Configuration List&quot;, description=&quot;Sample list configuration&quot;)\npublic @interface MyConfigList {\n\n    @Property(label=&quot;Key Value Pairs&quot;, description=&quot;List of key value pairs&quot;)\n    KeyValue&#x5B;] keyValues();\n\t\n\t@interface KeyValue {\n\t\t@Property\n\t\tString key();\n\t\t\n\t\t@Property\n\t\tString valye\n\t}\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>Odczyt konfiguracji<\/strong><\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nResource contentResource = resourceResolver.getResource(&quot;\/content\/tenant1\/region1\/site1\/page1&quot;);\nMyConfig config = contentResource.adaptTo(ConfigurationBuilder.class).as(MyConfig.class);\n<\/pre><\/div>\n\n\n<p>Jak wida\u0107, jest to bardzo wygodne rozwi\u0105zanie, poniewa\u017c ca\u0142a logika zwi\u0105zana z dostarczaniem w\u0142a\u015bciwego kontekstu, wyszukiwaniem warto\u015bci p\u00f3l, dziedziczeniem oraz mechanizmem fallback jest obs\u0142ugiwana przez bibliotek\u0119 Context-Aware Configuration, bez konieczno\u015bci pisania jakiegokolwiek w\u0142asnego kodu. Warto r\u00f3wnie\u017c wspomnie\u0107, \u017ce Sling CAC jest cz\u0119\u015bci\u0105 standardowej instalacji OOTB AEM.<\/p>\n\n\n\n<p><strong>Co jednak, kiedy mamy specjalne wymagania, a mimo to chcieliby\u015bmy nadal korzysta\u0107 z CAC?<\/strong> Na szcz\u0119\u015bcie, biblioteka pozwala dostosowa\u0107 j\u0105 do naszych potrzeb.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dostosowanie i adaptacja do potrzeb projektu<\/strong><\/h2>\n\n\n\n<p>Potencjaln\u0105 wad\u0105 przechowywania danych konfiguracyjnych w CAC jest brak przyjaznego, out-of-the-box interfejsu u\u017cytkownika do edycji konfiguracji. Obecnie konfiguracj\u0119 mo\u017cna zmienia\u0107 jedynie poprzez dostarczanie jej wraz z paczk\u0105 kodu albo bezpo\u015brednio w narz\u0119dziu CRXDE.<\/p>\n\n\n\n<p><strong>Ale co w przypadku, kiedy chcemy, aby autorzy mogli edytowa\u0107 przynajmniej cz\u0119\u015b\u0107 konfiguracji i j\u0105 publikowa\u0107?<\/strong> Na szcz\u0119\u015bcie da si\u0119 to zrealizowa\u0107 przy u\u017cyciu niewielkiej ilo\u015bci w\u0142asnego kodu do edycji i zapisu danych \u2013 co wa\u017cne, nadal korzystaj\u0105c ze wszystkich zalet CAC przy ich odczycie.<\/p>\n\n\n\n<p>Przyjrzyjmy si\u0119 scenariuszowi, w kt\u00f3rym chcieliby\u015bmy po\u0142\u0105czy\u0107 przechowywanie danych na zwyk\u0142ych stronach, jako zwyk\u0142e komponenty, a jednocze\u015bnie odczytywa\u0107 te warto\u015bci w ustandaryzowany spos\u00f3b.<\/p>\n\n\n\n<p>Za\u0142\u00f3\u017cmy struktur\u0119:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n\/content\n   \/tenant1\n      \/region1\n\t     \/site1\n\t        \/configuration \u2013 configuration page\n\t           \/jcr:content\n\t              \/myconfig \u2013 configuration component\n\t                 @prop1 = \u201cvalue\u201d\n<\/pre><\/div>\n\n\n<p>gdzie istnieje specjalna strona konfiguracyjna z instancjami komponent\u00f3w przechowuj\u0105cych poszukiwane przez nas warto\u015bci p\u00f3l.<\/p>\n\n\n\n<p>W pierwszej kolejno\u015bci musimy zaimplementowa\u0107 interfejs ContextPathStrategy:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n@Component(\n   service = ContextPathStrategy.class\n   property = {\n      \u201cservice.ranking.integer:1000\u201d   \n   }\n}\npublic class CustomContextPathStrategy implments ContextPathStrategy {\n   private static final String CONFIG_PAGE = &quot;configuration&quot;;\n   \n   @Override\n   public Iterator&lt;ContextResource&gt; findContextResource(Resource resource) {\n      List&lt;ContextResource&gt; contextResources = new ArrayList();\n      \n      Resource current = resource; \n      while (current != null) {\n         if (current.getPath().startsWith(&quot;\/content\/&quot;)) { \n            Resource configurationPage = current.getChild(CONFIG_PAGE); \n            if(configurationPage != null) {\n               contextResources.add(new ContextResource(configurationPage, current.getPath()));\n            }\n         }\n         current.getParent();\n      }\n      return contextResources.iterator();\n   }\n}\n<\/pre><\/div>\n\n\n<p>Ta us\u0142uga OSGI b\u0119dzie u\u017cywana podczas wyszukiwania \u015bcie\u017cki kontekstu. Wysoki ranking zapewnia, \u017ce zostanie u\u017cyta jako pierwsza. W metodzie findContextResource przeszukujemy hierarchi\u0119 zasob\u00f3w w g\u00f3r\u0119 do poziomu \/content, szukaj\u0105c takiego, kt\u00f3ry posiada dziecko o nazwie configuration \u2013 czyli naszej strony konfiguracyjnej. Je\u015bli zostanie znaleziona, jest dodawana do wyniku.<\/p>\n\n\n\n<p>Nast\u0119pnie przychodzi czas na u\u017cycie tej us\u0142ugi we w\u0142asnej implementacji ConfigurationResourceResolvingStrategy. W tym miejscu wprost wykorzystujemy CustomContextPathStrategy, kt\u00f3ra zwraca wyszukane \u015bcie\u017cki kontekstu.<\/p>\n\n\n\n<p>Nast\u0119pnie iterujemy po nich, szukaj\u0105c komponentu, kt\u00f3rego nazwa odpowiada nazwie interfejsu konfiguracji (MyConfig) oraz zgodna jest z zasadami tworzenia nazw komponent\u00f3w w AEM (metoda getComponentName). Je\u015bli komponent zostanie znaleziony \u2013 metoda go zwraca, a je\u015bli nie \u2013 nast\u0119puje fallback do kolejnej \u015bcie\u017cki kontekstu i ca\u0142y scenariusz jest powtarzany.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n@Component {\n   serice = ConfigurationResourceResolvingStrategy.class,\n   property = {\n      &quot;serivce.ranking:Integer=1000&quot;\n   }\n}\npublic class CustomConfigurationResourceResolvingStrategy implements ConfigurationResourceResolvingStrategy {\n   @Reference(target=&quot;(component.name=x.y.z.CustomContextPathStrategy)&quot;)\n   private ContextPathStrategy contextPathStrategy;\n   \n   @Override\n   public Resource getResource(Resource resourceResolver, Collection&lt;String&gt; bucketName) {\n      String className = configName.substring(configName.lastIndex(&#039;.&#039;) + 1);\n      return findContextResources(contentResource)\n         .map(configurationPage -&gt; findChildResource(configurationPage, getComponentName(className)))\n         .filter(Object::nonNull)\n         .findFirst()\n         .orElse(null)\n   }\n   \n   private String getComponentName(String className) {\n      String componentName = className.toLowerCase();\n      if(componentName.length() &gt; 20) {\n            return componentName.substring(0, 20);\n      }\n      return componentName;\n   }\n   \n   private Resource findChildResource(Resource resource, String name) {\n      if(resource.getName().equals(name)) {\n         return resource;\n      }\n      for(Resource child : resource.getChildren()) {\n         Resource result = findChildResource(child, name);\n         if(resoult != null) {\n            return result;\n         }\n      }\n      return null;\n   }\n\n   ...\n   implmenetation of the rest of the methods\n   ...\n   \n}\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/oferty-pracy\/\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" width=\"737\" height=\"170\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2026\/01\/praca-PL-k-3.jpg\" alt=\"oferty pracy\" class=\"wp-image-32991\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2026\/01\/praca-PL-k-3.jpg 737w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2026\/01\/praca-PL-k-3-300x69.jpg 300w\" sizes=\"(max-width: 737px) 100vw, 737px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>W podobny spos\u00f3b mo\u017cna obs\u0142ugiwa\u0107 kolekcje. Trzeba jedynie pami\u0119ta\u0107, \u017ce nazwa konfiguracji ma posta\u0107 x.y.z.MyConfig\/jcr:content\/keyValues i trzeba to uwzgl\u0119dni\u0107, aby by\u0142a poprawnie zapisywana jak i odczytywana.<\/p>\n\n\n\n<p>Cz\u0119\u015b\u0107 \/jcr:content pochodzi z wewn\u0119trznej implementacji Granite i w trakcie moich eksperyment\u00f3w nie uda\u0142o mi si\u0119 jej zmieni\u0107.<\/p>\n\n\n\n<p>Stworzenie implementacji tych dw\u00f3ch interfejs\u00f3w jest wystarczaj\u0105ce, aby obs\u0142u\u017cy\u0107 nasz niestandardowy scenariusz i stanowi \u015bwietny przyk\u0142ad elastyczno\u015bci mechanizmu Sling Context-Aware Customization.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dalsze rozwa\u017cania<\/strong><\/h2>\n\n\n\n<p>Istnieje r\u00f3wnie\u017c biblioteka 3rd party, kt\u00f3ra udost\u0119pnia UI oraz w\u0142asne strategie konfiguracji: <a href=\"https:\/\/wcm.io\/caconfig\/\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >Context-Aware Configuration | wcm.io<\/a><\/p>\n\n\n\n<p>Zawsze warto tak\u017ce zajrze\u0107 do oficjalnej dokumentacji: <a href=\"https:\/\/sling.apache.org\/documentation\/bundles\/context-aware-configuration\/context-aware-configuration.html\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >Apache Sling :: Apache Sling Context-Aware Configuration<\/a><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;32990&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;1&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( vote: 1)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;AEM Sites \u2013 konfiguracja z u\u017cyciem Sling Context\u2011Aware Configuration&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( vote: 1)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Przy tworzeniu jakiegokolwiek bardziej z\u0142o\u017conego projektu w AEM pr\u0119dzej czy p\u00f3\u017aniej pojawia si\u0119 temat przechowywania i dost\u0119pu do r\u00f3\u017cnych danych &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/aem-sites-konfiguracja-z-uzyciem-sling-context%e2%80%91aware-configuration\/\">Continued<\/a><\/p>\n","protected":false},"author":768,"featured_media":32993,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[6010,1512,930,551],"class_list":["post-32990","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-aem-2","tag-poradnik","tag-e-commerce","tag-konfiguracja"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2026\/01\/Coding.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/32990"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/768"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=32990"}],"version-history":[{"count":1,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/32990\/revisions"}],"predecessor-version":[{"id":32995,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/32990\/revisions\/32995"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/32993"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=32990"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=32990"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=32990"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}