Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
043cb02
feat: revamped /blog page
immortalcodes Jun 4, 2026
ca6c4bb
lint: formatted scss and js files
immortalcodes Jun 4, 2026
333007a
feat: article update
Skazitron Jun 5, 2026
64fb0e4
fix: update number of blogs rednered to 4
Skazitron Jun 5, 2026
97c3741
fix: addressed pagination on smaller screens
immortalcodes Jun 5, 2026
aab8b3e
fix: quotes rendering in strange way
Skazitron Jun 5, 2026
b476015
fix: update newsletter
Skazitron Jun 8, 2026
77ee78b
fix: update fallback image source and increase description length in …
immortalcodes Jun 9, 2026
a9cef8b
Merge pull request #2585 from canonical/WD-33184-dev-update-c-com-blog
immortalcodes Jun 9, 2026
2c8f19a
refactor: improve structure and formatting of tag page template
immortalcodes Jun 8, 2026
785a32e
fix: UX review
immortalcodes Jun 10, 2026
f7b6a4b
refactor: update author page template to use vf_hero macro and stream…
immortalcodes Jun 11, 2026
bf23ad6
Merge pull request #2596 from canonical/WD-36718-dev-canonical-com-up…
immortalcodes Jun 11, 2026
fb25575
refactor: hide author image for "canonical"
immortalcodes Jun 15, 2026
9c0260c
refactor: canonical author handling
immortalcodes Jun 15, 2026
aab5197
Merge pull request #2604 from canonical/WD-36719-dev-canonical-com-up…
immortalcodes Jun 16, 2026
0cf929f
fix: update blog article
Skazitron Jun 16, 2026
ab5e147
fix: update blog article
Skazitron Jun 18, 2026
5f35bb5
Merge branch 'main' into blog-article-update
Skazitron Jun 18, 2026
76db703
fix: update blog api
Skazitron Jun 19, 2026
a09eec8
fix: update blog style
Skazitron Jun 19, 2026
3faf289
Merge branch 'feature-blog' into blog-article-update
Skazitron Jun 19, 2026
cfc11fc
fix: youtube embed hugs screen
Skazitron Jun 19, 2026
5c087b0
fix: minor changes
Skazitron Jun 19, 2026
80279e2
Revert "fix: minor changes"
Skazitron Jun 19, 2026
693f30d
Revert "Merge branch 'feature-blog' into blog-article-update"
Skazitron Jun 19, 2026
7635a83
fix: minor changes
Skazitron Jun 19, 2026
af5c9e1
WIP: rebrand /blog/latest-news
Ataku-B Jun 4, 2026
fc5780c
fix: change /blog/latest-news heading to display heading
Ataku-B Jun 4, 2026
69ff836
fix: revert latest-news view to use common blog view
Ataku-B Jun 9, 2026
947a3bd
fix: use common blog-card to avoid duplicate code
Ataku-B Jun 10, 2026
93db34a
feat: bump vanilla version and add 8 col card to /blog/latest-news
Ataku-B Jun 15, 2026
bf9a28f
feat: revamped /blog page
immortalcodes Jun 4, 2026
eeb8fed
lint: formatted scss and js files
immortalcodes Jun 4, 2026
d34167f
fix: addressed pagination on smaller screens
immortalcodes Jun 5, 2026
40e03b6
fix: update fallback image source and increase description length in …
immortalcodes Jun 9, 2026
d08a2d6
refactor: improve structure and formatting of tag page template
immortalcodes Jun 8, 2026
71059c0
fix: UX review
immortalcodes Jun 10, 2026
4412b89
refactor: update author page template to use vf_hero macro and stream…
immortalcodes Jun 11, 2026
1541da4
refactor: hide author image for "canonical"
immortalcodes Jun 15, 2026
dfdc89a
refactor: canonical author handling
immortalcodes Jun 15, 2026
f68cf5b
fix: UX review comments
Ataku-B Jun 17, 2026
935f344
fix: restore case-study pagination
Ataku-B Jun 17, 2026
a05c04d
remove redundant /press-center -> /blog/latest-news redirect
Ataku-B Jun 17, 2026
fb8aa76
Add deep padding below pagination in /blog/latest-news
Ataku-B Jun 17, 2026
a047b34
Add alt attributes to images in /blog/latest-news
Ataku-B Jun 18, 2026
82b7e7b
Apply review suggestions
Ataku-B Jun 18, 2026
5f9ffd0
lint python
Ataku-B Jun 18, 2026
44afafb
lint jinja
Ataku-B Jun 18, 2026
0641b6b
test coverage for /blog/latest-news
Ataku-B Jun 18, 2026
1723c1f
lint python
Ataku-B Jun 18, 2026
d836c16
Add tests for blog latest news page with and without page query param…
Ataku-B Jun 19, 2026
1ddedb7
lint python
Ataku-B Jun 19, 2026
f9ff5ea
Merge branch 'feature-blog' into blog-article-update
Skazitron Jun 25, 2026
f69c9e4
fix: restore missing _pattern_blog-card.scss to unbreak scss build
Skazitron Jun 25, 2026
b2bc716
fix: minor changes
Skazitron Jun 25, 2026
2f8459a
fix: added comment
Skazitron Jun 25, 2026
5a6972f
Merge pull request #2592 from canonical/blog-article-update
Skazitron Jun 25, 2026
509f8c7
feat: add product cards
Skazitron Jun 26, 2026
c4d9305
fix: addressed comments
Skazitron Jun 26, 2026
a58af35
fix: make arrow into css
Skazitron Jun 26, 2026
9865988
fix: addressed comments
Skazitron Jun 26, 2026
6eea8f7
fix: addressed comments
Skazitron Jun 26, 2026
17e803e
fix: linting errors
Skazitron Jun 26, 2026
95132b4
fix: linting errors
Skazitron Jun 26, 2026
95e8bff
fix: prettier and djlint fix
Skazitron Jun 26, 2026
32e534e
Merge pull request #2694 from canonical/product-cards
Skazitron Jun 26, 2026
fdb4c30
chore: use categories to display blogs instead of tags (#2708)
Onibenjo Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
- name: Install python dependencies
run: |
python3 -m pip install --upgrade pip
sudo pip3 install djlint
sudo pip3 install "$(grep -m1 -E '^djlint==' requirements.txt)" "click>=8.1"

- name: Get changed HTML files in the templates folder
id: changed-files
Expand Down
4 changes: 2 additions & 2 deletions navigation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,8 @@ company:
links:
- title: Blog
url: /blog
- title: Press Center
url: /press-center
- title: Latest News
url: /latest-news
Comment on lines +712 to +713

preview_secondary_links:
title: Company highlights
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"sass": "1.89.2",
"use-query-params": "^2.2.1",
"uuid": "^11.1.0",
"vanilla-framework": "4.50.0",
"vanilla-framework": "4.52.0",
"venobox": "2.1.8",
"yup": "^1.6.1"
},
Expand Down Expand Up @@ -85,5 +85,8 @@
"^.+\\.(ts|tsx|js|jsx)$": "ts-jest"
},
"coverageReporters": ["cobertura", "text", "html"]
},
"resolutions": {
"vanilla-framework": "canonical/vanilla-framework#WD-36957-create-8-column-card-pattern-on-vanilla-framework"
}
}
3 changes: 2 additions & 1 deletion postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let config = {
"node_modules/leaflet/dist/leaflet.js",
"node_modules/venobox/dist/venobox.min.js",
"node_modules/vanilla-framework/templates/_macros/*.jinja",
"node_modules/intl-tel-input/build/js/utils.js"
"node_modules/intl-tel-input/build/js/utils.js",
],
defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
safelist: {
Expand All @@ -48,6 +48,7 @@ let config = {
/^cc-/, // Cookie consent related
/^optanon/, // Cookie consent related
/^has-/, // State-related classes
/blog-article/, // Blog article layout (incl. dynamic .wp-block-embed)
],
deep: [/form-.+/],
keyframes: true,
Expand Down
3 changes: 2 additions & 1 deletion redirects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ partners/apps-and-snaps/?: "/partners"
partners/kubernetes/?: "/partners"
partners/devices-and-iot/?: "/partners/iot-device"
partners/isv-partners/?: "/partners/isv-program"
press-centre/?: "/press-center"
press-centre/?: "/blog/latest-news"
press-center/?: "/blog/latest-news"
enterprise-services/ubuntu-advantage/landscape/dedicated-edition/?: "https://ubuntu.com/support"
intellectual-property-rights-policy/?: "/legal/intellectual-property-policy"
intellectual-property-policy/?: "/legal/intellectual-property-policy"
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
canonicalwebteam.flask-base==2.6.1
canonicalwebteam.blog==6.8.4
canonicalwebteam.blog==7.1.0
canonicalwebteam.http==1.0.4
canonicalwebteam.image-template==1.9.0
canonicalwebteam.templatefinder==1.0.0
Expand Down
4 changes: 1 addition & 3 deletions static/js/careers-progression.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ function standardCarousel() {
/** @type {HTMLElement} */
const child = slidesContainer[i].children[j];
child.style.transitionDuration = `${ms}s`;
child.style.transform = `translateX(-${
child.offsetWidth * index
}px)`;
child.style.transform = `translateX(-${child.offsetWidth * index}px)`;
}
}

Expand Down
6 changes: 3 additions & 3 deletions static/js/csp-event-handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@
pushGAEvent(
el.getAttribute("data-ga-category"),
el.getAttribute("data-ga-action"),
el.getAttribute("data-ga-label"),
el.getAttribute("data-ga-label")
);
pushGAEvent(
el.getAttribute("data-ga-extra-category"),
el.getAttribute("data-ga-extra-action"),
el.getAttribute("data-ga-extra-label"),
el.getAttribute("data-ga-extra-label")
);
});
});
Expand All @@ -62,7 +62,7 @@
pushGAEvent(
form.getAttribute("data-ga-submit-category"),
form.getAttribute("data-ga-submit-action"),
form.getAttribute("data-ga-submit-label"),
form.getAttribute("data-ga-submit-label")
);
});
});
Expand Down
97 changes: 57 additions & 40 deletions static/js/events.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
// Add anchor to search form submission
document.getElementById('event-search-form')?.addEventListener('submit', function(e) {
this.action = '/events#events-table';
});
document
.getElementById("event-search-form")
?.addEventListener("submit", function (e) {
this.action = "/events#events-table";
});

// Show more/less functionality
const toggleBtn = document.querySelector('.js-toggle-show-events');
const truncatedBody = document.querySelector('tbody.js-events-truncated');
const allBody = document.querySelector('tbody.js-events-all');
const toggleBtn = document.querySelector(".js-toggle-show-events");
const truncatedBody = document.querySelector("tbody.js-events-truncated");
const allBody = document.querySelector("tbody.js-events-all");

if (toggleBtn) {
toggleBtn.addEventListener('click', function() {
const isHidden = allBody.classList.contains('u-hide');
toggleBtn.addEventListener("click", function () {
const isHidden = allBody.classList.contains("u-hide");
if (isHidden) {
allBody.classList.remove('u-hide');
truncatedBody.classList.add('u-hide');
toggleBtn.innerHTML = 'Show less';
allBody.classList.remove("u-hide");
truncatedBody.classList.add("u-hide");
toggleBtn.innerHTML = "Show less";
} else {
allBody.classList.add('u-hide');
truncatedBody.classList.remove('u-hide');
toggleBtn.innerHTML = 'Show all events';
allBody.classList.add("u-hide");
truncatedBody.classList.remove("u-hide");
toggleBtn.innerHTML = "Show all events";
}
});
}
Expand All @@ -28,13 +30,17 @@ function getSortValue(cell, dataType) {
let value;

if (dataType === "link") {
const link = cell?.querySelector('a');
value = link ? link.textContent.toLowerCase().trim() : (cell ? cell.textContent.toLowerCase().trim() : '');
const link = cell?.querySelector("a");
value = link
? link.textContent.toLowerCase().trim()
: cell
? cell.textContent.toLowerCase().trim()
: "";
} else if (dataType === "string") {
value = cell ? cell.textContent.toLowerCase().trim() : '';
value = cell ? cell.textContent.toLowerCase().trim() : "";
} else if (dataType === "date") {
const parsed = new Date(cell ? cell.textContent.trim() : '');
value = isNaN(parsed) ? '' : parsed.getTime().toString().padStart(20, '0');
const parsed = new Date(cell ? cell.textContent.trim() : "");
value = isNaN(parsed) ? "" : parsed.getTime().toString().padStart(20, "0");
}

return value;
Expand All @@ -43,8 +49,8 @@ function getSortValue(cell, dataType) {
// Helper function to sort rows
function sortRows(rows, column, dataType, ascending) {
return rows.sort((a, b) => {
const aCells = a.querySelectorAll('td');
const bCells = b.querySelectorAll('td');
const aCells = a.querySelectorAll("td");
const bCells = b.querySelectorAll("td");
const aCell = aCells[column];
const bCell = bCells[column];

Expand All @@ -60,21 +66,21 @@ function sortRows(rows, column, dataType, ascending) {
}

// Table sorting functionality
const table = document.querySelector('.js-sortable-table');
const table = document.querySelector(".js-sortable-table");
if (table) {
const sortBtns = table.querySelectorAll('.js-sortable-table__button');
const initCol = table.getAttribute('data-sort-column');
const initDir = table.getAttribute('data-sort-direction');
const sortBtns = table.querySelectorAll(".js-sortable-table__button");
const initCol = table.getAttribute("data-sort-column");
const initDir = table.getAttribute("data-sort-direction");
let currentSort = {
column: initCol !== null ? parseInt(initCol) : null,
ascending: initDir !== 'desc',
ascending: initDir !== "desc",
};

sortBtns.forEach(btn => {
btn.addEventListener('click', function() {
sortBtns.forEach((btn) => {
btn.addEventListener("click", function () {
const th = this.parentElement;
const column = parseInt(th.getAttribute('data-column'));
const dataType = th.getAttribute('data-type') || 'string';
const column = parseInt(th.getAttribute("data-column"));
const dataType = th.getAttribute("data-type") || "string";

// Toggle sort direction if clicking the same column
if (currentSort.column === column) {
Expand All @@ -83,25 +89,36 @@ if (table) {
currentSort.column = column;
currentSort.ascending = true;
}

// If there are two table bodies, sort from the "all" tbody
if (allBody && truncatedBody) {
const allRows = sortRows(Array.from(allBody.querySelectorAll('tr')), column, dataType, currentSort.ascending);
const allRows = sortRows(
Array.from(allBody.querySelectorAll("tr")),
column,
dataType,
currentSort.ascending
);

// Update "all" tbody
allBody.innerHTML = '';
allRows.forEach(row => allBody.appendChild(row));
allBody.innerHTML = "";
allRows.forEach((row) => allBody.appendChild(row));

// Update truncated tbody with first 5 values
const firstTen = allRows.slice(0, 10);
truncatedBody.innerHTML = '';
firstTen.forEach(row => truncatedBody.appendChild(row.cloneNode(true)));

truncatedBody.innerHTML = "";
firstTen.forEach((row) =>
truncatedBody.appendChild(row.cloneNode(true))
);
} else if (truncatedBody) {
// Update truncated tbody only
const rows = sortRows(Array.from(truncatedBody.querySelectorAll('tr')), column, dataType, currentSort.ascending);
rows.forEach(row => truncatedBody.appendChild(row));
const rows = sortRows(
Array.from(truncatedBody.querySelectorAll("tr")),
column,
dataType,
currentSort.ascending
);
rows.forEach((row) => truncatedBody.appendChild(row));
}
});
});
}
}
2 changes: 1 addition & 1 deletion static/js/forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function requiredCheckbox(fieldset, target) {
*/
function setDataLayerConsentInfo() {
/** @type {Array} */
const dataLayer = (window.dataLayer) || [];
const dataLayer = window.dataLayer || [];
const latestConsentUpdateElements = dataLayer
.slice()
.reverse()
Expand Down
Loading