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));
}
}