2013-09-03 12 views
10

Robię ten prosty serwer WWW, który może hostować mojego bloga, ale cokolwiek robię; Nie mogę wykonać prawidłowego sformatowanego czasu w moim html/template.Wykonaj sformatowany czas w plasterku za pomocą szablonu/html/template

Oto, co zrobić:

Utworzyłem ten struct:

type Blogpost struct { 
    Title string 
    Content string 
    Date time.Time 
} 

Następna w kolejce mam utworzony ten mały func że pobiera blogposts z analogicznym tytule/pochodzi z AppEngine magazynu danych i powrócić że jako plaster:

func GetBlogs(r *http.Request, max int) []Blogpost { 
    c := appengine.NewContext(r) 
    q := datastore.NewQuery("Blogpost").Order("-Date").Limit(max) 
    bp := make([]Blogpost, 0, max) 
    q.GetAll(c, &bp) 
    return bp 
} 

Wreszcie w blogHandler tworzę kawałek na podstawie uzyskanych danych z AppEngine magazynu danych przy użyciu:

blogs := GetBlogs(r, 10) 

Teraz, kiedy mogę wykonać mój szablon o nazwie blog tak, daty blogów są analizowane jako daty domyślnych:

blog.Execute(w, blogs) // gives dates like: 2013-09-03 16:06:48 +0000 UTC 

Tak, mnie, jako n00b Golang że jestem, by powiedzieć, że funkcja jak poniżej dałby mi wynik chcę

blogs[0].Date = blogs[0].Date.Format("02-01-2006 15:04:05") // Would return like 03-09-2013 16:06:48, at least when you print the formatted date that is. 

jednak, że wyniki w konflikt typu oczywiście, co starałem się rozwiązać za pomocą:

blogs[0].Date, _ = time.Parse("02-01-2006 15:04:05", blogs[0].Date.Format("02-01-2006 15:04:05")) // returns once again: 2013-09-03 16:06:48 +0000 UTC 

Jest to prawdopodobnie jedna z rzeczy, którą ponownie nadzorowałem, ale po prostu nie widzę, jak mogę zmienić czas. Czas Wpisz kawałek lub przynajmniej wydrukuj go w żądanym formacie.

+0

Mam wrażenie, że to pytanie ma coś wspólnego z używaniem interfejsu jako argumentu. Wykonaj zamiast tego użycie struktury. Ale nie jest jeszcze w 100% pewne. – Dani

Odpowiedz

29

Twoje pole Date ma typ time.Time. Jeśli sformatujesz go jako ciąg i przeanalizujesz go ponownie, otrzymasz ponownie wartość time.Time, która będzie nadal drukować domyślny sposób, gdy wykonanie szablonu wywoła jego metodę String, więc to naprawdę nie rozwiązuje twojego problemu.

Sposób rozwiązania polega na tym, że szablon zawiera sformatowany ciąg czasu zamiast wartości czasu i można to zrobić na wiele sposobów. Na przykład:

  • Dodaj metodę do swojego bloga po nazwie FormattedDate typu lub podobny, która zwraca ciąg prawidłowo sformatowany w stylu preferencjami. To najprostszy i prawdopodobnie najmilszy sposób, jeśli nie masz ochoty na przypadek.

  • Dodaj pole ciągu do swojego bloga o nazwie FormattedDate lub podobnie; Jest to bardzo podobne do powyższej opcji, ale musisz zachować ostrożność, aby ustawić i zaktualizować pole w razie potrzeby, więc wolałbym zamiast tego opcję metody.

  • Jeśli chcesz formatować wartości czasu na wiele sposobów w ramach szablonu, możesz również zdecydować się na zdefiniowanie funkcji formatyzatora szablonów, dzięki czemu możesz zrobić coś takiego, jak {{post.Date | fdate "02-01-2006 15:04:05"}}. Szczegółowe informacje na ten temat znajdują się w dokumentacji pod numerami Template.Funcs, FuncMap type i this example.

Aktualizacja: Przykładowy kod dla pierwszej opcji: http://play.golang.org/p/3QYdrDQ1YO

+1

Co za odpowiedź. Wspaniale. Dzięki Gustavo – Dani

+0

Nie testujesz swojego przykładu: http://play.golang.org/p/3QYdrDQ1YO z plikami szablonów. Dla plików szablonów powinieneś użyć: 'func (post BlogPost) Formatteddate() string' zamiast ' func (post * BlogPost) FormattedDate() string' – mrLSD

+1

Nie chodzi o bycie plikiem szablonu, czy nie. Jest oczywiście pojedynczy silnik, który interpretuje oba przypadki. Chodzi o to, jak udostępniasz dane szablonowi. Użyj odwołania zamiast wartości. –

4

Jeśli wyprowadzać time.time w szablonie zostanie on przekształcony w ciąg. Ta domyślna konwersja jest widoczna. Jeśli potrzebujesz innego formatu masz dwie realnych możliwościach:

  1. dodać pole `ciąg FormatedDate do blogpost i wypełnić go z Date poprzez Date.Format (cokolwiek)
  2. napisać i zarejestrować filter` formatowania w swojej szablon (patrz http://golang.org/pkg/html/template/#Template.Funcs) i użyj tego.
+1

Odpowiedź Gustavosa jest lepsza. – Volker

+1

To bardzo uczciwe z was, wielkie dzięki! – Dani

36

Chociaż patrząc na podobną funkcjonalność po prostu format i uczynić typ time.Time w html/template, ja przypadkowo odkryli, że Go szablon metody parser pozwala się nazywać pod certain restrictions podczas renderowania typ time.Time.

Na przykład;

type Post struct { 
    Id  int 
    Title  string 
    CreatedOn time.Time 
} 

// post is a &Post. in my case, I fetched that from a postgresql 
// table which has a datetime column for that field and 
// value in db is 2015-04-04 20:51:48 

template.Execute(w, post) 

i jest możliwe, aby wykorzystać ten czas w szablonie jak poniżej:

<span>{{ .CreatedOn }}</span> 
<!-- Outputs: 2015-04-04 20:51:48 +0000 +0000 --> 

<span>{{ .CreatedOn.Format "2006 Jan 02" }}</span> 
<!-- Outputs: 2015 Apr 04 --> 

<span>{{ .CreatedOn.Format "Jan 02, 2006" }}</span> 
<!-- Outputs: Apr 04, 2015 --> 

<span>{{.CreatedOn.Format "Jan 02, 2006 15:04:05 UTC" }}</span> 
<!-- Outputs: Apr 04, 2015 20:51:48 UTC --> 

jako notatkę; moja wersja go jest go1.4.2 darwin/amd64

Mam nadzieję, że pomaga innym.

+0

Super proste! Miły! – Bijan

+0

Świetnie! lorem ipsum – Deleplace

Powiązane problemy