Framework do pisania CRUDów polecacie?

Framework do pisania CRUDów polecacie?
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
2

Cześć, słyszałem ze niektóre firmy przepisują CRUD z Javy do Rusta i zastanawiam się czy jest jakiś dobry framework lub biblioteka do tego. Przy czym bardziej chodzi mi o rustowy odpowiednik Akka-HTTP i JOOQ/Slice niż spasioną kobyłę jak Spring


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
KamilAdam
Ciekawe. Nie jestem w stanie edytować posta ze srajfona
UglyMan
Bo srajfon to zło!!!
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:3561
0

@KamilAdam:

Serio przepisują? Moze dostałeś tylko pół informacji, np tylko 5% krytyczne wydajnościowo?
Nie wyobrażam sobie płynnego rozwoju rozległego, uniwersalnego systemu w języku bez refleksji, toż to zrobienie i UŻYTKOWANIE jakiejkolwiek biblioteki, to straszliwe schody
Podobnie jak fw w Delphi, C, C++. Niby można, ale nikt tego nie robi (oprócz w/w 5%). I raczej jednowarstwowe aplikacje na konkretny projekt


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 1x, ostatnio: AnyKtokolwiek
KR
Refleksja w runtime to zło. Zawsze przez nią same problemy tylko były.
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
2

@AnyKtokolwiek: a po co ci ta refleksja? Np w Slick refleksja jest bardzo słabo używana. Slick nie używa refleksji przy mapowaniu z i do emocji bazodanowych. Podobnie przy serializacji do JSONa nie używa się w Scali refleksji. Wiec na co ta refleksja w zasadzie jest potrzebna?


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
W0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 2 godziny
  • Postów:3540
4
AnyKtokolwiek napisał(a):

Nie wyobrażam sobie płynnego rozwoju rozległego, uniwersalnego systemu w języku bez refleksji, toż to zrobienie i UŻYTKOWANIE jakiejkolwiek biblioteki, to straszliwe schody

Zgadzam się z tym, że napisanie jakiejkolwiek dużej biblioteki (a tym bardziej frameworka) to dużo roboty, ale nie zgadzam się z tym, że nie da się tego zrobić bez refleksji. W najgorszym wypadku wpadnie trochę więcej boilerplate'u w niektórych miejscach.

edytowany 2x, ostatnio: wartek01
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:3561
0
wartek01 napisał(a):
AnyKtokolwiek napisał(a):

Nie wyobrażam sobie płynnego rozwoju rozległego, uniwersalnego systemu w języku bez refleksji, toż to zrobienie i UŻYTKOWANIE jakiejkolwiek biblioteki, to straszliwe schody

Zgadzam się z tym, że napisanie jakiejkolwiek dużej biblioteki (a tym bardziej frameworka) to dużo roboty, ale nie zgadzam się z tym, że nie da się tego zrobić bez refleksji. W najgorszym wypadku wpadnie trochę więcej boilerplate'u w niektórych miejscach.

Dokładnie, da się zastąpić znaczną ilością boilerplate'u. Np w C++ się jedzie makrami z ##

Różnica układu opartego na refleksji a bez niej jest taka, że albo np do silnika raportów lub generatora formatek CRUD możemy podać jakikolwiek obiekt (który sam się dokumentuje) a musi być przygotowany (implementować interfejsy, czy w inny sposób).

Jak ktoś pamięta EJB 1/2 (ja nie, zerkałem "przez ramię" z trzeciego rzędu) to tam był przymus implementowania interfejsów, coby nie powiedzieć POJO to krok we właściwą stronę.


Bo C to najlepszy język, każdy uczeń ci to powie
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

Aż mnie zaciekawiłeś - co takiego można łatwo osiągnąć refleksją, czego nie da się łatwo osiągnąć procmakrami oraz traitami? Powiedziałbym nawet, że podejście Rusta jest dużo lepsze, ponieważ makra działają w czasie kompilacji :-)


edytowany 1x, ostatnio: Patryk27
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
0
AnyKtokolwiek napisał(a):

Różnica układu opartego na refleksji a bez niej jest taka, że albo np do silnika raportów lub generatora formatek CRUD możemy podać jakikolwiek obiekt (który sam się dokumentuje) a musi być przygotowany (implementować interfejsy, czy w inny sposób).

Nie do końca rozumiem o co ci chodzi ale w Ruscie dla dowolnego istniejącego już typu struktury (odpowiedniku klasy) możesz dalej implementować trakty (odpowiedniki interfejsów). Podobnie jest w Swifcie tylko tam są protokoły i Haskellu tylko tam są klasy typów.


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:3561
0

@KamilAdam: @Patryk27:

Ale oczywiście, że się da interfejsować *), tylko pytanie, czy należy (przeróbka Bartoszewskiego)

Jak ja mam Customera, to podaję go takiego samego do frontu (przyjmijmy swój), do silnika raportowego (przyjmijmy że to obcy produkt), a może i do perzystencji (wieloletnia libka firmowa)

Wy chcecie intefejsowac go dwa (lub więcej) razy.
W moim odczuciu rynek już dawno wybrał, że POJO (w ekosystemie Javy) jest lepsze od interfejsowanych klas. To samo POJO mogę podać do siedemnastu bibliotek/frameworków, których autorzy nigdy niczego ze sobą nie uzgodnili.

nawet czuję, co odpowiecie: CustomerForPrint, CustomerForFront, CustomerMiddleLayer, CustomerEntity
Może w korpo tak się pisze, ja mam wątpliwości czy to rozsądne.

ps. Mocno (względnie) przezywam syf w C++, gdzie każdy framework ma swojego stringa, to taka analogia

*) naście lat temu brałem się za to w C++, na szczęście zaraziłem się Javą i (wtedy w Swingu) wszystko stało się jaśniejsze


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 2x, ostatnio: AnyKtokolwiek
W0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 2 godziny
  • Postów:3540
1

@AnyKtokolwiek: no spoko - rynek "wybrał", że POJO est lepsze od "interfejsowanych klas". Tyle tylko, że - jak sam piszesz:

nawet czuję, co odpowiecie: CustomerForPrint, CustomerForFront, CustomerMiddleLayer, CustomerEntity
Może w korpo tak się pisze, ja mam wątpliwości czy to rozsądne.

Każde podejście ma swoje wady i zalety. Wadą jednolitego POJO, które jest konwertowane przez wszystkie mechanizmy jest to, że łatwo coś zepsuć o tym nie wiedząc. Wadą takich oddzielnych klas jest to, że trzeba trochę więcej kodu napisać.
Przy mniejszych i średnich projektach podejście pierwsze może się sprawdzać. Przy większych - podejście drugie jest raczej lepsze.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
1

@AnyKtokolwiek: w Ruście miałbyś przecież jedną strukturę i ewentualnie kilka #[derive(...)], w stylu:

Kopiuj
#[derive(DatabaseEntity, ReportEntity, Whatever)]
struct Customer {
   ...
}

... no copy-paste needed here; chyba że czegoś nie dostrzegam :-)


edytowany 1x, ostatnio: Patryk27
AK
Ale to jak się implementuje? Ja sobie wyobrażam, że np ReportEntity to ma string[] getFields() i getValue(string) - to takie minimum
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:3561
0
wartek01 napisał(a):

@AnyKtokolwiek: no spoko - rynek "wybrał", że POJO est lepsze od "interfejsowanych klas". Tyle tylko, że - jak sam piszesz:

nawet czuję, co odpowiecie: CustomerForPrint, CustomerForFront, CustomerMiddleLayer, CustomerEntity
Może w korpo tak się pisze, ja mam wątpliwości czy to rozsądne.

Wadą takich oddzielnych klas jest to, że trzeba trochę więcej kodu napisać.

Napisać to pikuś, ale to tzreba konserwować. Za dużo widziałem sklepów internetowych, gdzie coś się pozytywnie waliduje na froncie, ale leci wyjątek z backendu.
Z mojej perspektywy o wiele bezpieczniej się czuję bez niepotzrebnego mnożenia DTO


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 1x, ostatnio: AnyKtokolwiek
hauleth
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:12 dni
3

@AnyKtokolwiek: jeśli chodzi o to jak się implementuje własne derive to trzeba napisać makro. Co do samego ReportEntity to zamiast ReportEntity::get_fields oraz ReportEntity::get_value możesz zamiast tego mieć wizytora, przez co generowany jest kod w postaci:

Kopiuj
struct Customer {
  name: String,
  age: usize,
}

trait ReportEntity for Customer {
  fn report(&self, reporter: &mut Reporter) -> io::Result<()> {
    reporter.add_str("name", self.name)?;
    reporter.add_usize("age", self.age)?;

    Ok(())
  }
}

Dzięki czemu nie musisz mieć refleksji w runtime, a jedynie w compile-time.


edytowany 2x, ostatnio: hauleth
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:3561
0

@hauleth:

Kapuję. Jeszcze getery po nazwie by trzeba.

Na pewno to wygląda ładniej, czytelniej, niż w templejtkach C++ bindingi miedzy kodem natywnym (struktury, ale też klasy z metodami) a interpreterem, gdzie trzeba wystawić nazwane stringiem (luabind, boost::python, których kiedyś używałem).

Istota zagadnienia bardzo podobna.


Bo C to najlepszy język, każdy uczeń ci to powie
hauleth
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:12 dni
1

@AnyKtokolwiek: a po co? Zrób pola publiczne jak potrzebujesz je czytać poza modułem, w którym są zdefiniowane.


AK
Moduł raportów nigdy nie było kompilowany w powiązaniu z Customer ???
hauleth
@AnyKtokolwiek: nie rozumiem o co pytasz.
stivens
  • Rejestracja:ponad 8 lat
  • Ostatnio:37 minut
7

Jeszcze getery po nazwie by trzeba.

I od razu wiesz ze rozmawiasz z Javovcem... :D :D


λλλ
edytowany 1x, ostatnio: stivens
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 7 godzin
  • Postów:2964
1

Wracając do tematu: actix-web jest całkiem spoko, o ile go sparujesz z czymś mocnym do ui na froncie (przy czym tu nie podpowiem, bo nie moja bajka).

AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:3561
0
stivens napisał(a):
AnyKtokolwiek

Jeszcze getery po nazwie by trzeba.

I od razu wiesz ze rozmawiasz z Javovcem... :D :D

nie rozumiem o co pytasz. — @hauleth

Dlaczego?
Może raczej z plusowcem. Javowiec w sposób oczywisty by jechał refleksją

Nie mówcie, że w w/w Rust trait jest po cichu zawarte pobieranie w jednym module, z modułu który był nieznany na etapie kompilacji - bo nie wierzę.

Kopiuj
class CustomerWrapper {
       private:
          const Customer * parent;

public:
  // C++ , przynajmniej starsze wersje, ma problem z typem zwracanym
        AnyCokolwiek get(string field_name);
}


Bez takiego pośrednictwa silnik raportów / webowy (nigdy nie dotykałem w C++) lub interpreter (dotykałem, i to niemało: Python, Lua, własny silnik C++/język do wydruków) nie zintegruje się z częścią binarną


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 4x, ostatnio: AnyKtokolwiek
stivens
  • Rejestracja:ponad 8 lat
  • Ostatnio:37 minut
4

Tylko Javovcy wciskaja na sile get i set bez logiki.

Jak masz setter, ktory robi { this.foo = foo } to rownie dobrze mozesz wywalic enkapsulacje. A jak nie masz settera w ogole to wystarczy publiczne, niemutowalne pole.


λλλ
edytowany 2x, ostatnio: stivens
KamilAdam
Kiedyś wymagały tego frameworki. Dziś robi się to z przyzwyczajenia
AK
Rozmawiamy o zupełnie innej sytuacji
stivens
A na pewno masz na mysli getter?
AK
Rzeczony silnik raportowy ze wzorca (projektu raportu) poznał potrzebę wydrukowania pola o nazwie "alamakota" - jak to ma pobrać z klienta raportu? Nazwałem to 'geter po nazwie'. Chodzi o most między kodem natywnym, a przetwarzaniem po stringach
hauleth
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:12 dni
1

@AnyKtokolwiek: ale po co Ci to pobieranie? Dałem przykład jak można zaimplementować taki reporting w taki sposób, że dynamicznie możesz użyć takiego komponentu do budowania raportów.

Mając ww. przykład można stworzyć:

Kopiuj
#[derive(Default)]
struct JSONReporter {
  // …
}

impl Reporter for JSONReporter {
  fn add_str(&mut self, key: &str, value: &str) {
    self.output(key, value);
  }

  fn add_usize(&mut self, key: &str, value: size) {
    self.output(key, value.to_string())
  }

  // …
}

fn gen_json_report(data: &dyn ReportEntity) {
  let mut reporter = JSONReporter::default();

  data.report(&mut reporter);
}

W ten sposób możesz przekazać jako argument do gen_json_report cokolwiek, co implementuje trait ReportEntity i dynamicznie, w czasie wykonania, będzie wybrana odpowiednia implementacja poprzez vtable. Na co Ci jakiekolwiek gettery czy settery?


AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:3561
0

@hauleth:

Rust ma konsekwentnego "przodka" wszystkich obiektów, z prymitywami włącznie ?


Bo C to najlepszy język, każdy uczeń ci to powie
SL
Nie, jak chcesz jakąś funkcjonalność to po prostu ją implementujesz, jak chcesz defaultowe zachowania to możesz użyć domyślnej implementacji https://doc.rust-lang.org/rust-by-example/trait/derive.html#derive . Wszystko ładnie i elegancko odseparowane. Nie musisz płacić za to czego nie używasz jak to ma miejsce w Javie, że ktoś 25 lat temu wymyślił sobie, że każdy obiekt musi być monitorem
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
0

@AnyKtokolwiek: Rust nie jest językiem obiektowym. Nie ma obiektów. Nie ma dziedziczenia pól. Nie ma dziedziczenia implementacji za wyjątkiem domyślnej implementacji zawartej w traitach
UPDATE powiedz proszę jaki problem chcesz tym przodkiem rozwiązać bo rozwiązania z Javy nie mapują się na Rusta 1 do 1


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
edytowany 1x, ostatnio: KamilAdam
AK
Zrozum, że nie porównuję do javy, tylko do C++. Dla mnie np interfejs miedzy językiem interpretowanym, a do niego dodatkiem natywnym jest oczywista (najczęściej C a C++ jest warstwą dodatkową). Musi istnieć dwustronny most obiektów kilku typów, sterowanych stringiem. Używam "obiekty" w szerokim sensie, bo nawet w C się da to wyrazić
KamilAdam
Chyba rozumiem o co ci chodzi ale dziś tego nie napiszę bo jestem poza domem. Może w poniedziałek
hauleth
@AnyKtokolwiek: ja dalej nie rozumiem co chcesz osiągnąć. No jak potrzebujesz rożne typy w jednej zmiennej to zawsze jest enum, który Ci na to pozwoli.
hauleth
Alternatywnie możesz użyć fat-pointer, który używa vtable do tego by przechować wskaźniki na implementację.
KA
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 lata
  • Postów:594
6

Po cholerę pisać w Rust jakieś CRUDy.
Masakra jakaś. Nie każdy język musi służyć do pisania weba.
Już Golanga dostatecznie popsuto.

No i po co jak w czymś innym zrobicie to szybciej...

Pozniej każdy jeden język jest do wszystkiego i do niczego.

edytowany 2x, ostatnio: karsa
Zobacz pozostałe 6 komentarzy
KR
Dobrego programistę Rust nie jest tak trudno znaleźć - jest ich wprawdzie mniej, ale średni poziom jest wyższy, więc masz mniejszy odrzut na rekrutacji. To nie jest taka nisza jak Clojure czy Haskell. Poza tym praktycznie każdy programista C++ ogarnie Rust z marszu, no może po przeczytaniu książki przez weekend.
KA
Ludzie z C++ zazwyczaj crudow nie pisza
KR
Piszą, piszą. Jest masa korporacyjnych systemów legacy napisanych kiedyś w latach 90-tych w C++, które ktoś musi utrzymywać i które nie zostały przypisane.
Escanor16
O jakie złoto, oprawić w ramkę i powiesić nad biurkiem
KA
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 7 godzin
  • Postów:2964
9
karsa napisał(a):

Po cholerę pisać w Rust jakieś CRUDy.

Ludzie się tak zafiksowują na wydajności i low-latency, że zapominają o innych przewagach Rust nad większością popularnych języków. Porównajmy z Java:

  • Inferencja typów
  • Makra > refleksja runtime, zdecydowanie mniej magii
  • Prostszy i bardziej spójny system obsługi błędów, który się nie gryzie z FP
  • traity są bardziej ekspresywne od klas/interfejsów, lepiej działają z genericsami
  • Package private, które działa jak trzeba
  • Brak wymazywania typów, można zrobić T::new, gdzie T to typ generyczny, można zaimplementować ten sam interfejs kilka razy dla różnych typów generycznych itp
  • Sprawdzanie w czasie kompilacji rzeczy które Java umie sprawdzać tylko w runtime (np. użycie zasobu po zamknięciu)
  • Sprawdzanie w czasie kompilacji rzeczy, których Java w ogóle nie umie sprawdzać nawet w runtime (np. wyścigi w danych)
  • Świetny system paczkowania cargo
  • Wbudowane cargo fmt / check / clippy / audit
  • Sum types
  • Pattern matching
  • Typy unsigned
  • Natywne operacje na liczbach 128-bitowych bez tego całego BigIntegerowego nonsensu
  • Świetne komunikaty o błedach, bardzo przyjazny kompilator
  • Deterministycznie sprzątanie zasobów (try w Javie to zabawka)
Zobacz pozostałe 27 komentarzy
KA
Nie chcę mi się wymieniać każdego języka ze świata jvm ;)
hauleth
@karsa: K8s był napisany w Javie i często w kodzie Go to widać. A tak szczerze, to jak mam pisać CRUDy czy inne coś co działa z siecią to najczęściej wolę Elixira/Erlanga, bo tam praca z pakietami i siecią jest po prostu przyjemna, a nie jest to ból d**y jak w większości innych języków.
KA
No był ale nikt by nie używał. A z Infry teraz Java będzie powoli znikać. Elixir może, nie spotkałem jeszcze na prodzie
hauleth
Czy ja wiem czy nikt by nie używał. Kafki jakoś używają, Hadoopa i Elastica też. No ja spotkałem, samemu nawet go tam umieszczałem.
KA
No i pogadaj z ludźmi co swoimi recoma ta Kafke trzymają na produkcji i ile to zasobów zżera. Też już słyszałem kejz o wywaleniu Elastica. Zamiast Casandry możesz scylledb, zamiast Kafki Red Pandę, zamiast Elastica Algolie czy tam mailsearch napisany w Rust na podstawie algolii. A jak robisz cloud offering i chcesz być konkurencyjny to chcesz mieć mniejsze koszty za EC2.
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:Laska, z Polski
  • Postów:10056
2

Best framework is no framework.

PP
@Riddle: teraz ramke i stawiac na kazdym biurku.
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
0
Riddle napisał(a):

Best framework is no framework.

:D

To jaką biblitekę do pisania serwera HTTP/REST polecacie? Coś lekkiego jak akka-http szukam
Jaką bibliotekę do obsługi SQLa polecacie? Najlepiej z typowanym SQLem jak Slick, ewentualnie jak JOOQ
:P


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
Tenonymous
  • Rejestracja:ponad 7 lat
  • Ostatnio:15 dni
  • Postów:425
0
KamilAdam napisał(a):
Riddle napisał(a):

Best framework is no framework.

:D

To jaką biblitekę do pisania serwera HTTP/REST polecacie? Coś lekkiego jak akka-http szukam
Jaką bibliotekę do obsługi SQLa polecacie? Najlepiej z typowanym SQLem jak Slick, ewentualnie jak JOOQ
:P

Actix-web do backendu, jeżeli chodzi o SQL to Diesel.

AN
AN
  • Rejestracja:około rok
  • Ostatnio:7 miesięcy
  • Postów:30
1

Obecnie za wcześnie na takie połączenie, ale czekam niecierpliwie na rozwój sytuacji.

https://www.reddit.com/r/rust/comments/17b3ltu/my_journey_modifying_the_rust_compiler_to_target/
https://github.com/dwdkls/pizzamvc

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)