66 lines
2.3 KiB
Ruby
66 lines
2.3 KiB
Ruby
module PortalHomeData
|
|
extend ActiveSupport::Concern
|
|
|
|
private
|
|
|
|
def load_home_data
|
|
load_recommended_content
|
|
# The classic hero only needs the recommendations above; the rest is
|
|
# documentation-layout home data (also used on custom-domain home pages).
|
|
return unless @portal.layout == 'documentation'
|
|
|
|
@visible_categories = @portal.categories
|
|
.where(locale: @locale)
|
|
.joins(:articles).where(articles: { status: :published })
|
|
.order(position: :asc)
|
|
.group('categories.id')
|
|
@popular_topics = @recommended_categories.presence || @visible_categories.first(3)
|
|
@featured = base_articles.order_by_views.limit(6)
|
|
@category_contributors = build_category_contributors(@visible_categories)
|
|
end
|
|
|
|
def load_recommended_content
|
|
@recommended_categories = recommended_categories
|
|
@recommended_articles = recommended_articles
|
|
end
|
|
|
|
def base_articles
|
|
@base_articles ||= @portal.articles.published.where(locale: @locale).includes(:author, :category)
|
|
end
|
|
|
|
# Admin-recommended categories for the locale, in the chosen order. Unlike the
|
|
# position-based fallback, published articles aren't required: the admin's pick wins.
|
|
def recommended_categories
|
|
ids = @portal.popular_category_ids(@locale)
|
|
ordered_by_ids(@portal.categories.where(locale: @locale, id: ids), ids)
|
|
end
|
|
|
|
# Admin-recommended articles for the locale, in the chosen order, limited to
|
|
# published articles that still exist.
|
|
def recommended_articles
|
|
ids = @portal.popular_article_ids(@locale)
|
|
ordered_by_ids(base_articles.where(id: ids), ids)
|
|
end
|
|
|
|
# Loads the scope and returns its records ordered to match `ids`, dropping any
|
|
# that no longer exist. Skips the query entirely when `ids` is blank.
|
|
def ordered_by_ids(scope, ids)
|
|
return [] if ids.blank?
|
|
|
|
by_id = scope.index_by(&:id)
|
|
ids.filter_map { |id| by_id[id] }
|
|
end
|
|
|
|
def build_category_contributors(categories)
|
|
category_ids = categories.map(&:id)
|
|
return {} if category_ids.empty?
|
|
|
|
@portal.articles
|
|
.published
|
|
.where(locale: @locale, category_id: category_ids)
|
|
.includes(:author)
|
|
.group_by(&:category_id)
|
|
.transform_values { |articles| articles.filter_map(&:author).uniq.first(3) }
|
|
end
|
|
end
|