Class: Jekyll::AutoAuthors::AuthorPageGenerator
- Inherits:
-
Generator
- Object
- Generator
- Jekyll::AutoAuthors::AuthorPageGenerator
- Defined in:
- lib/jekyll-auto-authors/main.rb
Overview
The entrypoint for the plugin, auto called by Jekyll based on priorities. :lowest - after all the plugins are done with their thing.
Instance Method Summary collapse
Instance Method Details
#generate(site) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/jekyll-auto-authors/main.rb', line 10 def generate(site) # load the configs for jekyll-paginate-v2. autopage_config = Jekyll::Utils.deep_merge_hashes(PaginateV2::AutoPages::DEFAULT, site.config["autopages"] || {}) pagination_config = Jekyll::Utils.deep_merge_hashes(PaginateV2::Generator::DEFAULT, site.config["pagination"] || {}) # Hack for exclude logic to be used later autopage_config["authors"]["exclude"] ||= [] # load the configs for jekyll-auto-authors (this plugin). = Jekyll::Utils.deep_merge_hashes(DEFAULT, site.config["autopages"]["authors"] || {}) # Do nothing if autopages / author config is disabled. if ( autopage_config["enabled"].nil? || !autopage_config["enabled"] || ["enabled"].nil? || !["enabled"] ) Jekyll.logger.info "Author Pages:", "Disabled / Not configured properly." return end # Lambda that created the author page for a given author. # will be passed to PaginateV2::Autopages for processing. = lambda do | , pagination_config, layout_name, , | # Force skip excluded authors from autopage generation return if ["exclude"].include?() if !["data"].nil? = YAML::load(File.read(["data"]))[] if .nil? Jekyll.logger.warn "Author Pages:", "Author data for '#{}' not found. Page will be generated without data." end end site.pages << AuthorAutoPage.new(site, site.dest, , pagination_config, layout_name, , ) end posts_to_use = [] site.collections.each do |coll_name, coll_data| if !coll_data.nil? # Exclude all pagination pages, as they are not posts. # Then for every page store it"s collection name. posts_to_use += coll_data.docs.select { |doc| !doc.data.has_key?("pagination") }.each{ |doc| doc.data["__coll"] = coll_name } end end # Pass the config to PaginateV2::AutoPages for processing. # autopage_create() indexes the posts into hashes by author (5th parameter here). # then checkes if configs are enabled and if so, calls the lambda to generate the author page. PaginateV2::AutoPages.autopage_create( autopage_config, pagination_config, posts_to_use, "authors", "author", ) # Set of authors for whom autopages have been created finished_pages = Set.new posts_to_use.each do | post | next if post.data["author"].nil? || finished_pages.include?(post.data["author"]) finished_pages << post.data["author"] end if !["data"].nil? # if a data file containing authors is not nil, then iterate through the specified # authors to build author pages for them, even if they don't have posts yet. = YAML::load(File.read(["data"])) .each do | , data | # The exclude attribute ignores authors from autopage generation unless they have a post assigned. if !finished_pages.include?() and !data["exclude"] # create pages for pending authors with specified layouts ['layouts'].each do | layout_name | .call(, pagination_config, layout_name, , ) end finished_pages << end end end # Now auto pages for authors have been created, we can generate the pagination logic. # Further logic is mostly similar as PaginateV2::Generator::PaginationModel#paginate(), but we need # to override the default pagination logic to include author pages too, so it isn"t called directly. # Generate lambda for adding/deleting pages to the site. page_add_lambda = lambda do | newpage | site.pages << newpage return newpage end page_remove_lambda = lambda do | page_to_remove | site.pages.delete_if {|page| page == page_to_remove } end # Logs formatted messages, defined similar to the one in PaginateV2::Generator::PaginationModel. logging_lambda = lambda do | , type = "info" | if type == "debug" Jekyll.logger.debug "Author Pages:","#{}" elsif type == "error" Jekyll.logger.error "Author Pages:", "#{}" elsif type == "warn" Jekyll.logger.warn "Author Pages:", "#{}" else Jekyll.logger.info "Author Pages:", "#{}" end end # Create an instance of pagination model. We will use some functions from this instance while # defining some logic of our own, for overriding the default pagination to include author pages too. pagination_model = Jekyll::PaginateV2::Generator::PaginationModel.new( logging_lambda, page_add_lambda, page_remove_lambda, nil ) # get posts which have pagination enabled. Ignore hidden posts. all_posts = site.collections["posts"].docs.select { |doc| !doc.data.has_key?("pagination") } all_posts = all_posts.reject { |doc| doc["hidden"] } # The Indexer is responsible for generating the hash for posts indexed by by author. # The structure is: {"author1" => {<posts>}, "author2" => {<posts>}, ...} = Jekyll::PaginateV2::Generator::PaginationIndexer.index_posts_by(all_posts, "author") # This gets all the pages where pagination is enabled. This also includes Autopages too, # as pagination data is assigned to them while generation (PaginateV2::AutoPages::BaseAutoPage line 45). templates = pagination_model.discover_paginate_templates(site.pages) templates.each do |template| if template.data["pagination"].is_a?(Hash) # For each template get the config, skip if paginatio is disabled, or it"s not an author page. config = Jekyll::Utils.deep_merge_hashes(pagination_config, template.data["pagination"] || {}) next if !config["enabled"] next if template.data["pagination"]["author"].nil? # Filter posts with bad configs. pagination_posts = PaginateV2::Generator::PaginationIndexer.read_config_value_and_filter_posts( config, "author", all_posts, ) # Apply sorting to the posts if configured, any field for the post is available for sorting. if config["sort_field"] sort_field = config["sort_field"].to_s pagination_posts.each do |post| if post.respond_to?("date") tmp_date = post.date if( !tmp_date || tmp_date.nil? ) post.date = File.mtime(post.path) end end end pagination_posts.sort!{ |a,b| PaginateV2::Generator::Utils.sort_values( PaginateV2::Generator::Utils.sort_get_post_data(a.data, sort_field), PaginateV2::Generator::Utils.sort_get_post_data(b.data, sort_field) ) } # Remove the first x entries. Defined by "offset" in the config. offset_post_count = [0, config["offset"].to_i].max pagination_posts.pop(offset_post_count) if config["sort_reverse"] pagination_posts.reverse! end end # Calculate number of total pages. total_pages = (pagination_posts.size.to_f / config["per_page"].to_i).ceil # If a upper limit is set on the number of total pagination pages then impose that now. if config["limit"] && config["limit"].to_i > 0 && config["limit"].to_i < total_pages total_pages = config["limit"].to_i end # Remove the template page from the site, index pages will be generated in the next steps. page_remove_lambda.call(template) # Store List of all newly created pages, used in creating pagination trails later. newpages = [] # Consider the default index page name and extension. indexPageName = config["indexpage"].nil? ? "" : config["indexpage"].split(".")[0] indexPageExt = config["extension"].nil? ? "" : Jekyll::PaginateV2::Generator::Utils.ensure_leading_dot(config["extension"]) indexPageWithExt = indexPageName + indexPageExt total_pages = 1 if total_pages.zero? (1..total_pages).each do |cur_page_nr| # Create a new page for each page number. newpage = Jekyll::PaginateV2::Generator::PaginationPage.new( template, cur_page_nr, total_pages, indexPageWithExt ) # Create the permalink for the in-memory page, construct title, set all page.data values needed. paginated_page_url = config["permalink"] first_index_page_url = "" if template.data["permalink"] first_index_page_url = Jekyll::PaginateV2::Generator::Utils.ensure_trailing_slash(template.data["permalink"]) else first_index_page_url = Jekyll::PaginateV2::Generator::Utils.ensure_trailing_slash(template.dir) end paginated_page_url = File.join(first_index_page_url, paginated_page_url) # Create the pager logic for this page, pass in the prev and next page numbers, assign pager to in-memory page. newpage.pager = PaginateV2::Generator::Paginator.new( config["per_page"], first_index_page_url, paginated_page_url, pagination_posts, cur_page_nr, total_pages, indexPageName, indexPageExt) # Create the url for the new page, make sure to prepend any permalinks that are defined in the template page before. if newpage.pager.page_path.end_with? "/" newpage.set_url(File.join(newpage.pager.page_path, indexPageWithExt)) elsif newpage.pager.page_path.end_with? indexPageExt # Support for direct .html files. newpage.set_url(newpage.pager.page_path) else # Support for extensionless permalinks. newpage.set_url(newpage.pager.page_path + indexPageExt) end if( template.data["permalink"] ) newpage.data["permalink"] = newpage.pager.page_path end # Transfer the title across to the new page. if( !template.data["title"] ) tmp_title = site.title else tmp_title = template.data["title"] end # If the user specified a title suffix to be added then add that to all the pages except the first. if( cur_page_nr > 1 && config.has_key?("title") ) newpage.data["title"] = "#{Jekyll::PaginateV2::Generator::Utils.format_page_title(config["title"], tmp_title, cur_page_nr, total_pages)}" else newpage.data["title"] = tmp_title end # Signals that this page is automatically generated by the pagination logic. # We don"t do this for the first page as it is there to mask the one we removed. if cur_page_nr > 1 newpage.data["autogen"] = "jekyll-paginate-v2" end # Add the page to the site. page_add_lambda.call( newpage ) # Store the page to the internal list. newpages << newpage end # Now generate the pagination number path, so that the users can have a prev 1 2 3 4 5 next structure on their page # simplest is to include all of the links to the pages preceeding the current one # (e.g for page 1 you get the list 2, 3, 4.... and for page 2 you get the list 3,4,5...) if( config["trail"] && !config["trail"].nil? && newpages.size.to_i > 1 ) trail_before = [config["trail"]["before"].to_i, 0].max trail_after = [config["trail"]["after"].to_i, 0].max trail_length = trail_before + trail_after + 1 if( trail_before > 0 || trail_after > 0 ) newpages.select do | npage | idx_start = [ npage.pager.page - trail_before - 1, 0].max # Selecting the beginning of the trail idx_end = [idx_start + trail_length, newpages.size.to_i].min # Selecting the end of the trail # Always attempt to maintain the max total of <trail_length> pages in the trail (it will look better if the trail doesn"t shrink). if( idx_end - idx_start < trail_length ) # Attempt to pad the beginning if we have enough pages. idx_start = [idx_start - ( trail_length - (idx_end - idx_start) ), 0].max # Never go beyond the zero index. end # Convert the newpages array into a two dimensional array that has [index, page_url] as items. npage.pager.page_trail = newpages[idx_start...idx_end].each_with_index.map {|ipage,idx| Jekyll::PaginateV2::Generator::PageTrail.new(idx_start+idx+1, ipage.pager.page_path, ipage.data["title"])} end end end end end Jekyll.logger.info "Author Pages:", "Generated autopages for #{finished_pages.size} author(s)" end |