diff --git a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr_.java b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr_.java index aaa5d48e2..763f87304 100644 --- a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr_.java +++ b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr_.java @@ -19,7 +19,7 @@ import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.pages.*; import gplx.xowa.w import gplx.xowa.parsers.utils.*; public class Xoh_page_wtr_wkr_ { public static byte[] Bld_page_content_sub(Xoae_app app, Xowe_wiki wiki, Xoae_page page, Bry_bfr tmp_bfr) { - byte[] subpages = app.Html_mgr().Page_mgr().Subpages_bldr().Bld(wiki.Ns_mgr(), page.Ttl()); + byte[] subpages = app.Html_mgr().Page_mgr().Subpages_bldr().Bld(wiki, page.Ttl()); byte[] page_content_sub = page.Html_data().Content_sub(); // contentSub exists; SEE: {{#isin}} byte[] redirect_msg = Xop_redirect_mgr.Bld_redirect_msg(app, wiki, page.Redirect_trail()); return Bry_.Add(subpages, page_content_sub, redirect_msg); diff --git a/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr.java b/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr.java index 387f64369..bcfef895b 100644 --- a/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr.java +++ b/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr.java @@ -18,50 +18,74 @@ import gplx.core.brys.fmtrs.*; import gplx.xowa.htmls.hrefs.*; import gplx.xowa.wikis.nss.*; public class Xoh_subpages_bldr implements gplx.core.brys.Bfr_arg { - private Bry_bfr tmp_bfr = Bry_bfr_.Reset(255), ttl_bfr = Bry_bfr_.Reset(255); + private final Bry_bfr html_bfr = Bry_bfr_.Reset(255), path_bfr = Bry_bfr_.Reset(255); + private Xowe_wiki wiki; private byte[][] segs; - public byte[] Bld(Xow_ns_mgr ns_mgr, Xoa_ttl ttl) { + public byte[] Bld(Xowe_wiki wiki, Xoa_ttl ttl) { + // check if subpages is valid + Xow_ns_mgr ns_mgr = wiki.Ns_mgr(); Xow_ns ns = ttl.Ns(); if (! ( ns.Subpages_enabled() // ns has subpages - && ttl.Leaf_bgn() != Bry_find_.Not_found // ttl has leaf text; EX: Help:A/B && ns.Id() != ns_mgr.Ns_page_id() // ns is not [[Page:]]; PAGE:en.s:Notes_on_Osteology_of_Baptanodon._With_a_Description_of_a_New_Species DATE:2014-09-06 + && ttl.Leaf_bgn() != Bry_find_.Not_found // ttl has leaf text; EX: Help:A/B ) - ) return Bry_.Empty; // doesn't match above; return empty; + ) + return Bry_.Empty; // doesn't match above; return empty; + + // split ttl by slashes; EX: "Help:A/B/C" -> "Help:A", "B", "C" byte[] raw = ttl.Raw(); this.segs = Bry_split_.Split(raw, Byte_ascii.Slash); - fmtr_grp.Bld_bfr(tmp_bfr, this); - return tmp_bfr.To_bry_and_clear(); + + // build html + this.wiki = wiki; + fmtr_grp.Bld_bfr(html_bfr, this); + return html_bfr.To_bry_and_clear(); } public void Bfr_arg__add(Bry_bfr bfr) { - int segs_len = segs.length - 1; // last seg is current page; do not print - for (int i = 0; i < segs_len; ++i) { - byte[] dlm = null; - if (i == 0) - dlm = Dlm_1st; - else { - dlm = Dlm_nth; - ttl_bfr.Add_byte_slash(); + int segs_len = segs.length - 1; // skip last seg which is current page and should not be printed + + byte[] delimiter = Delimiter__1st; + for (int i = 0; i < segs_len; i++) { + // if not first, change delimiter and add "/" to path bfr + if (i != 0) { + delimiter = Delimiter__nth; + path_bfr.Add_byte_slash(); } - byte[] seg = segs[i]; - ttl_bfr.Add(seg); - byte[] seg_ttl = ttl_bfr.To_bry(); - byte[] seg_ttl_enc = gplx.langs.htmls.encoders.Gfo_url_encoder_.Href.Encode(ttl_bfr.To_bry()); - byte[] href = Bry_.Add(Xoh_href_.Bry__wiki, seg_ttl_enc); // EX: /wiki/Help:A - fmtr_itm.Bld_bfr(bfr, dlm, href - // NOTE: convert underscore to space; ISSUE#:308 PAGE:en.v:Computer-aided_design/Software DATE:2018-12-23 - , Xoa_ttl.Replace_unders(seg_ttl) - , Xoa_ttl.Replace_unders(seg)); + + // get seg and add to path + byte[] seg = segs[i]; // EX: "B" + path_bfr.Add(seg); // EX: "Help:A/" + "B" -> "Help:A/B" + + // build subpage_ttl + byte[] subpage_ttl_bry = path_bfr.To_bry(); + Xoa_ttl subpage_ttl = wiki.Ttl_parse(subpage_ttl_bry); + + // re-define subpage_ttl_bry to properly-case title elements; EX: "help:a/b" -> "Help:A/b" + subpage_ttl_bry = subpage_ttl.Full_txt_w_ttl_case(); + + // if page is missing, skip it; ISSUE#:626; DATE:2019-12-01 + if (!wiki.Parser_mgr().Ifexist_mgr().Exists(wiki, subpage_ttl_bry)) continue; + + // get subpage_caption; note that 1st seg is Full_url ("Help:A"), but nth is just leaf ("b", not "Help:A/b") + byte[] subpage_caption = (i == 0) ? subpage_ttl.Full_url() : subpage_ttl.Leaf_url(); + + // add to subpage trail + // NOTE: convert underscore to space; ISSUE#:308 PAGE:en.v:Computer-aided_design/Software DATE:2018-12-23 + fmtr_itm.Bld_bfr(bfr, delimiter + , Bry_.Add(Xoh_href_.Bry__wiki, subpage_ttl.Full_url()) // EX: /wiki/Help:A + , Xoa_ttl.Replace_unders(subpage_ttl_bry) + , Xoa_ttl.Replace_unders(subpage_caption)); } - ttl_bfr.Clear(); + path_bfr.Clear(); } - private static final byte[] Dlm_1st = Bry_.new_a7("< "), Dlm_nth = Bry_.new_a7("‎ | "); + private static final byte[] Delimiter__1st = Bry_.new_a7("< "), Delimiter__nth = Bry_.new_a7("‎ | "); private static final Bry_fmtr fmtr_grp = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last ( "~{itms}" , "" ), "itms") , fmtr_itm = Bry_fmtr.new_ - ( "~{dlm}~{caption}" - , "dlm", "href", "title", "caption") + ( "~{delimiter}~{caption}" + , "delimiter", "href", "title", "caption") ; } \ No newline at end of file diff --git a/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr_tst.java b/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr_tst.java index 25c3d1159..f8344346c 100644 --- a/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr_tst.java +++ b/400_xowa/src/gplx/xowa/htmls/portal/Xoh_subpages_bldr_tst.java @@ -16,36 +16,68 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt package gplx.xowa.htmls.portal; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import org.junit.*; import gplx.xowa.wikis.nss.*; public class Xoh_subpages_bldr_tst { - @Before public void init() {fxt.Init();} private Xoh_subpages_bldr_fxt fxt = new Xoh_subpages_bldr_fxt(); + private Xoh_subpages_bldr_fxt fxt; + @Before public void init() {fxt = new Xoh_subpages_bldr_fxt();} @Test public void Basic() { - fxt.Test_bld("Help:A/B/C", String_.Concat_lines_nl_skip_last + fxt.Init__Create_pages("Help:A", "Help:A/B"); + fxt.Test__Parse("Help:A/B/C", String_.Concat_lines_nl_skip_last ( "< Help:A‎ | B" , "" )); } @Test public void Underscore_space() {// PURPOSE: convert underscore to space; ISSUE#:308 PAGE:en.v:Computer-aided_design/Software DATE:2018-12-23 - fxt.Test_bld("Help:A_1/B_1/C_1", String_.Concat_lines_nl_skip_last + fxt.Init__Create_pages("Help:A_1", "Help:A_1/B_1"); + fxt.Test__Parse("Help:A_1/B_1/C_1", String_.Concat_lines_nl_skip_last ( "< Help:A 1‎ | B 1" , "" )); } - @Test public void Skip_page() { - fxt.Wiki().Ns_mgr().Add_new(104, "Page"); - fxt.Wiki().Ns_mgr().Ns_page_id_(104); - fxt.Test_bld("Page:A/B/C", ""); + @Test public void Skip_page_ns() { + fxt.Init__Page_ns(); + fxt.Test__Parse("Page:A/B/C", ""); + } + @Test public void Missing_pages() { // PURPOSE: missing pages should not show up in subpages; ISSUE#:626; DATE:2019-12-01 + fxt.Init__Create_pages("Help:A", "Help:A/B/C"); // NOTE: "Help:A/B" is missing + fxt.Test__Parse("Help:A/B/C/D", String_.Concat_lines_nl_skip_last + ( "< Help:A‎ | C" + , "" + )); + } + @Test public void Title_case_segments() { // PURPOSE: make sure ns and page_ttl is properly-cased; ISSUE#:626; DATE:2019-12-01 + fxt.Init__Create_pages("Help:A", "Help:A/b"); + + /* + For "help:a/b" + * Upper-case to "Help" b/c namespaces are upper-cased + * Upper-case to "A" b/c Help ns automatically upper-cases all titles ("a/b" -> "A/b") + * Skip "b" b/c path segments are not cased ("A/b" should not be "A/B") + */ + fxt.Test__Parse("help:a/b/c", String_.Concat_lines_nl_skip_last + ( "< Help:A‎ | b" + , "" + )); } } class Xoh_subpages_bldr_fxt { - private Xoae_app app; - private Xoh_subpages_bldr subpages_bldr = new Xoh_subpages_bldr(); - public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki; - public void Init() { + private final Xoae_app app; + private final Xowe_wiki wiki; + private final Xoh_subpages_bldr subpages_bldr = new Xoh_subpages_bldr(); + public Xoh_subpages_bldr_fxt() { this.app = Xoa_app_fxt.Make__app__edit(); this.wiki = Xoa_app_fxt.Make__wiki__edit(app); wiki.Ns_mgr().Ids_get_or_null(Xow_ns_.Tid__help).Subpages_enabled_(true); } - public void Test_bld(String ttl_str, String expd) { - byte[] actl = subpages_bldr.Bld(wiki.Ns_mgr(), Xoa_ttl.Parse(wiki, Bry_.new_u8(ttl_str))); + public void Init__Page_ns() { + wiki.Ns_mgr().Add_new(104, "Page"); + wiki.Ns_mgr().Ns_page_id_(104); + } + public void Init__Create_pages(String... pages) { + for (String page : pages) { + Xop_fxt.Init_page_create_static(wiki, page, page); + } + } + public void Test__Parse(String ttl_str, String expd) { + byte[] actl = subpages_bldr.Bld(wiki, Xoa_ttl.Parse(wiki, Bry_.new_u8(ttl_str))); Tfds.Eq_str_lines(expd, String_.new_u8(actl)); } }