{"id":53,"date":"2012-02-04T22:39:00","date_gmt":"2012-02-04T22:39:00","guid":{"rendered":"http:\/\/tpodolak.com.hostingasp.pl\/blog\/2012\/02\/04\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/"},"modified":"2016-01-31T00:20:50","modified_gmt":"2016-01-31T00:20:50","slug":"asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2012\/02\/04\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/","title":{"rendered":"ASP.NET MVC &#8211; okna modalne z wykorzystaniem Kendo UI"},"content":{"rendered":"<p>Ostatnimi czasy w pracy eksperymentujemy z ASP.NET MVC. Jednym z problem\u00f3w na jakie natkn\u0105\u0142em si\u0119 poznaj\u0105c t\u0105 technologi\u0119 by\u0142o utworzenie okien modalnych. Po niezbyt owocnej walce z kontrolkami ze stajni Devexpressa postanowili\u015bmy, \u017ce skorzystamy z darmowej biblioteki Kendo UI napisanej w jQuery. Wspomnian\u0105 wcze\u015bniej bibliotek\u0119 mo\u017cemy znale\u017a\u0107 pod adresem http:\/\/www.kendoui.com\/get-kendo-ui.aspx. Aby uzyska\u0107 dost\u0119p do plik\u00f3w nale\u017cy zarejestrowa\u0107 si\u0119 w systemie &#8211; oczywi\u015bcie rejestracja jest darmowa. Po zassaniu wszystkich plik\u00f3w kopiujemy zawarto\u015b\u0107 katalogu &#8220;source&#8221; do naszego projektu MVC. W moim przypadku utworzy\u0142em katalog Kendo w katalogu Content i tam umie\u015bci\u0142em zawarto\u015b\u0107 katalogu &#8220;source&#8221;.<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/Structure.jpg\" rel=\"attachment wp-att-438\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/Structure.jpg\" alt=\"Structure\" width=\"260\" height=\"555\" class=\"aligncenter size-full wp-image-438\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/Structure.jpg 260w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/Structure-70x150.jpg 70w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/Structure-141x300.jpg 141w\" sizes=\"auto, (max-width: 260px) 100vw, 260px\" \/><\/a><\/p>\n<p>Maj\u0105c wszystkie pliki w komplecie musimy wskaza\u0107 naszej aplikacji aby zacz\u0119\u0142a z nich korzysta\u0107. Dodajmy zatem w pliku _Layout.cshtml nast\u0119puj\u0105ce elementy<\/p>\n<pre lang=\"html\">\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/jquery.min.js\")\" type=\"text\/javascript\"><\/script>\r\n<link href=\"@Url.Content(\"~\/Content\/Site.css\")\" rel=\"stylesheet\" type=\"text\/css\" \/>\r\n<link href=\"@Url.Content(\"~\/Content\/Kendo\/styles\/kendo.common.css\")\" rel=\"stylesheet\"\/>\r\n<link href=\"@Url.Content(\"~\/Content\/Kendo\/styles\/kendo.default.css\")\" rel=\"stylesheet\"\/>\r\n<script src=\"@Url.Content(\"~\/Scripts\/jquery-1.5.1.min.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/jquery.min.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.core.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.data.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.pager.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.selectable.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.draganddrop.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.groupable.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.grid.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.fx.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.resizable.js\")\" type=\"text\/javascript\"><\/script>\r\n<script src=\"@Url.Content(\"~\/Content\/Kendo\/js\/kendo.window.js\")\" type=\"text\/javascript\"><\/script>\r\n<\/pre>\n<p>Przejd\u017amy teraz do najwa\u017cniejszej cz\u0119\u015bci, a mianowicie do tworzenia okna modalnego. Biblioteka Kendo UI udost\u0119pnia nam funkcj\u0119 kendoWindow, dzi\u0119ki kt\u00f3rej jeste\u015bmy w stanie utworzy\u0107 okno modalne. Okno to jednak nie ma w sobie \u017cadnej zawarto\u015bci &#8211; nie posiada nawet przycisk\u00f3w typu &#8220;Zapisz&#8221; oraz &#8220;Anuluj&#8221;. Utworzenie i za\u0142adowanie zawarto\u015bci okna oraz reakcja na klikni\u0119cia w potencjalne przyciski musi zosta\u0107 obs\u0142u\u017cona przez nas. Zacznijmy zatem od utworzenia zawarto\u015bci okna. Za\u0142\u00f3\u017cmy, \u017ce okno, kt\u00f3re za chwil\u0119 stworzymy b\u0119dzie s\u0142u\u017cy\u0142o do dodawania nowego produktu do bazy danych. Klasa produkt jest bardzo prost\u0105 klas\u0105 prezentuj\u0105c\u0105 si\u0119 w nast\u0119puj\u0105cy spos\u00f3b:<\/p>\n<pre lang=\"csharp\">\r\npublic class Product\r\n{\r\n    public string Id { get; set; }\r\n    public string Name { get; set; }\r\n    public int Quantity { get; set; }\r\n}\r\n<\/pre>\n<p>Stw\u00f3rzmy zatem strongly-typed partial view, kt\u00f3ry b\u0119dzie zawarto\u015bci\u0105 naszego okna modalnego. Widok ten b\u0119dzie posiada\u0142 dwa textboxy do wype\u0142niania propertis\u00f3w obiektu, oraz przyciski &#8220;Zapisz&#8221; oraz &#8220;Anuluj&#8221;. Zacznijmy od dodania odpowiednich funkcji w kontrolerze. Pierwsz\u0105 z nich b\u0119dzie akcja AddProduct();<\/p>\n<pre lang=\"csharp\">\r\npublic PartialViewResult AddProduct()\r\n{\r\n    return PartialView(\"AddProduct\", new Product());\r\n}\r\n<\/pre>\n<p>W celu dodania widoku klikamy PPM na nazw\u0119 funkcji i wybieramy opcj\u0119 &#8220;Add View&#8221;. W otwartym oknie zaznaczmy opcj\u0119 &#8220;Create Strongly Typed View&#8221;, a w comboboxie wpisujemy &#8220;Product&#8221;. Ponadto zaznaczamy checkboxa &#8220;Create as a partial view&#8221;.<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/addcontroller.jpg\" rel=\"attachment wp-att-436\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/addcontroller.jpg\" alt=\"addcontroller\" width=\"509\" height=\"501\" class=\"aligncenter size-full wp-image-436\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/addcontroller.jpg 509w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/addcontroller-150x148.jpg 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/addcontroller-300x295.jpg 300w\" sizes=\"auto, (max-width: 509px) 100vw, 509px\" \/><\/a><br \/>\nW katalogu Home pojawi\u0142 si\u0119 nowy plik AddProduct.cshtml. W pliku tym zdefiniujemy wygl\u0105d zawarto\u015bci naszego okna modalnego. Jako, \u017ce nasze dane b\u0119d\u0105 musia\u0142y zosta\u0107 wys\u0142ane na serwer do zapisu, skorzystamy z funkcji pomocniczej Html.BeginForm, w kt\u00f3rej to umie\u015bcimy wszystkie potrzebne elementy do edycji produktu.<\/p>\n<pre lang=\"html\">\r\n@model ModalDialogs.Models.Product\r\n<div id=\"windowContent\">\r\n    @using (Html.BeginForm(\"AddProduct\", \"Home\", FormMethod.Post, new { id = \"fmAddProduct\" }))\r\n    {\r\n        @Html.ValidationSummary(true)\r\n        <div>\r\n            @Html.Label(\"lblName\", \"Nazwa\")\r\n            @Html.TextBoxFor(val => val.Name)\r\n            @Html.ValidationMessageFor(val => val.Name)\r\n        <\/div>\r\n        <div>\r\n            @Html.Label(\"lblQuantity\", \"Ilo\u015b\u0107\")\r\n            @Html.TextBoxFor(val => val.Quantity)\r\n            @Html.ValidationMessageFor(val => val.Quantity)\r\n        <\/div>\r\n        <input type=\"button\" value=\"Zapisz\" id=\"btnSave\" \/>\r\n        <input type=\"button\" value=\"Anuluj\" id=\"btnCancel\" \/>\r\n    }\r\n<\/div>\r\n<\/pre>\n<p>Dodajmy teraz na naszej stronie g\u0142\u00f3wnej linka, kt\u00f3ry wywo\u0142a nasze okno modalne.<\/p>\n<pre lang=\"csharp\">\r\n@Html.ActionLink(\"Dodaj produkt\", \"AddProduct\", \"Home\", null, new { id = \"addProduct\" })\r\n<\/pre>\n<p>Przyszed\u0142 teraz czas na najwa\u017cniejsz\u0105 cz\u0119\u015b\u0107 wpisu, a mianowicie na wykorzystaniu jQuery oraz kendoWindow do pokazania okna edycji\/dodawania produktu. Najpierw podpinamy si\u0119 do zdarzenia(dodajemy handler) click utworzonego przed chwil\u0105 odno\u015bnika. W funkcji obs\u0142uguj\u0105cej zdarzenie click musimy utworzy\u0107 okno,wype\u0142ni\u0107 jego zawarto\u015b\u0107 oraz pokaza\u0107 okno.<\/p>\n<pre lang=\"javascript\">\r\n$(document).ready(function () {\r\n        var $kendoWindow;\r\n        $(\"#addProduct\").click(function (event) {\r\n            debugger;\r\n            event.preventDefault(); \/\/ anulujemy domy\u015bln\u0105 akcj\u0119\r\n            var $dialog = $('<div><\/div>');\r\n            var $url = $(this).attr('href'); \/\/wyci\u0105gamy  url-a\r\n            $dialog.empty();\r\n            $kendoWindow = $dialog.kendoWindow({ \/\/tworzmy okno\r\n                height: \"200px\", \/\/o wysokosci 200px\r\n                title: \"Dodaj\", \/\/ z tytulem \"Dodaj\"\r\n                width: \"200px\", \/\/ o szerokosci 200px\r\n                actions: [\"Close\"], \/\/ ktore mozna jedynie zamknac - nie mozna przesuwac, odswiezac itp\r\n                content: $url \/\/ ktorego zawartosc pobieramy z urla przechwyconego z clica\r\n\r\n            }).data(\"kendoWindow\");\r\n            $kendoWindow.center(); \/\/centrujemy okno\r\n            $kendoWindow.open(); \/\/ otwieramy\r\n        });\r\n...\r\n...\r\n...\r\n}<\/pre>\n<p>Korzystaj\u0105c z selektora jQuery znajdujemy link opisany id-kiem &#8220;addProduct&#8221;, a nast\u0119pnie pod\u0142\u0105czamy si\u0119 do zdarzenia click. W funkcji obs\u0142uguj\u0105cej zdarzenie musimy najpierw zapobiec wywo\u0142aniu si\u0119 domy\u015blnej akcji wykonuj\u0105cej si\u0119 po naci\u015bni\u0119ciu na link. Robimy to przy pomocy funkcji prefentDefault(). W kolejnych krokach tworzymy okno modalne zgodnie ze wskaz\u00f3wkami znajduj\u0105cymi si\u0119 w dokumentacji Kendo UI http:\/\/demos.kendoui.com\/web\/window\/index.html. Najwa\u017cniejszym elementem przy tworzeniu okna jest dynamiczne za\u0142adowanie jego zawarto\u015bci poprzez podanie linka do akcji w kontrolerze. Linka tego jeste\u015bmy w stanie wyci\u0105gn\u0105\u0107 wykorzystuj\u0105c kolejn\u0105 u\u017cyteczn\u0105 funkcj\u0119 jQuery &#8211; attr(&#8216;nazwaAtrybutu&#8217;).<br \/>\nOd tej chwili po naci\u015bni\u0119ciu odno\u015bnika &#8220;Dodaj produkt&#8221; zawsze b\u0119dzie odpalane okno modalne dodawania nowego produktu. Teraz musimy jeszcze obs\u0142u\u017cy\u0107 zdarzenia click na przyciskach &#8220;Zapisz&#8221; oraz &#8220;Anuluj&#8221;. Do funkcji przedstawionej powy\u017cej dopisujemy nast\u0119puj\u0105ce linijki<\/p>\n<pre lang=\"javascript\">\r\n$(\"#btnSave\").live(\"click\", function (event) {\r\n            event.preventDefault(); \/\/ anulujemy domy\u015bln\u0105 akcj\u0119\r\n            var $url = $(\"#fmAddProduct\").attr(\"action\"); \/\/wyci\u0105gamy  url-a\r\n           \/\/ odpalamy ajaxa w celu wywo\u0142ania akcji kontrolera\r\n            $.ajax(\r\n                {\r\n                    url: $url,  \/\/ podajemy url z akcja kontrolera\r\n                    type: \"POST\", \/\/ okreslamy metode \r\n                    data: $(\"#fmAddProduct\").serialize(), \/\/ przekazujemy dane \r\n                    success: function (response) {       \/\/w przypadku gdy wszystko OK\r\n                        $(\"#btnSave\").unbind(); \/\/ odpinamy zdarzenia\r\n                        $(\"btnCancel\").unbind();\r\n                        $kendoWindow.close(); \/\/zamykamy i \r\n                        $kendoWindow.destroy(); \/\/ niszczymy okno\r\n                    },\r\n                    error: function (response) {\r\n                        $(\"#btnSave\").unbind(); \/\/odpinamy zarzenia\r\n                        $(\"btnCancel\").unbind();\r\n                        $kendoWindow.content(response.responseText); \/\/odswiezamy zawartosc okna\r\n                    }\r\n                });\r\n        });\r\n\r\n        $(\"#btnCancel\").live(\"click\", function (event) {\r\n            event.preventDefault();\/\/ anulujemy domy\u015bln\u0105 akcj\u0119\r\n            $(\"#btnSave\").unbind(); \/\/odpinamy zdarzenia\r\n            $(\"btnCancel\").unbind();\r\n            $kendoWindow.close(); \/\/zamykamy i\r\n            $kendoWindow.destroy(); \/\/ niszczymy okno\r\n        });\r\n<\/pre>\n<p>Tutaj sytuacja odrobin\u0119 si\u0119 komplikuje gdy\u017c musimy wys\u0142a\u0107 wprowadzone dane do kontrolera oraz obs\u0142u\u017cy\u0107 ewentualne b\u0142\u0119dy walidacji. Zaczynamy od znalezienia przycisku opisanego id-kiem &#8220;btnSave&#8221; oraz podpi\u0119cia si\u0119 do zdarzenia click. Ponownie anulujemy domy\u015bln\u0105 akcj\u0119 wywo\u0142uj\u0105c funkcj\u0119 preventDefault(). W kolejnym kroku wyci\u0105gamy url-a, kt\u00f3ry mia\u0142 zosta\u0107 wywo\u0142any po naci\u015bni\u0119ciu przycisku. Robimy to, ponownie wykorzystuj\u0105c funkcj\u0119 attr(&#8216;nazwaAtrybutu&#8217;). Jednak\u017ce teraz wyszukujemy tego atrybutu na obiekcie o id =&#8221;fmAddProduct&#8221; (taki id nadali\u015bmy &#8220;formie&#8221; na kt\u00f3rej s\u0105 pola edycyjne produktu).Ostatnim elementem jest wykonanie asynchronicznego zapytania AJAX. Do tego zapytania przekazujemy wcze\u015bniej uzyskany url,okre\u015blamy typ zapytania jako &#8220;POST&#8221; oraz przesy\u0142amy dane wykorzystuj\u0105c funkcj\u0119 serialize z biblioteki jQuery. Na samym ko\u0144cu musimy sprecyzowa\u0107 co ma si\u0119 sta\u0107 w przypadku gdy wszystko p\u00f3jdzie ok &#8211; parametr success, a co w przypadku gdy co\u015b b\u0119dzie nie tak &#8211; parametr error. Musimy oczywi\u015bcie doda\u0107 do kontrolera jeszcze jedn\u0105 akcj\u0119. Tym razem b\u0119dzie to r\u00f3wnie\u017c akcja AddProduct, jednak\u017ce b\u0119dzie to akcja HttpPost posiadaj\u0105ca jeden parametr typu <span style=\"font-style: italic;\">Product<\/span><\/p>\n<pre lang=\"csharp\">\r\n[HttpPost]\r\npublic ActionResult AddProduct(Product product)\r\n{\r\n    if (ModelState.IsValid)\r\n        return new EmptyResult();\r\n    Response.StatusCode = (int)HttpStatusCode.BadRequest;\r\n    return PartialView(\"AddProduct\", product);\r\n}\r\n<\/pre>\n<p><a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/save.jpg\" rel=\"attachment wp-att-437\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/save.jpg\" alt=\"okna modalne\" width=\"407\" height=\"176\" class=\"aligncenter size-full wp-image-437\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/save.jpg 407w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/save-150x65.jpg 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/02\/asp-net-mvc-okna-modalne-z-wykorzystaniem-kendo-ui\/save-300x130.jpg 300w\" sizes=\"auto, (max-width: 407px) 100vw, 407px\" \/><\/a><br \/>\nOstatni\u0105 rzecz\u0105 jak\u0105 musimy zrobi\u0107 jest wy\u0142\u0105czenie cachowania widok\u00f3w, kt\u00f3re s\u0105 pokazywane w oknie modalnym &#8211; mo\u017cna to zrobi\u0107 wykorzystuj\u0105c atrybut OutputCaching. W przypadku gdy nie wy\u0142\u0105czymy cachowania, okna modalne, kt\u00f3re raz nie przesz\u0142y walidacji nie b\u0119d\u0105 mog\u0142y zosta\u0107 zapisane. W celu wy\u0142\u0105czenia cachowania dla poszczeg\u00f3lnych widok\u00f3w najpierw musimy stworzy\u0107 profil cachowania. Dodajemy taki oto wpis do pliku Web.config<\/p>\n<pre lang=\"xml\">\r\n<caching>\r\n      <outputCacheSettings>\r\n        <outputCacheProfiles>\r\n          <add name=\"DisableCaching\"\r\n               duration=\"0\"\r\n               varyByParam=\"None\"\r\n               location=\"None\" \/>\r\n        <\/outputCacheProfiles>\r\n      <\/outputCacheSettings>\r\n<\/caching>\r\n<\/pre>\n<p>a nast\u0119pnie dekorujemy atrybutem<\/p>\n<pre lang=\"csharp\">\r\n[OutputCache(CacheProfile = \"DisableCaching\")]\r\n<\/pre>\n<p>akcje AddProduct() oraz AddProduct(Product product)<br \/>\nTo by by\u0142o na tyle, projekt mo\u017cna zassa\u0107 z tego linka http:\/\/www.4shared.com\/rar\/F4pNi3VH\/ModalDialogs.html<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ostatnimi czasy w pracy eksperymentujemy z ASP.NET MVC. Jednym z problem\u00f3w na jakie natkn\u0105\u0142em si\u0119 poznaj\u0105c t\u0105 technologi\u0119 by\u0142o utworzenie okien modalnych. Po niezbyt owocnej walce z kontrolkami ze stajni Devexpressa postanowili\u015bmy, \u017ce skorzystamy z darmowej biblioteki Kendo UI napisanej w jQuery. Wspomnian\u0105 wcze\u015bniej bibliotek\u0119 mo\u017cemy znale\u017a\u0107 pod adresem http:\/\/www.kendoui.com\/get-kendo-ui.aspx. Aby uzyska\u0107 dost\u0119p do plik\u00f3w [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[83,116,115],"tags":[223,248,249],"class_list":["post-53","post","type-post","status-publish","format-standard","hentry","category-asp-net-mvc","category-modalwindow","category-mvc","tag-asp-net-mvc","tag-modalwindow","tag-mvc"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/53","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":5,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"predecessor-version":[{"id":558,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/53\/revisions\/558"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}