Beispiel #1
0
func reverseAppsArticle(a *app.App, art interface{}, checked map[*app.App]bool) (string, error) {
	checked[a] = true
	var articles []*article.Article
	aa, _ := reusableapp.AppData(a).(*appData)
	if aa != nil {
		articles = aa.Articles
	}
	switch x := art.(type) {
	case string:
		for _, v := range articles {
			if articleId(v) == x {
				return a.Reverse(ArticleHandlerName, v.Slug())
			}
		}
	case *article.Article:
		return a.Reverse(ArticleHandlerName, x.Slug())
	case article.Article:
		return a.Reverse(ArticleHandlerName, x.Slug())
	}
	if p := a.Parent(); p != nil && !checked[p] {
		return reverseAppsArticle(p, art, checked)
	}
	for _, v := range a.Included() {
		if checked[v] {
			continue
		}
		if url, err := reverseAppsArticle(v, art, checked); err == nil {
			return url, nil
		}
	}
	if id, ok := art.(string); ok {
		return "", fmt.Errorf("no article with id %q found", id)
	}
	return "", fmt.Errorf("can't reverse Article from %T, must be *Article or string (article id)", art)
}
Beispiel #2
0
// AppDataWithKey works similarly to AppData, but uses the provided key instead.
// Also, if the data is not found in the *app.App passed in as the first argument,
// its children apps are also searched. This allows reusable apps to retrieve their
// additional data in contexts where the reusable app pointer is not available.
// (e.g. in template plugins which are called from the parent app). See gnd.la/apps/users
// for an example of this usage.
func AppDataWithKey(a *app.App, key interface{}) interface{} {
	ra, _ := a.Get(key).(*App)
	if ra != nil {
		return ra.Data()
	}
	if key != reusableAppKey {
		for _, ia := range a.Included() {
			if data := AppDataWithKey(ia, key); data != nil {
				return data
			}
		}
	}
	return nil
}