Skip to content

Show the title of each example on its page - #1603

Open
reiern70 wants to merge 1 commit into
masterfrom
reiern70/improve-examples
Open

reiern70 wants to merge 1 commit into
masterfrom
reiern70/improve-examples

Conversation

@reiern70

Copy link
Copy Markdown
Contributor

Example pages linked from an index gave no hint of which example they showed: the link text was not repeated on the page, and the browser title was a generic, often stale, per-application string.

WicketExamplePage now renders the example's title as a heading and as the browser title. The title is read from the resource key .title, kept in a wicket-package.properties per example application, and index pages use the same keys for their link texts. The hard-coded <title> tags and headings duplicating the new title are removed from the example markup, and a test checks that every example page has a title.

Example pages linked from an index gave no hint of which example they
showed: the link text was not repeated on the page, and the browser
title was a generic, often stale, per-application string.

WicketExamplePage now renders the example's title as a heading and as
the browser title. The title is read from the resource key
<simple class name>.title, kept in a wicket-package.properties per
example application, and index pages use the same keys for their link
texts. The hard-coded <title> tags and headings duplicating the new
title are removed from the example markup, and a test checks that every
example page has a title.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.87%. Comparing base (86c1b78) to head (0b061d4).

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1603      +/-   ##
============================================
- Coverage     61.88%   61.87%   -0.01%     
+ Complexity    11231    11229       -2     
============================================
  Files          1247     1247              
  Lines         48338    48338              
  Branches       6783     6783              
============================================
- Hits          29913    29911       -2     
- Misses        15717    15718       +1     
- Partials       2708     2709       +1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@reiern70

Copy link
Copy Markdown
Contributor Author

I see this in the logs

2026-09-16 07:28:37.024 [qtp1681595665-51] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/index.html","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-xywDZUd-dnTby0S6XfkguL6h'; style-src 'nonce-xywDZUd-dnTby0S6XfkguL6h' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}
2026-09-16 07:28:41.636 [qtp1681595665-76] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/helloworld/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/helloworld/?0","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-3ql9L9LT-ghmHp11t8FTKwSh'; style-src 'nonce-3ql9L9LT-ghmHp11t8FTKwSh' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"http://192.168.0.152:8080/index.html","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}
2026-09-16 07:28:44.482 [qtp1681595665-48] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/index.html","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-5nn64NVJtiurMsKaHTK1YiGD'; style-src 'nonce-5nn64NVJtiurMsKaHTK1YiGD' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}
2026-09-16 07:28:47.256 [qtp1681595665-49] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/echo/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/echo/?0","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-SaT_xlj-6v6LjzERRyBHAyZp'; style-src 'nonce-SaT_xlj-6v6LjzERRyBHAyZp' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"http://192.168.0.152:8080/index.html","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}
2026-09-16 07:28:49.966 [qtp1681595665-51] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/index.html","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-2wGvzZSn68PvYQymzhZjB8mZ'; style-src 'nonce-2wGvzZSn68PvYQymzhZjB8mZ' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}
2026-09-16 07:28:56.932 [qtp1681595665-85] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/ajax/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/ajax/?0","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-aiRrJs3tGemBVppYsbivoooG'; style-src 'nonce-aiRrJs3tGemBVppYsbivoooG' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"http://192.168.0.152:8080/index.html","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}
2026-09-16 07:28:59.872 [qtp1681595665-53] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/ajax/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/ajax/autocomplete?1","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-0y8fqRIbSegDUvtsmHkzVy1T'; style-src 'nonce-0y8fqRIbSegDUvtsmHkzVy1T' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"http://192.168.0.152:8080/ajax/?0","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}
2026-09-16 07:29:06.719 [qtp1681595665-85] ERROR org.apache.wicket.csp.ReportCSPViolationMapper - {"csp-report":{"blocked-uri":"http://192.168.0.152:8080/ajax/wicket/resource/org.apache.wicket.examples.WicketExamplePage/style-ver-1789560316135.css","column-number":15,"disposition":"enforce","document-uri":"http://192.168.0.152:8080/ajax/?0","effective-directive":"style-src-elem","line-number":142,"original-policy":"default-src 'none'; script-src 'strict-dynamic' 'nonce-aiRrJs3tGemBVppYsbivoooG'; style-src 'nonce-aiRrJs3tGemBVppYsbivoooG' https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css; img-src 'self'; connect-src 'self'; font-src 'self' https://maxcdn.bootstrapcdn.com; manifest-src 'self'; child-src 'self'; base-uri 'self'; frame-src 'self'; report-uri http://192.168.0.152:8080/cspviolation","referrer":"http://192.168.0.152:8080/index.html","source-file":"resource","status-code":200,"violated-directive":"style-src-elem"}}

expected?

@solomax

solomax commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Hello @reiern70

There seems to be different logic for each Index.java page :(
Maybe it worth to be unified?

In such case I would propose to list package classes dynamically instead of hardcoding them into static list

with the code like this in the BasePage.java:

protected static List<Class<? extends BasePage>> getPackageClasses(Class<? extends BasePage> clazz) {
		Set<Class<? extends BasePage>> classes = new HashSet<>();
		final String packageName = clazz.getPackageName();
		try {
			Enumeration<URL> resources = clazz.getClassLoader().getResources(packageName.replace('.', '/'));
			while (resources.hasMoreElements()) {
				classes.addAll(findClasses(new File(resources.nextElement().getFile()), packageName));
			}
		} catch (Exception e) {
			// no-op
		}
		classes.remove(clazz);
		return List.copyOf(classes);
	}

	@SuppressWarnings("unchecked")
	private static Set<Class<? extends BasePage>> findClasses(File base, String packageName) {
		Set<Class<? extends BasePage>> classes = new HashSet<>();
		if (!base.exists()) {
			return Set.of();
		}
		File[] files = base.listFiles();
		if (files == null) {
			return Set.of();
		}
		for (File f : files) {
			if (f.isDirectory()) {
				classes.addAll(findClasses(f, packageName + "." + f.getName()));
			} else {
				try {
					final String name  = f.getName();
					Class<?> pClazz = Class.forName(packageName + "." + name.substring(0, name.lastIndexOf('.')));
					if (BasePage.class.isAssignableFrom(pClazz)) {
						classes.add((Class<? extends BasePage>)pClazz);
					}
				} catch (ClassNotFoundException e) {
					// no-op
				}
			}
		}
		return classes;
	}

this way examples can be "just added" without maintaining various lists :)

@reiern70

Copy link
Copy Markdown
Contributor Author

Hello @reiern70

There seems to be different logic for each Index.java page :( Maybe it worth to be unified?

In such case I would propose to list package classes dynamically instead of hardcoding them into static list

with the code like this in the BasePage.java:

protected static List<Class<? extends BasePage>> getPackageClasses(Class<? extends BasePage> clazz) {
		Set<Class<? extends BasePage>> classes = new HashSet<>();
		final String packageName = clazz.getPackageName();
		try {
			Enumeration<URL> resources = clazz.getClassLoader().getResources(packageName.replace('.', '/'));
			while (resources.hasMoreElements()) {
				classes.addAll(findClasses(new File(resources.nextElement().getFile()), packageName));
			}
		} catch (Exception e) {
			// no-op
		}
		classes.remove(clazz);
		return List.copyOf(classes);
	}

	@SuppressWarnings("unchecked")
	private static Set<Class<? extends BasePage>> findClasses(File base, String packageName) {
		Set<Class<? extends BasePage>> classes = new HashSet<>();
		if (!base.exists()) {
			return Set.of();
		}
		File[] files = base.listFiles();
		if (files == null) {
			return Set.of();
		}
		for (File f : files) {
			if (f.isDirectory()) {
				classes.addAll(findClasses(f, packageName + "." + f.getName()));
			} else {
				try {
					final String name  = f.getName();
					Class<?> pClazz = Class.forName(packageName + "." + name.substring(0, name.lastIndexOf('.')));
					if (BasePage.class.isAssignableFrom(pClazz)) {
						classes.add((Class<? extends BasePage>)pClazz);
					}
				} catch (ClassNotFoundException e) {
					// no-op
				}
			}
		}
		return classes;
	}

this way examples can be "just added" without maintaining various lists :)

Very good idea. I will do so. Thanks for feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants