Implement flattened structure with in-page navigation and back-to-top links

This commit is contained in:
Hugh Ratsch
2025-03-02 11:35:08 -06:00
parent be1c0d3dc9
commit b5433bedf5
5 changed files with 291 additions and 41 deletions
+52
View File
@@ -1,5 +1,57 @@
/* Custom styling for IT Learning Notes */ /* Custom styling for IT Learning Notes */
/* Table of Contents styling */
.toc {
background-color: #f8f9fa;
border: 1px solid #eaecef;
border-radius: 4px;
padding: 1em;
margin-bottom: 2em;
}
.toc ul, .toc ol {
list-style-type: none;
padding-left: 1em;
}
.toc li {
margin: 0.5em 0;
}
/* Back to top link styling */
a[href^="#"] {
text-decoration: none;
color: #4183c4;
font-weight: 600;
}
a[href^="#"]:hover {
text-decoration: underline;
}
/* Navigation links at bottom of sections */
a[href="#user-management-solutions-"],
a[href="#storage-management-solutions-"],
a[href="#service-management-solutions-"],
a[href="#network-solutions-"],
a[href="#security-solutions-"],
a[href="#container-management-solutions-"],
a[href="#system-recovery-solutions-"],
a[href="#shell-scripting-solutions-"] {
display: inline-block;
background-color: #f1f8ff;
padding: 0.3em 0.6em;
margin: 1.5em 0;
border-radius: 4px;
border-left: 4px solid #4183c4;
font-size: 0.9em;
}
/* Section anchor targets */
div[id^="scenario-"] {
scroll-margin-top: 70px;
}
/* Ensure all sections are properly visible */ /* Ensure all sections are properly visible */
.section { .section {
display: block !important; display: block !important;
+164 -1
View File
@@ -1 +1,164 @@
// Custom JavaScript for IT Learning Notes
// Wait for the DOM to be fully loaded
document.addEventListener('DOMContentLoaded', function() {
// Improve anchor link scrolling behavior
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
// Only process internal page links
if (targetId.startsWith('#')) {
const targetElement = document.querySelector(targetId);
if (targetElement) {
// Smooth scroll to the target
window.scrollTo({
top: targetElement.offsetTop - 60, // Account for header/navigation
behavior: 'smooth'
});
// Update URL without reloading the page
history.pushState(null, null, targetId);
}
}
});
});
// Add "Back to Top" links if they don't exist in the content
const sections = document.querySelectorAll('h2');
sections.forEach(section => {
// Check if there's already a back-to-top link after this section
const nextElement = section.nextElementSibling;
const hasBackToTop = false;
// Find the end of this section (next h2 or end of document)
let currentElement = section.nextElementSibling;
while (currentElement && currentElement.tagName !== 'H2') {
if (currentElement.tagName === 'A' &&
currentElement.getAttribute('href') &&
currentElement.getAttribute('href').includes('top')) {
hasBackToTop = true;
break;
}
currentElement = currentElement.nextElementSibling;
}
// Add back-to-top link if needed
if (!hasBackToTop && currentElement && currentElement.tagName === 'H2') {
const backToTop = document.createElement('a');
backToTop.href = '#';
backToTop.textContent = 'Back to Top';
backToTop.className = 'back-to-top';
backToTop.style.display = 'block';
backToTop.style.marginBottom = '2em';
// Insert before the next heading
section.parentNode.insertBefore(backToTop, currentElement);
}
});
// Fix for any dynamically loaded content
setTimeout(function() {
// Force redraw of content area
const content = document.querySelector('.content');
if (content) {
content.style.display = 'none';
content.offsetHeight; // Force reflow
content.style.display = 'block';
}
// Scroll to anchor if present in URL
if (window.location.hash) {
const element = document.getElementById(window.location.hash.substring(1));
if (element) {
element.scrollIntoView({behavior: 'smooth'});
}
}
}, 100);
});
// Create a table of contents if it doesn't exist
function generateTableOfContents() {
// Only run if we don't have a TOC div already
if (!document.querySelector('.toc')) {
const headings = document.querySelectorAll('h2');
if (headings.length > 2) { // Only if we have a reasonable number of headings
const toc = document.createElement('div');
toc.className = 'toc';
const tocTitle = document.createElement('h2');
tocTitle.textContent = 'Table of Contents';
toc.appendChild(tocTitle);
const tocList = document.createElement('ul');
headings.forEach(heading => {
if (!heading.textContent.toLowerCase().includes('table of contents')) {
const listItem = document.createElement('li');
const link = document.createElement('a');
// Create an id for the heading if it doesn't have one
if (!heading.id) {
heading.id = heading.textContent.toLowerCase()
.replace(/[^\w]+/g, '-');
}
link.href = '#' + heading.id;
link.textContent = heading.textContent;
listItem.appendChild(link);
tocList.appendChild(listItem);
}
});
toc.appendChild(tocList);
// Insert after the first heading (title)
const title = document.querySelector('h1');
if (title && title.nextElementSibling) {
title.parentNode.insertBefore(toc, title.nextElementSibling.nextElementSibling);
}
}
}
}
// Run when the page loads
window.addEventListener('load', function() {
// Generate TOC if needed
generateTableOfContents();
// Enable all sections that might have been hidden
document.querySelectorAll('.content-hidden')
.forEach(el => el.classList.remove('content-hidden'));
});
// Monitor for any dynamically added elements and ensure they're visible
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes && mutation.addedNodes.length > 0) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
const node = mutation.addedNodes[i];
if (node.nodeType === 1) { // Element node
if (node.classList && (
node.classList.contains('section') ||
node.classList.contains('content') ||
node.classList.contains('content-hidden')
)) {
node.style.display = 'block';
node.style.visibility = 'visible';
node.style.opacity = '1';
node.classList.remove('content-hidden');
}
}
}
}
});
});
// Start observing the document body for changes
observer.observe(document.body, {
childList: true,
subtree: true
});
+8 -34
View File
@@ -15,37 +15,11 @@
# My Solutions Portfolio # My Solutions Portfolio
- [Portfolio Overview](solutions/README.md) - [Portfolio Overview](solutions/README.md)
- [User Management Solutions [👤]](solutions/user-management.md)
## User Management [👤] - [Storage Management Solutions [💾]](solutions/storage-management.md)
- [User Management Solutions](solutions/user-management.md) - [Service Management Solutions [⚙️]](solutions/service-management.md)
- [Creating Users with Specific Requirements (v1-S1)](solutions/user-management.md#scenario-creating-users-with-specific-requirements) - [Network Solutions [🌐]](solutions/networking.md)
- [Departmental User Structure (v1-S1 Expanded)](solutions/user-management.md#scenario-creating-users-with-specific-requirements-1) - [Security Solutions [🔒]](solutions/security.md)
- [Container Management Solutions [📦]](solutions/container-management.md)
## Storage Management [💾] - [System Recovery Solutions [🔧]](solutions/system-recovery.md)
- [Storage Management Solutions](solutions/storage-management.md) - [Shell Scripting Solutions [📜]](solutions/shell-scripting.md)
- [LVM Configuration and Extension (v1-S2)](solutions/storage-management.md#scenario-v1-s2-lvm-configuration-and-management)
- [Create and Extend Logical Volume (v1-S2)](solutions/storage-management.md#scenario-v1-s2-create-a-new-2gb-partition-on-devsdb-and-extend-the-logical-volume-by-500mb-using-lvm)
## Service Management [⚙️]
- [Service Management Solutions](solutions/service-management.md)
- [Time Synchronization and Security (v1-S3)](solutions/service-management.md#scenario-v1-s3-time-synchronization-and-security-configuration)
## Networking [🌐]
- [Network Solutions](solutions/networking.md)
- [Network Interface Configuration (v1-S7)](solutions/networking.md#scenario-v1-s7-network-interface-configuration)
## Security [🔒]
- [Security Solutions](solutions/security.md)
- [SELinux and Firewall Configuration (v1-S3)](solutions/security.md#scenario-v1-s3-selinux-and-firewall-configuration)
## Container Management [📦]
- [Container Management Solutions](solutions/container-management.md)
- [Container Deployment (v1-S4)](solutions/container-management.md#scenario-v1-s4-container-management)
## System Recovery & Maintenance [🔧]
- [System Recovery Solutions](solutions/system-recovery.md)
- [System Recovery and Maintenance (v1-S5)](solutions/system-recovery.md#scenario-v1-s5-system-recovery-and-maintenance)
## Shell Scripting [📜]
- [Shell Scripting Solutions](solutions/shell-scripting.md)
- [File Management Script (v1-S6)](solutions/shell-scripting.md#scenario-v1-s6-shell-scripting)
+36 -3
View File
@@ -2,6 +2,20 @@
This section documents my solutions to storage management scenarios, including partitioning, LVM, filesystem management, and storage troubleshooting. This section documents my solutions to storage management scenarios, including partitioning, LVM, filesystem management, and storage troubleshooting.
<div class="toc">
## Table of Contents
- [Scenario Tags](#scenario-tags)
- [Scenario: LVM Configuration and Management](#scenario-v1-s2-lvm-configuration-and-management)
- [Scenario: Create a new 2GB partition](#scenario-v1-s2-create-a-new-2gb-partition-on-devsdb-and-extend-the-logical-volume-by-500mb-using-lvm)
- [Scenario: Storage Configuration](#scenario-v2-s2-storage-configuration)
- [Scenario: Dynamic Storage Management](#scenario-v3-s2-dynamic-storage-management)
- [Scenario: Advanced File System Management](#scenario-v3-s8-advanced-file-system-management)
</div>
<div id="scenario-tags"></div>
## Scenario Tags ## Scenario Tags
| Tag | Description | | Tag | Description |
@@ -11,6 +25,10 @@ This section documents my solutions to storage management scenarios, including p
| [v3-S2] | Dynamic Storage Management - Practice Scenarios v3 | | [v3-S2] | Dynamic Storage Management - Practice Scenarios v3 |
| [v3-S8] | Advanced File System Management - Practice Scenarios v3 | | [v3-S8] | Advanced File System Management - Practice Scenarios v3 |
[Back to Top](#storage-management-solutions-)
<div id="scenario-v1-s2-lvm-configuration-and-management"></div>
## Scenario: [v1-S2] LVM Configuration and Management ## Scenario: [v1-S2] LVM Configuration and Management
### Original Problem ### Original Problem
@@ -64,8 +82,9 @@ df -h
- Filesystem Management - Filesystem Management
- Storage Troubleshooting - Storage Troubleshooting
--- [Back to Top](#storage-management-solutions-)
---
<div id="scenario-v1-s2-create-a-new-2gb-partition-on-devsdb-and-extend-the-logical-volume-by-500mb-using-lvm"></div>
## Scenario: [v1-S2] Create a new 2GB partition on /dev/sdb and extend the logical volume by 500MB using LVM ## Scenario: [v1-S2] Create a new 2GB partition on /dev/sdb and extend the logical volume by 500MB using LVM
@@ -188,6 +207,10 @@ lsblk -f
- Filesystem Management - Filesystem Management
- Storage Troubleshooting - Storage Troubleshooting
[Back to Top](#storage-management-solutions-)
<div id="scenario-v2-s2-storage-configuration"></div>
## Scenario: [v2-S2] Storage Configuration ## Scenario: [v2-S2] Storage Configuration
### Original Problem ### Original Problem
@@ -208,6 +231,10 @@ From Practice Scenarios v2, Scenario 2:
### Solution Steps ### Solution Steps
[Your solution will be added here] [Your solution will be added here]
[Back to Top](#storage-management-solutions-)
<div id="scenario-v3-s2-dynamic-storage-management"></div>
## Scenario: [v3-S2] Dynamic Storage Management ## Scenario: [v3-S2] Dynamic Storage Management
### Original Problem ### Original Problem
@@ -228,6 +255,10 @@ From Practice Scenarios v3, Scenario 2:
### Solution Steps ### Solution Steps
[Your solution will be added here] [Your solution will be added here]
[Back to Top](#storage-management-solutions-)
<div id="scenario-v3-s8-advanced-file-system-management"></div>
## Scenario: [v3-S8] Advanced File System Management ## Scenario: [v3-S8] Advanced File System Management
### Original Problem ### Original Problem
@@ -248,4 +279,6 @@ From Practice Scenarios v3, Scenario 8:
- Required Outcome: [To be filled] - Required Outcome: [To be filled]
### Solution Steps ### Solution Steps
[Your solution will be added here] [Your solution will be added here]
[Back to Top](#storage-management-solutions-)
+31 -3
View File
@@ -2,6 +2,19 @@
This section contains my solutions to various user management scenarios from the practice exercises. This section contains my solutions to various user management scenarios from the practice exercises.
<div class="toc">
## Table of Contents
- [Scenario Tags](#scenario-tags)
- [Scenario: Creating Users with Specific Requirements](#scenario-creating-users-with-specific-requirements)
- [Scenario: Creating Users with Specific Requirements (Expanded)](#scenario-creating-users-with-specific-requirements-1)
- [Scenario: System Access and File Management](#scenario-v2-s1-system-access-and-file-management)
- [Scenario: Advanced User Management](#scenario-v3-s1-advanced-user-management)
</div>
<div id="scenario-tags"></div>
## Scenario Tags ## Scenario Tags
| Tag | Description | | Tag | Description |
@@ -10,6 +23,10 @@ This section contains my solutions to various user management scenarios from the
| [v2-S1] | System Access and File Management - Practice Scenarios v2 | | [v2-S1] | System Access and File Management - Practice Scenarios v2 |
| [v3-S1] | Advanced User Management - Practice Scenarios v3 | | [v3-S1] | Advanced User Management - Practice Scenarios v3 |
[Back to Top](#user-management-solutions-)
<div id="scenario-creating-users-with-specific-requirements"></div>
## Scenario: Creating Users with Specific Requirements ## Scenario: Creating Users with Specific Requirements
### Original Problem ### Original Problem
@@ -51,10 +68,11 @@ From Practice Scenarios v1: Create a user named 'john' with a custom shell and h
- Security Best Practices - Security Best Practices
- System Verification - System Verification
*** [Back to Top](#user-management-solutions-)
***
## Scenario: Creating Users with Specific Requirements-1 <div id="scenario-creating-users-with-specific-requirements-1"></div>
## Scenario: Creating Users with Specific Requirements (Expanded)
### Original Problem ### Original Problem
- Create a new user called 'analyst1' with home directory '/home/analyst1' - Create a new user called 'analyst1' with home directory '/home/analyst1'
@@ -133,6 +151,10 @@ sudo chage -l analyst1
> [NOTE] > [NOTE]
> This scenario is a good example of how to create a user with a specific home directory, add them to a group, create a directory owned by the group with SGID set, and set password expiry. > This scenario is a good example of how to create a user with a specific home directory, add them to a group, create a directory owned by the group with SGID set, and set password expiry.
[Back to Top](#user-management-solutions-)
<div id="scenario-v2-s1-system-access-and-file-management"></div>
## Scenario: [v2-S1] System Access and File Management ## Scenario: [v2-S1] System Access and File Management
### Original Problem ### Original Problem
@@ -152,6 +174,10 @@ From Practice Scenarios v2, Scenario 1:
### Solution Steps ### Solution Steps
[Your solution will be added here] [Your solution will be added here]
[Back to Top](#user-management-solutions-)
<div id="scenario-v3-s1-advanced-user-management"></div>
## Scenario: [v3-S1] Advanced User Management ## Scenario: [v3-S1] Advanced User Management
### Original Problem ### Original Problem
@@ -175,3 +201,5 @@ From Practice Scenarios v3, Scenario 1:
### Solution Steps ### Solution Steps
[Your solution will be added here] [Your solution will be added here]
[Back to Top](#user-management-solutions-)