Nowości w Bonsole(4): Obsługa formularzy i pierwszy przydatny przykład
21.04.2020 11:55
W końcu stworzyłem przydatny program. Służy do edycji /etc/passwd za pomocą formularza html lub konsolowego (w zależności od uruchomionego backend-u).
Zaprezentowałem już, jak działa obsługa formularzy w backendzie konsolowym. Ogólnie źle, prawda? Znacznie lepiej się prezentuje obsługa przez backend normalny/Bonsole. Tak wygląda ten sam formularz w backendzie normalnym:
Mamy tutaj przycisk następne, zapisz pełny plik i utwórz nowy rekord. Przycisk następne nie jest zawsze widoczny, a gdy jest to możliwe, ukazuje się przycisk poprzednie.
Do zrzutu pliku, tworzymy plik tymczasowy, zapisujemy w nim dane, usuwamy plik docelowy poleceniem rm (z shella), przenosimy plik tymczasowy w miejsce usuniętego poleceniem mv (z shella). Gdy te operacje nie są możliwe, to wykorzystujemy pkexec. Wykorzystuję polecenia powłoki (shella), gdyż jest to najlepszy sposób, w przypadku przenoszenia plików (implementacja czegoś takiego jest dosyć trudna, zważywszy iż możemy mieć wiele systemów plików, dowiązania, itd.). Może w przyszłości się to zmieni.
Ze strony programisty
Przede wszystkim, to programy należy łączyć z biblioteką kliencką Bonsole. Ona ładuje odpowiedni backend, w zależności od ustawień użytkownika. Mamy do dyspozycji trochę wywołań i konwencji:
Bonsole wymaga, by program generował drzewo dokumentu, dokładając kolejne elementy do elementu głównego, zwróconego przez:
bonsole_reset_document(0); xmlDocPtr a = bonsole_window(0); xmlNodePtr root = xmlDocGetRootElement(a);
xmlDocGetRootElement. Jak jednak widać, musimy najpierw pobrać dokument przez bonsole_window. Zero przekazane jako argument oznacza kontekst - obecnie wymagane jest, by zawsze podawać w miejsce kontekstu NULL (bądź też 0).
bonsole_reset_document(kontekst) resetuje dokument dla wskazanego kontekstu. Jest to wymóg, dzięki któremu poprzednie elementy nie pozostaną w drzewie przy kolejnym generowaniu widoku.
Wspomnę, że Bonsole korzysta z libxml2 i aplikacja także musi.
Do utworzenia formularzy, posiłkujemy się znacznikiem form, nadając mu atrybut action o wartości app:nazwa_akcji . Podczas przesyłania formularza, bonsole będzie się zachowywać jak przeglądarka internetowa, dodając parametry po znaku ? (poprzedzonego nazwą akcji - bez app:), oddzielając każdy przez znak &, a wartości i nazwy zmiennych oddzielając znakiem równości.
Takie ciągi będą przesyłane do pętli obsługi żądań/komunikatów. By nadać wartości polom formularza, posiłkujemy się:
bonsole_set_form(kontekst, "app:nazwa_akcji", "json");
W json nazwy pól to nazwy pól formularza, a wartości pól to wartości pól formularza.
Możemy także pobrać wartości pól formularza w dowolnym momencie, poprzez:
bonsole_get_form(kontekst, akcja, prefix);
Za kontekst oczywiście podstawiamy NULL, za akcję nazwę akcji formularza, wraz z app:, a za prefix app:nazwa_prefiksu. Jest jednak jeden minus. Wywołanie tej funkcji oznacza wysłanie komunikatu do pętli obsługi komunikatów, a nie powrót z wynikiem w miejscu wywołania
Postaram się naprawić to w przyszłości.