Compare commits
7 Commits
7bba517b48
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ae31fec647 | |||
| ceb37fc5af | |||
| 63e181109c | |||
| b79a4ece03 | |||
| 3a205a53cf | |||
| 4447e50bcf | |||
| 1ce1a08442 |
BIN
assets/img/demo-post-thumbnails/demo-post-thumbnail-1.jpg
Normal file
BIN
assets/img/demo-post-thumbnails/demo-post-thumbnail-1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 723 KiB |
BIN
assets/img/demo-post-thumbnails/demo-post-thumbnail-2.jpg
Normal file
BIN
assets/img/demo-post-thumbnails/demo-post-thumbnail-2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 875 KiB |
BIN
assets/img/demo-post-thumbnails/demo-post-thumbnail-3.jpg
Normal file
BIN
assets/img/demo-post-thumbnails/demo-post-thumbnail-3.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 698 KiB |
32
assets/js/custom-image-sizes.js
Normal file
32
assets/js/custom-image-sizes.js
Normal file
@ -0,0 +1,32 @@
|
||||
function lcpUpdateImageSizes(imageSizes) {
|
||||
// Validate the input to ensure it's an array
|
||||
if (!Array.isArray(imageSizes)) {
|
||||
console.error('Invalid image sizes data');
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the form data to send to WordPress to update the theme settings
|
||||
const updateData = new FormData();
|
||||
updateData.append('action', 'update_lcp_theme_settings'); // WordPress action hook
|
||||
updateData.append('image_sizes', JSON.stringify(imageSizes)); // Send image sizes as a JSON string
|
||||
updateData.append('nonce', customImageSizeAjax.nonce); // Send the nonce
|
||||
|
||||
console.log('Sending data to AJAX:', updateData); // Log the data for debugging
|
||||
|
||||
// Send the AJAX request
|
||||
fetch(customImageSizeAjax.ajax_url, {
|
||||
method: 'POST',
|
||||
body: updateData, // Send form data directly
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
console.log('Theme settings updated successfully.');
|
||||
} else {
|
||||
console.error('Failed to update theme settings:', data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error updating theme settings:', error);
|
||||
});
|
||||
}
|
||||
85
assets/js/demo-posts-import.js
Normal file
85
assets/js/demo-posts-import.js
Normal file
@ -0,0 +1,85 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// Check if the 'Import Demo Posts' button exists
|
||||
const importButton = document.getElementById('import-demo-posts');
|
||||
console.log(importButton); // This will log the button element to the console
|
||||
|
||||
if (importButton) {
|
||||
// Check if the lcp_demo_posts option exists
|
||||
if (lcp_ajax_obj.lcp_demo_posts && lcp_ajax_obj.lcp_demo_posts.post_ids && lcp_ajax_obj.lcp_demo_posts.post_ids.length > 0) {
|
||||
// Disable the 'Import Demo Posts' button if demo posts have already been imported
|
||||
importButton.disabled = true;
|
||||
importButton.textContent = 'Demo Posts Already Imported'; // Optional: Change button text
|
||||
} else {
|
||||
// Add event listener to import demo posts if the button is enabled
|
||||
importButton.addEventListener('click', function () {
|
||||
console.log("Clicked"); // This should be triggered on button click
|
||||
const formData = new FormData();
|
||||
|
||||
// Append action and nonce to the form data
|
||||
formData.append('action', 'lcp_import_demo_posts');
|
||||
formData.append('lcp_import_nonce', lcp_ajax_obj.nonce);
|
||||
|
||||
// Send the AJAX request to import demo posts
|
||||
fetch(lcp_ajax_obj.ajax_url, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert(data.data); // Success message
|
||||
importButton.disabled = true;
|
||||
importButton.textContent = 'Demo Posts Imported'; // Optional: Change button text
|
||||
} else {
|
||||
alert('Error: ' + (data.data || 'Unknown error')); // Error message
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('An error occurred while processing your request.');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the 'Delete Demo Posts' button exists
|
||||
const deleteButton = document.getElementById('delete-demo-posts');
|
||||
if (deleteButton) {
|
||||
deleteButton.addEventListener('click', function () {
|
||||
const formData = new FormData();
|
||||
|
||||
// Append action and nonce to the form data for deletion
|
||||
formData.append('action', 'lcp_delete_demo_posts'); // Use the correct action here
|
||||
formData.append('lcp_import_nonce', lcp_ajax_obj.nonce); // Pass nonce for security
|
||||
|
||||
// Send the AJAX request to delete demo posts
|
||||
fetch(lcp_ajax_obj.ajax_url, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert(data.data); // Success message
|
||||
deleteButton.disabled = true;
|
||||
deleteButton.textContent = 'Demo Posts Deleted';
|
||||
|
||||
// Re-enable the "Import Demo Posts" button and reset its text
|
||||
const importButton = document.getElementById('import-demo-posts');
|
||||
if (importButton) {
|
||||
importButton.disabled = false;
|
||||
importButton.textContent = 'Import Demo Posts';
|
||||
}
|
||||
} else {
|
||||
alert('Error: ' + (data.data || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('An error occurred while processing your request.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
@ -21,7 +21,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
formData.append('icon_set_id', iconSetId);
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', mytheme_ajax.ajax_url, true);
|
||||
xhr.open('POST', lcp_ajax.ajax_url, true);
|
||||
|
||||
xhr.onload = function () {
|
||||
if (xhr.status === 200) {
|
||||
@ -55,7 +55,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
formData.append('icon_set_id', iconSetId);
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', mytheme_ajax.ajax_url, true);
|
||||
xhr.open('POST', lcp_ajax.ajax_url, true);
|
||||
|
||||
xhr.onload = function () {
|
||||
if (xhr.status === 200) {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
|
||||
/* ACCORDION */
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Find all elements with the class "lcp-accordion"
|
||||
var accordions = document.querySelectorAll('.lcp-accordion');
|
||||
@ -31,31 +33,218 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
});
|
||||
|
||||
/* TABS */
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const tabs = document.querySelectorAll('.tab-link');
|
||||
const panes = document.querySelectorAll('.tab-pane');
|
||||
const tabContainer = document.querySelector('.lcp-tab-container'); // The parent container
|
||||
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
// Only enable the hash functionality if the container has the class '.lcp-support-hash'
|
||||
if (tabContainer && tabContainer.classList.contains('lcp-support-hash')) {
|
||||
|
||||
// Function to set the active tab based on the hash in the URL
|
||||
function setActiveTabFromHash() {
|
||||
const hash = window.location.hash; // Get the current URL hash
|
||||
if (hash) {
|
||||
const targetTab = document.querySelector(`.tab-link[data-tab="${hash.substring(1)}"]`); // Remove '#' from hash
|
||||
const targetPane = document.getElementById(hash.substring(1));
|
||||
|
||||
// Remove active class from all tabs and panes
|
||||
tabs.forEach(link => link.classList.remove('active'));
|
||||
panes.forEach(pane => pane.classList.remove('active'));
|
||||
// If both tab and pane exist, make them active
|
||||
if (targetTab && targetPane) {
|
||||
tabs.forEach(link => link.classList.remove('active'));
|
||||
panes.forEach(pane => pane.classList.remove('active'));
|
||||
|
||||
// Add active class to the clicked tab
|
||||
tab.classList.add('active');
|
||||
|
||||
// Get the target pane
|
||||
const targetPaneId = tab.dataset.tab;
|
||||
const targetPane = document.getElementById(targetPaneId);
|
||||
|
||||
// Check if targetPane exists before trying to manipulate it
|
||||
if (targetPane) {
|
||||
targetPane.classList.add('active');
|
||||
} else {
|
||||
console.error(`Tab pane with ID '${targetPaneId}' not found.`);
|
||||
targetTab.classList.add('active');
|
||||
targetPane.classList.add('active');
|
||||
} else {
|
||||
console.error(`Tab or pane with ID '${hash}' not found.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the active tab from the hash when the page loads
|
||||
setActiveTabFromHash();
|
||||
}
|
||||
// Handle tab clicks
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
// Remove active class from all tabs and panes
|
||||
tabs.forEach(link => link.classList.remove('active'));
|
||||
panes.forEach(pane => pane.classList.remove('active'));
|
||||
|
||||
// Add active class to the clicked tab
|
||||
tab.classList.add('active');
|
||||
|
||||
// Get the target pane and update URL hash
|
||||
const targetPaneId = tab.dataset.tab;
|
||||
const targetPane = document.getElementById(targetPaneId);
|
||||
|
||||
// Check if targetPane exists before trying to manipulate it
|
||||
if (targetPane) {
|
||||
targetPane.classList.add('active');
|
||||
if (tabContainer && tabContainer.classList.contains('lcp-support-hash')){
|
||||
window.location.hash = targetPaneId; // Update the URL hash
|
||||
}
|
||||
} else {
|
||||
console.error(`Tab pane with ID '${targetPaneId}' not found.`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/* REPEATER */
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Function to initialize each repeater instance
|
||||
function initRepeater(repeater) {
|
||||
const firstRow = repeater.querySelector('.lcp-repeater-row');
|
||||
|
||||
// Function to check if all required fields are filled
|
||||
function isRequiredFieldsFilled(row) {
|
||||
const requiredFields = row.querySelectorAll('[data-lcp-required="true"], [data-lcp-required-for-new-row="true"]');
|
||||
let valid = true;
|
||||
|
||||
requiredFields.forEach(input => {
|
||||
// Check input type and value for validation
|
||||
if (input.type === 'number' && (input.value === '' || isNaN(input.value))) {
|
||||
valid = false;
|
||||
} else if (input.type === 'checkbox' && !input.checked) {
|
||||
valid = false;
|
||||
}
|
||||
});
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
// Function to create a new row by cloning the first row
|
||||
function addRepeaterRow() {
|
||||
const newRow = firstRow.cloneNode(true); // true means deep cloning (includes children)
|
||||
|
||||
const inputs = newRow.querySelectorAll('input');
|
||||
inputs.forEach(input => input.value = ''); // Reset value for input fields
|
||||
newRow.querySelector('input[type="checkbox"]').checked = false; // Uncheck the checkbox
|
||||
|
||||
repeater.insertBefore(newRow, repeater.querySelector('.lcp-repeater-add-row'));
|
||||
|
||||
toggleAddRowButton();
|
||||
toggleSubmitButton();
|
||||
}
|
||||
|
||||
// Function to toggle the "Add Row" button based on the required field for new rows
|
||||
function toggleAddRowButton() {
|
||||
const addRowButton = repeater.querySelector('.lcp-repeater-add-row');
|
||||
const rows = repeater.querySelectorAll('.lcp-repeater-row');
|
||||
|
||||
let validForNewRow = true;
|
||||
|
||||
rows.forEach(row => {
|
||||
const requiredForNewRowFields = row.querySelectorAll('[data-lcp-required-for-new-row="true"]');
|
||||
requiredForNewRowFields.forEach(input => {
|
||||
if (input.value === '' || (input.type === 'checkbox' && !input.checked)) {
|
||||
validForNewRow = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
addRowButton.disabled = !validForNewRow;
|
||||
}
|
||||
|
||||
// Function to toggle the "Submit" button based on the validation of all rows
|
||||
function toggleSubmitButton() {
|
||||
const submitButton = repeater.querySelector('.lcp-repeater-submit');
|
||||
const rows = repeater.querySelectorAll('.lcp-repeater-row');
|
||||
|
||||
let allValid = true;
|
||||
|
||||
rows.forEach(row => {
|
||||
if (!isRequiredFieldsFilled(row)) {
|
||||
allValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
submitButton.disabled = !allValid;
|
||||
}
|
||||
|
||||
// Function to handle form submission, ensuring all required fields are filled
|
||||
function handleSubmit(event) {
|
||||
const submitButton = event.target;
|
||||
const actionType = submitButton.getAttribute('data-lcp-action'); // This will be used to pass data to the handler
|
||||
const rows = repeater.querySelectorAll('.lcp-repeater-row');
|
||||
let allValid = true;
|
||||
|
||||
rows.forEach(row => {
|
||||
if (!isRequiredFieldsFilled(row)) {
|
||||
allValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (allValid) {
|
||||
const repeaterData = [];
|
||||
|
||||
rows.forEach(function(row) {
|
||||
const rowData = {};
|
||||
const inputs = row.querySelectorAll('input');
|
||||
|
||||
inputs.forEach(function(input) {
|
||||
const key = input.getAttribute('data-lcp-repeater-key');
|
||||
let value;
|
||||
|
||||
if (input.type === 'checkbox') {
|
||||
value = input.checked; // Boolean value for checkbox
|
||||
} else {
|
||||
value = input.value; // Text or number inputs
|
||||
}
|
||||
|
||||
rowData[key] = value; // Add key-value pair to rowData
|
||||
});
|
||||
|
||||
repeaterData.push(rowData); // Add rowData to the repeaterData array
|
||||
});
|
||||
|
||||
// Now just pass the data off to the handler
|
||||
if (typeof window[actionType] === 'function') {
|
||||
window[actionType](repeaterData); // Calls the function (e.g., `lcpUpdateImageSizes`)
|
||||
}
|
||||
} else {
|
||||
alert("Please fill in all required fields.");
|
||||
}
|
||||
}
|
||||
|
||||
// Event listener for adding a new row when a user clicks the "Add Row" button
|
||||
const addRowButtons = repeater.querySelectorAll('.lcp-repeater-add-row');
|
||||
addRowButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
if (isRequiredFieldsFilled(firstRow)) {
|
||||
addRepeaterRow();
|
||||
} else {
|
||||
alert('Please fill in the required fields to add a new row.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Event listener for submitting the repeater form
|
||||
const submitButton = repeater.querySelector('.lcp-repeater-submit');
|
||||
submitButton.addEventListener('click', handleSubmit);
|
||||
|
||||
// Initial validation for the add row button
|
||||
toggleAddRowButton();
|
||||
|
||||
// Initial validation for the submit button
|
||||
toggleSubmitButton();
|
||||
|
||||
// Added event listeners to handle any changes in input and trigger validation
|
||||
repeater.addEventListener('input', function() {
|
||||
toggleAddRowButton(); // Revalidate Add Row button
|
||||
toggleSubmitButton(); // Revalidate Submit button
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize each repeater on the page
|
||||
const repeaters = document.querySelectorAll('.lcp-repeater');
|
||||
repeaters.forEach(repeater => {
|
||||
initRepeater(repeater);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -89,7 +89,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
|
||||
// Add debounced scroll event listener
|
||||
window.addEventListener('scroll', debounce(handleScroll, 20)); // 200ms debounce
|
||||
window.addEventListener('scroll', debounce(handleScroll, 0)); // 200ms debounce
|
||||
|
||||
});
|
||||
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Path to your icons.json file
|
||||
$filePath = 'output.json';
|
||||
|
||||
// Read the content of the JSON file
|
||||
$jsonData = file_get_contents($filePath);
|
||||
|
||||
// Decode the JSON data into a PHP array
|
||||
$iconsData = json_decode($jsonData, true);
|
||||
|
||||
// Check if the data is decoded successfully
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
die('Error decoding JSON data: ' . json_last_error_msg());
|
||||
}
|
||||
|
||||
// Check if the data contains a 'family' key (indicating it has families with SVGs)
|
||||
if (isset($iconsData[0]['family'])) {
|
||||
// Handle the case with families and svgs (structure 1)
|
||||
foreach ($iconsData as &$family) {
|
||||
if (isset($family['svgs']) && is_array($family['svgs'])) {
|
||||
// Sort the 'svgs' array alphabetically by the 'name' field
|
||||
usort($family['svgs'], function($a, $b) {
|
||||
return strcmp($a['name'], $b['name']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the families by the 'family' field (if needed)
|
||||
usort($iconsData, function($a, $b) {
|
||||
return strcmp($a['family'], $b['family']);
|
||||
});
|
||||
|
||||
} else {
|
||||
// Handle the case without families (structure 2)
|
||||
// Sort the flat array of icons alphabetically by the 'name' field
|
||||
usort($iconsData, function($a, $b) {
|
||||
return strcmp($a['name'], $b['name']);
|
||||
});
|
||||
}
|
||||
|
||||
// Encode the sorted data back to JSON
|
||||
$sortedJsonData = json_encode($iconsData, JSON_PRETTY_PRINT);
|
||||
|
||||
// Check if encoding was successful
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
die('Error encoding JSON data: ' . json_last_error_msg());
|
||||
}
|
||||
|
||||
// Write the sorted JSON data back to the file
|
||||
if (file_put_contents($filePath, $sortedJsonData)) {
|
||||
echo "The icons data has been sorted and saved successfully!";
|
||||
} else {
|
||||
echo "Error writing the sorted data to the file.";
|
||||
}
|
||||
|
||||
?>
|
||||
@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Function to generate a UUID (compliant with MySQL UUID)
|
||||
function generateUUID() {
|
||||
return bin2hex(random_bytes(16)); // Generate a random UUID
|
||||
}
|
||||
|
||||
// Function to convert the raw SVG to JSON format
|
||||
function convertSymbolsToJSON($svgContent) {
|
||||
// Match all <symbol> elements and extract them
|
||||
preg_match_all('/<symbol[^>]*>[\s\S]*?<\/symbol>/', $svgContent, $matches);
|
||||
|
||||
$jsonData = [];
|
||||
|
||||
foreach ($matches[0] as $symbol) {
|
||||
// Extract 'id', 'viewBox', and 'path' attributes
|
||||
preg_match('/id="([^"]+)"/', $symbol, $idMatches);
|
||||
preg_match('/viewBox="([^"]+)"/', $symbol, $viewBoxMatches);
|
||||
preg_match('/<path[^>]*d="([^"]+)"/', $symbol, $pathMatches);
|
||||
|
||||
// If we have a valid symbol, process it
|
||||
if (isset($idMatches[1]) && isset($viewBoxMatches[1]) && isset($pathMatches[1])) {
|
||||
// Generate a UUID for the symbol
|
||||
$uniqueId = generateUUID();
|
||||
|
||||
// Capitalize the name by replacing hyphens with spaces and capitalizing each word
|
||||
$name = ucwords(str_replace('-', ' ', $idMatches[1]));
|
||||
|
||||
// Build the symbol JSON object
|
||||
$symbolJSON = [
|
||||
"id" => $uniqueId,
|
||||
"name" => $name,
|
||||
"viewBox" => $viewBoxMatches[1],
|
||||
"path" => "<path d='" . $pathMatches[1] . "'/>"
|
||||
];
|
||||
|
||||
// Add the symbol JSON to the data array
|
||||
$jsonData[] = $symbolJSON;
|
||||
}
|
||||
}
|
||||
|
||||
return $jsonData;
|
||||
}
|
||||
|
||||
// Read the SVG file (assumes it's in the same directory)
|
||||
$svgFilePath = 'input.svg'; // The input SVG file
|
||||
if (file_exists($svgFilePath)) {
|
||||
$svgContent = file_get_contents($svgFilePath);
|
||||
|
||||
// Convert symbols to JSON
|
||||
$symbolsJson = convertSymbolsToJSON($svgContent);
|
||||
|
||||
// Output the JSON data to a file
|
||||
$outputFilePath = 'output.json';
|
||||
file_put_contents($outputFilePath, json_encode($symbolsJson, JSON_PRETTY_PRINT));
|
||||
|
||||
echo "JSON file has been created successfully: $outputFilePath\n";
|
||||
} else {
|
||||
echo "Error: SVG file not found.\n";
|
||||
}
|
||||
?>
|
||||
57
assets/json/demo-posts.json
Normal file
57
assets/json/demo-posts.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"posts": [
|
||||
{
|
||||
"title": "Mysterious Weather Patterns Reported in Faketown",
|
||||
"content": "Faketown, USA — In what can only be described as a strange turn of events, Faketown residents have been experiencing unpredictable weather patterns. Local meteorologists have been baffled as sudden temperature shifts have been occurring at all hours of the day. One moment, the sun is shining brightly, and the next, it's snowing. This bizarre occurrence is leaving many questioning whether this is a sign of something more ominous. 'I’ve lived here my entire life, and I’ve never seen anything like this,' said local resident Jane Doe.",
|
||||
"excerpt": "Faketown residents have been experiencing unpredictable weather patterns, baffling local meteorologists.",
|
||||
"category": "Local News",
|
||||
"tags": ["weather", "Faketown", "mystery"],
|
||||
"date": "2024-01-01",
|
||||
"status": "publish",
|
||||
"thumbnail": "demo-post-thumbnail-1.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Faketown Mayor Announces New Green Initiative",
|
||||
"content": "In a recent press conference, Faketown’s mayor, John Smith, unveiled an ambitious plan to tackle climate change within the city. The initiative aims to reduce carbon emissions by 40% over the next 10 years, primarily by encouraging the use of electric vehicles and expanding the city's public transportation system. 'We are committed to making Faketown a greener place,' said Mayor Smith. 'Our children and grandchildren deserve a sustainable future.' The plan includes installing charging stations for electric cars across the city and offering tax incentives for green energy solutions.",
|
||||
"excerpt": "Faketown’s mayor unveils a new green initiative to reduce carbon emissions by 40%.",
|
||||
"category": "Politics",
|
||||
"tags": ["green", "climate change", "Faketown"],
|
||||
"date": "2024-01-02",
|
||||
"status": "publish",
|
||||
"thumbnail": "demo-post-thumbnail-2.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Local Chef Opens Revolutionary Restaurant in Faketown",
|
||||
"content": "Faketown, USA — In a culinary first for Faketown, renowned chef Sarah Bellamy has opened a new restaurant that combines traditional American cuisine with exotic flavors from around the world. Located in the heart of Faketown, Bellamy’s restaurant has already become the talk of the town. The menu features a variety of dishes, including 'Fusion Fries' and 'Sushi Burger.' 'I wanted to create something completely unique, a blend of cultures,' said Bellamy. The restaurant offers both dine-in and delivery services, with plans to expand its menu soon.",
|
||||
"excerpt": "Faketown's new restaurant is offering a fusion of global flavors with a local twist.",
|
||||
"category": "Food & Drink",
|
||||
"tags": ["restaurant", "food", "Faketown"],
|
||||
"date": "2024-01-03",
|
||||
"status": "publish",
|
||||
"thumbnail": "demo-post-thumbnail-3.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Strange Creatures Spotted in Faketown's Forests",
|
||||
"content": "In the deep forests surrounding Faketown, local hikers have begun reporting sightings of strange creatures. Descriptions vary, but many claim to have seen large, mysterious beings with glowing eyes. Some hikers have even reported hearing unusual sounds that have no obvious explanation. 'I was out for a hike last week when I saw something huge moving through the trees,' said Greg Johnson, a local resident. 'I don’t know what it was, but it wasn’t a bear.' Authorities are urging hikers to stay on well-trodden paths and report any strange occurrences.",
|
||||
"excerpt": "Faketown residents report strange creatures spotted in nearby forests, baffling experts.",
|
||||
"category": "Strange Happenings",
|
||||
"tags": ["mystery", "Faketown", "creatures"],
|
||||
"date": "2024-01-04",
|
||||
"status": "publish",
|
||||
"thumbnail": "demo-post-thumbnail-1.jpg"
|
||||
|
||||
},
|
||||
{
|
||||
"title": "Faketown's Annual Festival Breaks Attendance Records",
|
||||
"content": "This year's annual Faketown Festival was a resounding success, breaking all previous attendance records. Held in the town square, the festival featured local bands, food trucks, and street performances. The highlight of the event was the traditional 'Faketown Parade,' which saw thousands of people lining the streets. 'We’ve never seen this many people come out,' said event coordinator Lisa Thompson. The festival’s success has sparked excitement about next year’s event, with many suggesting that Faketown could become a regional hub for arts and culture.",
|
||||
"excerpt": "Faketown’s annual festival saw record-breaking attendance, with thousands of people participating.",
|
||||
"category": "Community Events",
|
||||
"tags": ["festival", "community", "Faketown"],
|
||||
"date": "2024-01-05",
|
||||
"status": "publish",
|
||||
"thumbnail": "demo-post-thumbnail-2.jpg"
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Path to the input JSON file
|
||||
$inputFile = 'font-awesome-v6.1.7-solid-svgs.json';
|
||||
|
||||
// Step 1: Load the JSON data
|
||||
$jsonData = file_get_contents($inputFile);
|
||||
|
||||
// Check if the file was read successfully
|
||||
if ($jsonData === false) {
|
||||
die("Error reading the JSON file.");
|
||||
}
|
||||
|
||||
// Step 2: Decode the JSON data into a PHP array
|
||||
$data = json_decode($jsonData, true);
|
||||
|
||||
// Check if JSON decoding was successful
|
||||
if ($data === null) {
|
||||
die("Error decoding the JSON data.");
|
||||
}
|
||||
|
||||
// Step 3: Modify the structure by extracting the 'd' value and formatting the 'paths' tag
|
||||
foreach ($data as $index => $iconSet) {
|
||||
if (isset($iconSet['svgs']) && is_array($iconSet['svgs'])) {
|
||||
foreach ($iconSet['svgs'] as $svgIndex => $svg) {
|
||||
// Check if 'path' exists
|
||||
if (isset($svg['path'])) {
|
||||
// Extract the 'd' attribute value from the nested path string
|
||||
preg_match('/d=[\'"]([^\'"]+)[\'"]/i', $svg['path'], $matches);
|
||||
|
||||
// If we found the 'd' value, format the paths correctly
|
||||
if (isset($matches[1])) {
|
||||
$dValue = $matches[1]; // Get the actual 'd' value from the path
|
||||
|
||||
// Escape the 'd' value for JSON format (escape double quotes inside the string)
|
||||
$escapedDValue = str_replace('"', '\\"', $dValue);
|
||||
|
||||
// Now, add the proper <path> tag to the 'paths' field
|
||||
$svg['paths'] = "<path d=\"{$escapedDValue}\"/>";
|
||||
}
|
||||
|
||||
unset($svg['path']); // Optionally remove the original 'path' key
|
||||
}
|
||||
// Save the modified svg back to the array
|
||||
$data[$index]['svgs'][$svgIndex] = $svg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optional: Save the modified JSON to a new file
|
||||
$outputFile = 'solid-fixed-paths.json';
|
||||
file_put_contents($outputFile, json_encode($data, JSON_PRETTY_PRINT));
|
||||
|
||||
// Output the success message
|
||||
echo "Successfully modified and saved the JSON file with 'path' converted to 'paths'.\n";
|
||||
|
||||
?>
|
||||
@ -1,63 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Path to the input JSON file
|
||||
$inputFile = 'material-icons-twotone.json';
|
||||
// Path to the output JSON file
|
||||
$outputFile = 'material-icons-twotone-unescaped-with-ids.json';
|
||||
|
||||
// Function to generate a MySQL-style UUID
|
||||
function generateUUID() {
|
||||
// Generates a version 4 UUID (random)
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000,
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
|
||||
);
|
||||
}
|
||||
|
||||
// Step 1: Load the JSON data
|
||||
$jsonData = file_get_contents($inputFile);
|
||||
|
||||
// Check if the file was read successfully
|
||||
if ($jsonData === false) {
|
||||
die("Error reading the JSON file.");
|
||||
}
|
||||
|
||||
// Step 2: Decode the JSON data into a PHP array
|
||||
$data = json_decode($jsonData, true);
|
||||
|
||||
// Check if JSON decoding was successful
|
||||
if ($data === null) {
|
||||
die("Error decoding the JSON data.");
|
||||
}
|
||||
|
||||
// Step 3: Iterate through each item and unescape the 'paths' key, and generate a new 'id'
|
||||
foreach ($data as &$icon) {
|
||||
// Unescape only HTML entities (without affecting forward slashes)
|
||||
$icon['paths'] = html_entity_decode($icon['paths'], ENT_QUOTES | ENT_HTML5);
|
||||
|
||||
// Generate a new MySQL-style UUID for each 'id'
|
||||
$icon['id'] = generateUUID();
|
||||
}
|
||||
|
||||
// Step 4: Encode the modified data back into JSON format
|
||||
$newJsonData = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
|
||||
// Check if encoding was successful
|
||||
if ($newJsonData === false) {
|
||||
die("Error encoding the JSON data.");
|
||||
}
|
||||
|
||||
// Step 5: Save the modified JSON data to the output file
|
||||
file_put_contents($outputFile, $newJsonData);
|
||||
|
||||
// Check if file writing was successful
|
||||
if (file_put_contents($outputFile, $newJsonData) === false) {
|
||||
die("Error saving the modified JSON data.");
|
||||
}
|
||||
|
||||
echo "Paths have been unescaped, IDs have been added, and saved to '$outputFile'.\n";
|
||||
|
||||
?>
|
||||
@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Function to capitalize the 'name' field (capitalizes acronyms fully)
|
||||
function capitalizeName($name) {
|
||||
// Define a pattern to match acronyms (words in uppercase with no spaces)
|
||||
$acronymPattern = '/\b[A-Z]{2,}\b/';
|
||||
|
||||
// Capitalize each word, and keep acronyms fully uppercase
|
||||
$name = preg_replace_callback('/\b\w+\b/', function ($matches) use ($acronymPattern) {
|
||||
$word = $matches[0];
|
||||
// If it's an acronym (all uppercase), return as is
|
||||
if (preg_match($acronymPattern, $word)) {
|
||||
return strtoupper($word);
|
||||
}
|
||||
// Otherwise capitalize the first letter of each word and lowercase the rest
|
||||
return ucfirst(strtolower($word));
|
||||
}, $name);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
// Function to generate a MySQL UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
|
||||
function generateMysqlUuid() {
|
||||
// Generate a UUID using PHP's random_bytes for a total of 16 random bytes
|
||||
$data = random_bytes(16);
|
||||
|
||||
// Set the version to 4 (random UUID)
|
||||
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Version 4
|
||||
// Set the variant to RFC4122
|
||||
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // RFC4122 variant
|
||||
|
||||
// Now unpack the data into 5 parts for formatting as UUID
|
||||
$hexData = unpack('H8a/H4b/H4c/H4d/H12e', $data);
|
||||
|
||||
// Return the UUID in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
return $hexData['a'] . '-' . $hexData['b'] . '-' . $hexData['c'] . '-' . $hexData['d'] . '-' . $hexData['e'];
|
||||
}
|
||||
|
||||
// Get the current directory of the script
|
||||
$currentDir = __DIR__;
|
||||
|
||||
// Get all JSON files in the current directory
|
||||
$jsonFiles = glob($currentDir . '/*.json');
|
||||
|
||||
// Iterate over each JSON file
|
||||
foreach ($jsonFiles as $file) {
|
||||
// Read the content of the file
|
||||
$jsonContent = file_get_contents($file);
|
||||
|
||||
// Decode JSON to array
|
||||
$data = json_decode($jsonContent, true);
|
||||
|
||||
// Check if the data is valid
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
// Process each SVG object
|
||||
foreach ($data as &$set) {
|
||||
if (isset($set['svgs'])) {
|
||||
foreach ($set['svgs'] as &$svg) {
|
||||
// Capitalize the 'name' field
|
||||
if (isset($svg['name'])) {
|
||||
$svg['name'] = capitalizeName($svg['name']);
|
||||
}
|
||||
|
||||
// Generate a new MySQL UUID for the 'id' field
|
||||
if (isset($svg['id'])) {
|
||||
$svg['id'] = generateMysqlUuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-encode the modified data to JSON
|
||||
$newJsonContent = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
// Define the output file name (you can change this as needed)
|
||||
$outputFile = $currentDir . '/modified_' . basename($file);
|
||||
|
||||
// Save the updated content back to a new file
|
||||
file_put_contents($outputFile, $newJsonContent);
|
||||
|
||||
echo "Processed and saved to: " . basename($outputFile) . "\n";
|
||||
} else {
|
||||
echo "Invalid JSON in file: " . basename($file) . "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
826
functions.php
826
functions.php
@ -4,7 +4,7 @@
|
||||
|
||||
|
||||
include get_template_directory() . '/includes/classes/wp-hooks.php';
|
||||
include get_template_directory() . '/includes/classes/lcp-newsletters.php';
|
||||
|
||||
|
||||
//include get_template_directory(). '/includes/blocks/lcp-gallery/lcp-gallery.php';
|
||||
include get_template_directory() . '/includes/classes/blocks.php';
|
||||
@ -45,14 +45,6 @@ add_action('wp_enqueue_scripts', 'lcp_enqueue');
|
||||
|
||||
|
||||
|
||||
function lcp_backend_enqueue() {
|
||||
// Enqueue the theme's main stylesheet (style.css)
|
||||
wp_enqueue_style('lcp-style', get_stylesheet_uri());
|
||||
wp_enqueue_script('lcp-script', get_template_directory_uri() . '/script.js');
|
||||
|
||||
}
|
||||
|
||||
add_action('admin_enqueue_scripts', 'lcp_enqueue');
|
||||
|
||||
|
||||
/* KEY POINTS */
|
||||
@ -178,36 +170,10 @@ function drop_lcp_icons_table() {
|
||||
|
||||
|
||||
|
||||
/* BACKEND ICON ADDER */
|
||||
// Register the dashboard page in the admin menu
|
||||
function mytheme_register_dashboard_page() {
|
||||
add_menu_page(
|
||||
'Icon Management', // Page Title
|
||||
'Icon Management', // Menu Title
|
||||
'manage_options', // Capability
|
||||
'icon-management', // Menu Slug
|
||||
'mytheme_dashboard_page', // Callback function
|
||||
'dashicons-images-alt2', // Icon for the menu item
|
||||
60 // Position
|
||||
);
|
||||
}
|
||||
add_action('admin_menu', 'mytheme_register_dashboard_page');
|
||||
|
||||
// Callback function to display the dashboard page content
|
||||
function mytheme_dashboard_page() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php esc_html_e('Icon Management Dashboard', 'mytheme'); ?></h1>
|
||||
<div id="icon-dashboard-container">
|
||||
<?php mytheme_display_icon_sets(); ?>
|
||||
</div> <!-- This will be populated by PHP -->
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
// Function to read and display icon sets from the JSON file
|
||||
// Function to read and display icon sets from the JSON file
|
||||
function mytheme_display_icon_sets() {
|
||||
function lcp_display_icon_sets() {
|
||||
// Path to the JSON file
|
||||
$json_path = get_template_directory() . '/assets/json/icons/icon-definitions.json';
|
||||
|
||||
@ -238,16 +204,16 @@ function mytheme_display_icon_sets() {
|
||||
|
||||
|
||||
// Enqueue the dashboard styles only on the icon-management page
|
||||
function mytheme_enqueue_dashboard_styles($hook) {
|
||||
function lcp_enqueue_dashboard_styles($hook) {
|
||||
|
||||
|
||||
// Enqueue CSS for the dashboard
|
||||
wp_enqueue_style(
|
||||
'mytheme-dashboard-css',
|
||||
'lcp-dashboard-css',
|
||||
get_template_directory_uri() . '/assets/css/dashboard.css'
|
||||
);
|
||||
}
|
||||
add_action('admin_enqueue_scripts', 'mytheme_enqueue_dashboard_styles');
|
||||
add_action('admin_enqueue_scripts', 'lcp_enqueue_dashboard_styles');
|
||||
|
||||
|
||||
// Handle the AJAX request for installing icon sets
|
||||
@ -311,7 +277,7 @@ function lcp_install_icon_set($defaults = false) {
|
||||
$icon_set_id = intval($_POST['icon_set_id']);
|
||||
|
||||
// Create the database table if it doesn't exist
|
||||
mytheme_create_icons_table();
|
||||
lcp_create_icons_table();
|
||||
|
||||
// Read the icon definitions JSON file
|
||||
if (file_exists($json_path)) {
|
||||
@ -384,7 +350,7 @@ add_action('wp_ajax_install_icon_set', 'lcp_install_icon_set');
|
||||
|
||||
|
||||
// Function to create the icons table in the database if it doesn't exist
|
||||
function mytheme_create_icons_table() {
|
||||
function lcp_create_icons_table() {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'lcp_icons';
|
||||
@ -409,29 +375,10 @@ function mytheme_create_icons_table() {
|
||||
}
|
||||
|
||||
|
||||
function mytheme_enqueue_dashboard_scripts($hook) {
|
||||
// Only load the script on the icon-management page
|
||||
|
||||
|
||||
// Enqueue JavaScript for AJAX
|
||||
wp_enqueue_script(
|
||||
'icon-import-script',
|
||||
get_template_directory_uri() . '/assets/js/icon-import.js',
|
||||
array(), // No dependencies for vanilla JS
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
// Pass the AJAX URL to the script
|
||||
wp_localize_script('icon-import-script', 'mytheme_ajax', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php')
|
||||
));
|
||||
}
|
||||
add_action('admin_enqueue_scripts', 'mytheme_enqueue_dashboard_scripts');
|
||||
|
||||
|
||||
// Handle the AJAX request for uninstalling icon sets
|
||||
function mytheme_uninstall_icon_set() {
|
||||
function lcp_uninstall_icon_set() {
|
||||
// Ensure icon set ID is passed in the request
|
||||
if (!isset($_POST['icon_set_id'])) {
|
||||
wp_send_json_error(array('message' => 'Invalid icon set ID.'));
|
||||
@ -460,6 +407,761 @@ function mytheme_uninstall_icon_set() {
|
||||
}
|
||||
}
|
||||
|
||||
add_action('wp_ajax_uninstall_icon_set', 'mytheme_uninstall_icon_set');
|
||||
add_action('wp_ajax_uninstall_icon_set', 'lcp_uninstall_icon_set');
|
||||
|
||||
/* Import Demo Posts */
|
||||
function lcp_import_demo_posts() {
|
||||
$json_data = file_get_contents(get_template_directory() . '/assets/json/demo-posts.json');
|
||||
|
||||
// Check if the JSON data is successfully fetched and decoded
|
||||
if (empty($json_data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$posts = json_decode($json_data, true)['posts'];
|
||||
|
||||
if (empty($posts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Arrays to store post IDs and media (thumbnail) IDs
|
||||
$post_ids = [];
|
||||
$media_ids = [];
|
||||
|
||||
foreach ($posts as $post) {
|
||||
// Prepare post data
|
||||
$post_data = array(
|
||||
'post_title' => wp_strip_all_tags($post['title']),
|
||||
'post_content' => $post['content'],
|
||||
'post_excerpt' => isset($post['excerpt']) ? $post['excerpt'] : '',
|
||||
'post_status' => isset($post['status']) ? $post['status'] : 'draft', // Default to 'draft' if no status
|
||||
'post_date' => isset($post['date']) ? $post['date'] : current_time('mysql'),
|
||||
'post_type' => 'post',
|
||||
'post_author' => 1, // Change if you have specific user IDs
|
||||
);
|
||||
|
||||
// Insert the post into the database
|
||||
$post_id = wp_insert_post($post_data);
|
||||
|
||||
// If there was an issue inserting the post, skip this one
|
||||
if (is_wp_error($post_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store the post ID in the array
|
||||
$post_ids[] = $post_id;
|
||||
|
||||
// Assign categories (if they exist)
|
||||
if (!empty($post['category'])) {
|
||||
$category = term_exists($post['category'], 'category');
|
||||
if ($category) {
|
||||
wp_set_post_terms($post_id, array($category['term_id']), 'category');
|
||||
} else {
|
||||
// If category doesn't exist, create it
|
||||
$category_id = wp_create_term($post['category'], 'category');
|
||||
wp_set_post_terms($post_id, array($category_id['term_id']), 'category');
|
||||
}
|
||||
}
|
||||
|
||||
// Assign tags (if they exist)
|
||||
if (!empty($post['tags'])) {
|
||||
wp_set_post_terms($post_id, $post['tags'], 'post_tag');
|
||||
}
|
||||
|
||||
// Handle thumbnail (featured image)
|
||||
if (!empty($post['thumbnail'])) {
|
||||
$thumbnail_url = get_template_directory_uri() . '/assets/img/demo-post-thumbnails/' . $post['thumbnail'];
|
||||
|
||||
// Download the image and add it to the media library
|
||||
$thumbnail_id = media_handle_sideload(
|
||||
array(
|
||||
'name' => basename($thumbnail_url),
|
||||
'tmp_name' => download_url($thumbnail_url)
|
||||
),
|
||||
$post_id
|
||||
);
|
||||
|
||||
// If the image was uploaded successfully, set it as the post's featured image
|
||||
if (!is_wp_error($thumbnail_id)) {
|
||||
set_post_thumbnail($post_id, $thumbnail_id);
|
||||
// Store the media ID in the array
|
||||
$media_ids[] = $thumbnail_id;
|
||||
}
|
||||
}
|
||||
|
||||
// You can add additional meta fields if necessary
|
||||
// Example:
|
||||
// update_post_meta($post_id, 'some_meta_key', 'some_value');
|
||||
}
|
||||
|
||||
// After all posts are imported, update the 'lcp_demo_posts' option
|
||||
$demo_posts_data = array(
|
||||
'post_ids' => $post_ids,
|
||||
'media_ids' => $media_ids,
|
||||
);
|
||||
update_option('lcp_demo_posts', $demo_posts_data);
|
||||
|
||||
// Optionally, you can log the post and media IDs
|
||||
// var_dump($post_ids, $media_ids); // Uncomment this line if you need to inspect the result
|
||||
}
|
||||
|
||||
|
||||
/* Delete the Demo Posts */
|
||||
// Get the lcp_demo_posts option and delete all the posts from there
|
||||
function lcp_delete_demo_posts() {
|
||||
// Get the lcp_demo_posts option
|
||||
$demo_posts_data = get_option('lcp_demo_posts');
|
||||
|
||||
// Check if the option exists and contains data
|
||||
if (!empty($demo_posts_data) && isset($demo_posts_data['post_ids']) && isset($demo_posts_data['media_ids'])) {
|
||||
// Loop through and delete posts
|
||||
foreach ($demo_posts_data['post_ids'] as $post_id) {
|
||||
// Delete post, force delete if necessary (set true for delete permanently)
|
||||
wp_delete_post($post_id, true); // true will permanently delete
|
||||
}
|
||||
|
||||
// Loop through and delete media (attachments)
|
||||
foreach ($demo_posts_data['media_ids'] as $media_id) {
|
||||
// Delete attachment (media file)
|
||||
wp_delete_attachment($media_id, true); // true will permanently delete
|
||||
}
|
||||
|
||||
// After deletion, remove the option from wp_options table
|
||||
delete_option('lcp_demo_posts');
|
||||
|
||||
// Optionally, you can log the deletion for confirmation
|
||||
// error_log('Demo posts and media have been deleted.');
|
||||
} else {
|
||||
// If the option doesn't exist, or it's empty
|
||||
error_log('No demo posts data found or already deleted.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Localize */
|
||||
add_action('wp_ajax_lcp_import_demo_posts', 'lcp_import_demo_posts_ajax_handler');
|
||||
|
||||
// Define the function to handle the AJAX request
|
||||
function lcp_import_demo_posts_ajax_handler() {
|
||||
// Check for permissions (optional: can be used to ensure only admins can trigger this)
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('You do not have sufficient permissions to perform this action.');
|
||||
}
|
||||
|
||||
// Call the existing function that imports the demo posts
|
||||
lcp_import_demo_posts();
|
||||
|
||||
// Send a success response back to the browser
|
||||
wp_send_json_success('Demo posts imported successfully.');
|
||||
}
|
||||
|
||||
add_action('wp_ajax_lcp_delete_demo_posts', 'lcp_delete_demo_posts_ajax_handler');
|
||||
|
||||
// Define the function to handle the delete demo posts AJAX request
|
||||
function lcp_delete_demo_posts_ajax_handler() {
|
||||
// Verify nonce for security
|
||||
if (!isset($_POST['lcp_import_nonce']) || !wp_verify_nonce($_POST['lcp_import_nonce'], 'lcp_import_demo_posts_nonce')) {
|
||||
wp_send_json_error('Invalid nonce');
|
||||
}
|
||||
|
||||
// Check if the current user has permissions to manage options
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('You do not have sufficient permissions to perform this action.');
|
||||
}
|
||||
|
||||
// Call the function that deletes the demo posts
|
||||
lcp_delete_demo_posts();
|
||||
|
||||
// Send a success response back to the browser
|
||||
wp_send_json_success('Demo posts deleted successfully.');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Set a visited post cookies
|
||||
// Hooked into send_headers via wp-hooks.php
|
||||
|
||||
function lcp_set_visited_posts_cookie() {
|
||||
// Only track posts on single post pages
|
||||
if (is_single()) {
|
||||
// Get the current post's ID and post type
|
||||
$current_post_id = get_the_ID();
|
||||
$post_type = get_post_type();
|
||||
$visit_time = time(); // Get the current time as a Unix timestamp
|
||||
|
||||
// Check if the cookie exists
|
||||
if (isset($_COOKIE['lcp_visited_posts'])) {
|
||||
// Decode the cookie's JSON value
|
||||
$visited_posts = json_decode(stripslashes($_COOKIE['lcp_visited_posts']), true);
|
||||
|
||||
// Check if decoding was successful and if the format is correct
|
||||
if (json_last_error() !== JSON_ERROR_NONE || !is_array($visited_posts)) {
|
||||
// If the cookie is not valid, delete the cookie and start over
|
||||
setcookie('lcp_visited_posts', '', time() - 3600, '/'); // Expire the cookie
|
||||
$visited_posts = []; // Initialize an empty array
|
||||
}
|
||||
} else {
|
||||
// Initialize an empty array if the cookie doesn't exist
|
||||
$visited_posts = [];
|
||||
}
|
||||
|
||||
// If the post type is not already in the cookie, initialize it as an empty array
|
||||
if (!isset($visited_posts[$post_type])) {
|
||||
$visited_posts[$post_type] = [];
|
||||
}
|
||||
|
||||
// Add the current post ID and the visit timestamp as an array entry
|
||||
// Ensure that the post ID isn't already added for this post type
|
||||
$found = false;
|
||||
foreach ($visited_posts[$post_type] as &$post) {
|
||||
if (array_key_exists($current_post_id, $post)) {
|
||||
$post[$current_post_id] = $visit_time; // Update the timestamp if post already exists
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If post wasn't found, add it as a new entry
|
||||
if (!$found) {
|
||||
$visited_posts[$post_type][] = [$current_post_id => $visit_time];
|
||||
}
|
||||
|
||||
// Encode the updated visited posts array to JSON
|
||||
$cookie_value = json_encode($visited_posts);
|
||||
|
||||
// Set the cookie with a 30-day expiration time (this must be done before any output)
|
||||
setcookie('lcp_visited_posts', $cookie_value, time() + (30 * 24 * 60 * 60), '/'); // '/' makes the cookie available across the whole site
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* CUSTOM IMAGE SIZES */
|
||||
function lcp_update_image_sizes() {
|
||||
// Verify nonce for security
|
||||
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'custom_image_sizes_nonce')) {
|
||||
wp_send_json_error(array('message' => 'Nonce validation failed.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if image_sizes data is provided
|
||||
if (isset($_POST['image_sizes'])) {
|
||||
$image_sizes = json_decode(stripslashes($_POST['image_sizes']), true); // Decode JSON data
|
||||
|
||||
// Make sure that the image_sizes data is valid
|
||||
if (!is_array($image_sizes)) {
|
||||
wp_send_json_error(array('message' => 'Invalid image sizes data.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Process the data (e.g., update options)
|
||||
update_option('lcp_image_sizes', $image_sizes);
|
||||
|
||||
// Return success message
|
||||
wp_send_json_success(array('message' => 'Image sizes updated successfully.'));
|
||||
} else {
|
||||
wp_send_json_error(array('message' => 'No image sizes data received.'));
|
||||
}
|
||||
}
|
||||
|
||||
add_action('wp_ajax_update_lcp_theme_settings', 'lcp_update_image_sizes');
|
||||
add_action('wp_ajax_nopriv_update_lcp_theme_settings', 'lcp_update_image_sizes');
|
||||
|
||||
function lcp_register_custom_image_sizes() {
|
||||
// Retrieve the 'lcp_image_sizes' option, which is already unserialized by WordPress
|
||||
$custom_image_sizes = get_option('lcp_image_sizes');
|
||||
|
||||
// Check if the option exists and is an array (because WordPress auto-unserializes the data)
|
||||
if ($custom_image_sizes && is_array($custom_image_sizes)) {
|
||||
// Loop through the array and register each image size
|
||||
foreach ($custom_image_sizes as $size) {
|
||||
// Ensure the size has the correct keys and valid values
|
||||
if (isset($size['name'], $size['width'], $size['height'], $size['crop']) && !empty($size['name'])) {
|
||||
// Sanitize the name, but ensure it's not just a number like '1'
|
||||
$name = sanitize_key($size['name']);
|
||||
$width = (int) $size['width']; // Cast to integer
|
||||
$height = (int) $size['height']; // Cast to integer
|
||||
$crop = (bool) $size['crop']; // Convert to boolean
|
||||
|
||||
// Register the custom image size
|
||||
add_image_size($name, $width, $height, $crop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Hook into WordPress to register custom sizes
|
||||
add_action('after_setup_theme', 'lcp_register_custom_image_sizes');
|
||||
|
||||
|
||||
/* CUSTOM POST TYPES */
|
||||
|
||||
|
||||
// Register the post meta field for the gallery
|
||||
function to_register_meta_fields() {
|
||||
register_post_meta('post', 'lcp_post_gallery', [
|
||||
'type' => 'array',
|
||||
'description' => 'Custom post gallery',
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
]);
|
||||
}
|
||||
add_action('init', 'to_register_meta_fields');
|
||||
|
||||
// Add meta box for the gallery
|
||||
function add_lcp_gallery_meta_box() {
|
||||
add_meta_box(
|
||||
'lcp_gallery_meta_box',
|
||||
__('Post Gallery', 'textdomain'),
|
||||
'render_lcp_gallery_meta_box',
|
||||
'post',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
add_action('add_meta_boxes', 'add_lcp_gallery_meta_box');
|
||||
|
||||
// Render the meta box
|
||||
function render_lcp_gallery_meta_box($post) {
|
||||
// Add nonce for security
|
||||
wp_nonce_field('lcp_gallery_meta_box', 'lcp_gallery_meta_box_nonce');
|
||||
|
||||
// Get existing gallery items
|
||||
$gallery_items = get_post_meta($post->ID, 'lcp_gallery', true);
|
||||
if (!is_array($gallery_items)) {
|
||||
$gallery_items = array();
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
#lcp-gallery-list li {
|
||||
cursor: move;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
position: relative;
|
||||
}
|
||||
#lcp-gallery-list li.dragging {
|
||||
opacity: 0.5;
|
||||
border: 2px dashed #999;
|
||||
}
|
||||
.drag-handle {
|
||||
cursor: move;
|
||||
padding: 5px;
|
||||
margin-right: 10px;
|
||||
color: #999;
|
||||
}
|
||||
#lcp-media-source-selector {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.gallery-item-fields {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.gallery-item-fields input[type="text"],
|
||||
.gallery-item-fields textarea {
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.gallery-item-fields label {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.color-picker-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.color-picker-wrapper input[type="color"] {
|
||||
padding: 0;
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
}
|
||||
</style>
|
||||
<div id="lcp-gallery-container">
|
||||
<div id="lcp-media-source-selector">
|
||||
<select id="lcp-media-source">
|
||||
<option value="media_library">Media Library</option>
|
||||
<option value="youtube">YouTube</option>
|
||||
<option value="vimeo">Vimeo</option>
|
||||
</select>
|
||||
<button type="button" class="button" id="add-to-gallery">Add Media</button>
|
||||
</div>
|
||||
<ul id="lcp-gallery-list">
|
||||
<?php
|
||||
foreach ($gallery_items as $item) {
|
||||
$media_source = isset($item['media_source']) ? $item['media_source'] : '';
|
||||
$media_id = isset($item['media_id']) ? $item['media_id'] : '';
|
||||
$url = isset($item['url']) ? $item['url'] : '';
|
||||
$title = isset($item['title']) ? $item['title'] : '';
|
||||
$caption = isset($item['caption']) ? $item['caption'] : '';
|
||||
$background_color = isset($item['background_color']) ? $item['background_color'] : '';
|
||||
|
||||
echo '<li draggable="true" style="background-color: ' . esc_attr($background_color) . ';">';
|
||||
echo '<span class="drag-handle dashicons dashicons-menu"></span>';
|
||||
echo '<input type="hidden" name="lcp_gallery[]" value="' . esc_attr(json_encode($item)) . '">';
|
||||
|
||||
if ($media_source === 'media_library' && $media_id) {
|
||||
$image = wp_get_attachment_image_src($media_id, 'thumbnail');
|
||||
if ($image) {
|
||||
echo '<img src="' . esc_url($image[0]) . '" alt="" style="max-width: 150px; height: auto;">';
|
||||
}
|
||||
} elseif ($media_source === 'youtube' && $url) {
|
||||
echo '<div class="youtube-thumbnail" style="width: 150px; height: 150px; background: #f0f0f0; display: flex; align-items: center; justify-content: center;">';
|
||||
echo '<span class="dashicons dashicons-youtube"></span>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// Add fields for title, caption, and background color
|
||||
echo '<div class="gallery-item-fields">';
|
||||
echo '<label>Title</label>';
|
||||
echo '<input type="text" class="gallery-item-title" value="' . esc_attr($title) . '" placeholder="Enter title">';
|
||||
|
||||
echo '<label>Caption</label>';
|
||||
echo '<textarea class="gallery-item-caption" rows="3" placeholder="Enter caption">' . esc_textarea($caption) . '</textarea>';
|
||||
|
||||
echo '<label>Background Color</label>';
|
||||
echo '<div class="color-picker-wrapper">';
|
||||
echo '<input type="color" class="gallery-item-bgcolor" value="' . esc_attr($background_color) . '">';
|
||||
echo '<button type="button" class="button update-bgcolor">Update Background</button>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
|
||||
echo '<button type="button" class="button remove-gallery-item">Remove</button>';
|
||||
echo '</li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize gallery items array from PHP
|
||||
let galleryItems = <?php echo json_encode($gallery_items); ?>;
|
||||
console.log('Initial gallery items:', galleryItems);
|
||||
|
||||
// Function to update hidden input values and maintain state
|
||||
function updateHiddenInputs() {
|
||||
const list = document.querySelector('#lcp-gallery-list');
|
||||
list.innerHTML = ''; // Clear the list
|
||||
|
||||
console.log('Updating gallery items:', galleryItems);
|
||||
|
||||
// Rebuild the list with current items
|
||||
galleryItems.forEach((item, index) => {
|
||||
const li = document.createElement('li');
|
||||
li.draggable = true;
|
||||
if (item.background_color) {
|
||||
li.style.backgroundColor = item.background_color;
|
||||
}
|
||||
|
||||
// Add drag handle
|
||||
const dragHandle = document.createElement('span');
|
||||
dragHandle.className = 'drag-handle dashicons dashicons-menu';
|
||||
li.appendChild(dragHandle);
|
||||
|
||||
// Add hidden input with item data
|
||||
const input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input.name = 'lcp_gallery[]';
|
||||
input.value = JSON.stringify(item);
|
||||
li.appendChild(input);
|
||||
|
||||
// Add thumbnail
|
||||
if (item.media_source === 'media_library' && item.media_id) {
|
||||
wp.media.attachment(item.media_id).fetch().then(function() {
|
||||
const img = document.createElement('img');
|
||||
img.src = wp.media.attachment(item.media_id).get('url');
|
||||
img.style = 'max-width: 150px; height: auto;';
|
||||
li.appendChild(img);
|
||||
});
|
||||
} else if (item.media_source === 'youtube' && item.url) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'youtube-thumbnail';
|
||||
div.style = 'width: 150px; height: 150px; background: #f0f0f0; display: flex; align-items: center; justify-content: center;';
|
||||
div.innerHTML = '<span class="dashicons dashicons-youtube"></span>';
|
||||
li.appendChild(div);
|
||||
}
|
||||
|
||||
// Add fields container
|
||||
const fields = document.createElement('div');
|
||||
fields.className = 'gallery-item-fields';
|
||||
|
||||
// Title field
|
||||
const titleLabel = document.createElement('label');
|
||||
titleLabel.textContent = 'Title';
|
||||
fields.appendChild(titleLabel);
|
||||
|
||||
const titleInput = document.createElement('input');
|
||||
titleInput.type = 'text';
|
||||
titleInput.className = 'gallery-item-title';
|
||||
titleInput.value = item.title || '';
|
||||
titleInput.placeholder = 'Enter title';
|
||||
titleInput.addEventListener('input', () => {
|
||||
item.title = titleInput.value;
|
||||
updateItemData(index, item);
|
||||
});
|
||||
fields.appendChild(titleInput);
|
||||
|
||||
// Caption field
|
||||
const captionLabel = document.createElement('label');
|
||||
captionLabel.textContent = 'Caption';
|
||||
fields.appendChild(captionLabel);
|
||||
|
||||
const captionInput = document.createElement('textarea');
|
||||
captionInput.className = 'gallery-item-caption';
|
||||
captionInput.rows = 3;
|
||||
captionInput.value = item.caption || '';
|
||||
captionInput.placeholder = 'Enter caption';
|
||||
captionInput.addEventListener('input', () => {
|
||||
item.caption = captionInput.value;
|
||||
updateItemData(index, item);
|
||||
});
|
||||
fields.appendChild(captionInput);
|
||||
|
||||
// Background color field
|
||||
const colorLabel = document.createElement('label');
|
||||
colorLabel.textContent = 'Background Color';
|
||||
fields.appendChild(colorLabel);
|
||||
|
||||
const colorWrapper = document.createElement('div');
|
||||
colorWrapper.className = 'color-picker-wrapper';
|
||||
|
||||
const colorInput = document.createElement('input');
|
||||
colorInput.type = 'color';
|
||||
colorInput.className = 'gallery-item-bgcolor';
|
||||
colorInput.value = item.background_color || '#ffffff';
|
||||
|
||||
const updateColorBtn = document.createElement('button');
|
||||
updateColorBtn.type = 'button';
|
||||
updateColorBtn.className = 'button update-bgcolor';
|
||||
updateColorBtn.textContent = 'Update Background';
|
||||
updateColorBtn.addEventListener('click', () => {
|
||||
const newColor = colorInput.value;
|
||||
item.background_color = newColor;
|
||||
li.style.backgroundColor = newColor;
|
||||
updateItemData(index, item);
|
||||
console.log('Color updated for item', index, ':', item);
|
||||
});
|
||||
|
||||
colorInput.addEventListener('input', () => {
|
||||
// Preview the color as user picks
|
||||
li.style.backgroundColor = colorInput.value;
|
||||
});
|
||||
|
||||
colorWrapper.appendChild(colorInput);
|
||||
colorWrapper.appendChild(updateColorBtn);
|
||||
fields.appendChild(colorWrapper);
|
||||
|
||||
li.appendChild(fields);
|
||||
|
||||
// Add remove button
|
||||
const removeBtn = document.createElement('button');
|
||||
removeBtn.type = 'button';
|
||||
removeBtn.className = 'button remove-gallery-item';
|
||||
removeBtn.textContent = 'Remove';
|
||||
removeBtn.onclick = function() {
|
||||
galleryItems.splice(index, 1);
|
||||
console.log('Removed item at index', index, '. New gallery items:', galleryItems);
|
||||
updateHiddenInputs();
|
||||
};
|
||||
li.appendChild(removeBtn);
|
||||
|
||||
// Add drag and drop event listeners
|
||||
li.addEventListener('dragstart', handleDragStart);
|
||||
li.addEventListener('dragend', handleDragEnd);
|
||||
li.addEventListener('dragover', handleDragOver);
|
||||
li.addEventListener('drop', handleDrop);
|
||||
|
||||
list.appendChild(li);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to update a specific item's data
|
||||
function updateItemData(index, item) {
|
||||
galleryItems[index] = item;
|
||||
const input = document.querySelector(`#lcp-gallery-list li:nth-child(${index + 1}) input[name^="lcp_gallery"]`);
|
||||
if (input) {
|
||||
input.value = JSON.stringify(item);
|
||||
console.log('Updated item at index', index, ':', item);
|
||||
console.log('Current gallery items:', galleryItems);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the list with existing items
|
||||
if (galleryItems.length > 0) {
|
||||
console.log('Initializing gallery with existing items:', galleryItems);
|
||||
updateHiddenInputs();
|
||||
}
|
||||
|
||||
// Handle drag and drop
|
||||
let draggedItem = null;
|
||||
let draggedIndex = null;
|
||||
|
||||
function handleDragStart(e) {
|
||||
draggedItem = this;
|
||||
draggedIndex = Array.from(draggedItem.parentNode.children).indexOf(draggedItem);
|
||||
this.classList.add('dragging');
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
console.log('Started dragging item at index:', draggedIndex);
|
||||
}
|
||||
|
||||
function handleDragEnd(e) {
|
||||
this.classList.remove('dragging');
|
||||
draggedItem = null;
|
||||
draggedIndex = null;
|
||||
}
|
||||
|
||||
function handleDragOver(e) {
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
}
|
||||
|
||||
function handleDrop(e) {
|
||||
e.preventDefault();
|
||||
if (draggedItem === this) return;
|
||||
|
||||
const droppedIndex = Array.from(this.parentNode.children).indexOf(this);
|
||||
console.log('Dropping item from index', draggedIndex, 'to index', droppedIndex);
|
||||
|
||||
// Reorder galleryItems array
|
||||
const [movedItem] = galleryItems.splice(draggedIndex, 1);
|
||||
galleryItems.splice(droppedIndex, 0, movedItem);
|
||||
|
||||
console.log('Reordered gallery items:', galleryItems);
|
||||
updateHiddenInputs();
|
||||
}
|
||||
|
||||
// Initialize the media frame
|
||||
let mediaFrame;
|
||||
document.getElementById('add-to-gallery').addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
const source = document.getElementById('lcp-media-source').value;
|
||||
|
||||
if (source === 'media_library') {
|
||||
if (mediaFrame) {
|
||||
mediaFrame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
mediaFrame = wp.media({
|
||||
title: 'Select Media',
|
||||
button: {
|
||||
text: 'Add to Gallery'
|
||||
},
|
||||
multiple: false
|
||||
});
|
||||
|
||||
mediaFrame.on('select', function() {
|
||||
const attachment = mediaFrame.state().get('selection').first().toJSON();
|
||||
const item = {
|
||||
media_source: 'media_library',
|
||||
media_id: attachment.id,
|
||||
title: '',
|
||||
caption: '',
|
||||
background_color: ''
|
||||
};
|
||||
galleryItems.push(item);
|
||||
console.log('Added new media library item:', item);
|
||||
console.log('Current gallery items:', galleryItems);
|
||||
updateHiddenInputs();
|
||||
});
|
||||
|
||||
mediaFrame.open();
|
||||
} else {
|
||||
const url = prompt('Enter ' + source + ' URL:');
|
||||
if (url) {
|
||||
const item = {
|
||||
media_source: source,
|
||||
url: url,
|
||||
title: '',
|
||||
caption: '',
|
||||
background_color: ''
|
||||
};
|
||||
galleryItems.push(item);
|
||||
console.log('Added new URL item:', item);
|
||||
console.log('Current gallery items:', galleryItems);
|
||||
updateHiddenInputs();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
// Save the gallery meta data
|
||||
function save_lcp_gallery_meta_box($post_id) {
|
||||
// Check if our nonce is set
|
||||
if (!isset($_POST['lcp_gallery_meta_box_nonce'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify that the nonce is valid
|
||||
if (!wp_verify_nonce($_POST['lcp_gallery_meta_box_nonce'], 'lcp_gallery_meta_box')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is an autosave, our form has not been submitted, so we don't want to do anything
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the user's permissions
|
||||
if (isset($_POST['post_type']) && 'page' == $_POST['post_type']) {
|
||||
if (!current_user_can('edit_page', $post_id)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!current_user_can('edit_post', $post_id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the gallery data
|
||||
if (isset($_POST['lcp_gallery'])) {
|
||||
$gallery_items = array_map(function($item) {
|
||||
return is_string($item) ? json_decode(wp_unslash($item), true) : $item;
|
||||
}, $_POST['lcp_gallery']);
|
||||
|
||||
update_post_meta($post_id, 'lcp_gallery', $gallery_items);
|
||||
} else {
|
||||
delete_post_meta($post_id, 'lcp_gallery');
|
||||
}
|
||||
}
|
||||
add_action('save_post', 'save_lcp_gallery_meta_box');
|
||||
|
||||
// Enqueue color picker
|
||||
function lcp_gallery_admin_enqueue($hook) {
|
||||
if ('post.php' != $hook && 'post-new.php' != $hook) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_style('wp-color-picker');
|
||||
wp_enqueue_script('wp-color-picker');
|
||||
}
|
||||
add_action('admin_enqueue_scripts', 'lcp_gallery_admin_enqueue');
|
||||
|
||||
// Add AJAX handler for gallery updates
|
||||
add_action('wp_ajax_update_gallery_meta', 'handle_gallery_meta_update');
|
||||
add_action('wp_ajax_nopriv_update_gallery_meta', 'handle_gallery_meta_update');
|
||||
|
||||
function handle_gallery_meta_update() {
|
||||
// Verify nonce for security
|
||||
if (!current_user_can('edit_posts')) {
|
||||
wp_send_json_error('Permission denied');
|
||||
return;
|
||||
}
|
||||
|
||||
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
|
||||
$gallery_items = isset($_POST['gallery_items']) ? json_decode(stripslashes($_POST['gallery_items']), true) : array();
|
||||
|
||||
// Update the post meta
|
||||
$updated = update_post_meta($post_id, 'lcp_gallery', $gallery_items);
|
||||
|
||||
if ($updated) {
|
||||
wp_send_json_success(array('message' => 'Gallery updated successfully'));
|
||||
} else {
|
||||
wp_send_json_error(array('message' => 'Failed to update gallery'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '00e12da1bdf9e61c448a');
|
||||
<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'eca736ee702435b6a2ff');
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -10,26 +10,26 @@ export default function save(props) {
|
||||
// Conditionally render the link or button based on buttonAction
|
||||
return (
|
||||
|
||||
<div {...blockProps}>
|
||||
{buttonAction === 'customUrl' ? (
|
||||
<a href={customUrl} className="lcp-button" style={{ padding: buttonPadding || '10px' }}>
|
||||
{displayIcon && iconSvgPath && (
|
||||
<svg style={{ height: iconHeight }} className="lcp-icon" xmlns="http://www.w3.org/2000/svg" viewBox={iconSvgViewbox || "0 0 576 576"} dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
|
||||
)}
|
||||
<span className="lcp-button-text">
|
||||
{buttonText || 'Button'}
|
||||
</span>
|
||||
</a>
|
||||
) : (
|
||||
<button className="lcp-button" style={{ padding: buttonPadding || '10px' }}>
|
||||
{displayIcon && iconSvgPath && (
|
||||
<svg style={{ height: iconHeight }} className="lcp-icon" xmlns="http://www.w3.org/2000/svg" viewBox={iconSvgViewbox || "0 0 576 576"} dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
|
||||
)}
|
||||
<span className="lcp-button-text">
|
||||
{buttonText || 'Button'}
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<>
|
||||
{buttonAction === 'customUrl' ? (
|
||||
<a href={customUrl} className="lcp-button" style={{ padding: buttonPadding || '10px' }}>
|
||||
{displayIcon && iconSvgPath && (
|
||||
<svg style={{ height: iconHeight }} className="lcp-icon" xmlns="http://www.w3.org/2000/svg" viewBox={iconSvgViewbox || "0 0 576 576"} dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
|
||||
)}
|
||||
<span className="lcp-button-text">
|
||||
{buttonText || 'Button'}
|
||||
</span>
|
||||
</a>
|
||||
) : (
|
||||
<button className="lcp-button" style={{ padding: buttonPadding || '10px' }}>
|
||||
{displayIcon && iconSvgPath && (
|
||||
<svg style={{ height: iconHeight }} className="lcp-icon" xmlns="http://www.w3.org/2000/svg" viewBox={iconSvgViewbox || "0 0 576 576"} dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
|
||||
)}
|
||||
<span className="lcp-button-text">
|
||||
{buttonText || 'Button'}
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-i18n'), 'version' => '40a5279a7e8774abfe4c');
|
||||
<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-i18n'), 'version' => '04e9c02e00cfeee61658');
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
.wp-block-create-block-lcp-viewport{background-color:#21759b;color:#fff;padding:2px}
|
||||
.wp-block-create-block-lcp-viewport{background-color:#21759b;color:#fff;padding:2px}.lcp-dynamic-container.lcp-has-background-image{position:relative;width:100%}.lcp-dynamic-container.lcp-has-background-image>.lcp-background-image{height:100%;right:0;-o-object-fit:cover;object-fit:cover;-o-object-position:center center;object-position:center center;position:absolute;top:0;width:100%}
|
||||
|
||||
@ -1 +1 @@
|
||||
.wp-block-create-block-lcp-viewport{background-color:#21759b;color:#fff;padding:2px}
|
||||
.wp-block-create-block-lcp-viewport{background-color:#21759b;color:#fff;padding:2px}.lcp-dynamic-container.lcp-has-background-image{position:relative;width:100%}.lcp-dynamic-container.lcp-has-background-image>.lcp-background-image{height:100%;left:0;-o-object-fit:cover;object-fit:cover;-o-object-position:center center;object-position:center center;position:absolute;top:0;width:100%}
|
||||
|
||||
@ -65,10 +65,10 @@ if (!function_exists('lcp_random_string')) {
|
||||
}
|
||||
|
||||
|
||||
function render_lcp_container( $attributes, $content ) {
|
||||
function render_lcp_dynamic_container( $attributes, $content ) {
|
||||
// Debugging: Check the passed attributes
|
||||
//var_dump($attributes);
|
||||
|
||||
|
||||
// Generate a random class name (optional, could be customized)
|
||||
$random_class = lcp_random_string(12,true);
|
||||
|
||||
@ -159,13 +159,39 @@ if (!function_exists('lcp_random_string')) {
|
||||
if ( ! empty( $style ) ) {
|
||||
$style_tag = sprintf( '<style>.%s { %s }</style>', esc_attr( $random_class ), $style );
|
||||
}
|
||||
// Set the post thumbnail
|
||||
if ( has_post_thumbnail() ) {
|
||||
// Get the post thumbnail URL for different sizes
|
||||
$full_size_url = get_the_post_thumbnail_url( get_the_ID(), 'full' );
|
||||
$medium_size_url = get_the_post_thumbnail_url( get_the_ID(), 'medium' );
|
||||
$large_size_url = get_the_post_thumbnail_url( get_the_ID(), 'large' );
|
||||
|
||||
// Generate the <picture> element with <source> and <img> tags for responsiveness
|
||||
$post_thumb = '<picture class="lcp-background-image">';
|
||||
|
||||
// Add source for large image (for screens >= 1200px)
|
||||
$post_thumb .= '<source media="(min-width: 1200px)" srcset="' . esc_url( $large_size_url ) . '">';
|
||||
|
||||
// Add source for medium image (for screens >= 768px)
|
||||
$post_thumb .= '<source media="(min-width: 768px)" srcset="' . esc_url( $medium_size_url ) . '">';
|
||||
|
||||
// Add fallback image (for smaller screens or if no match for media queries)
|
||||
$post_thumb .= '<img src="' . esc_url( $full_size_url ) . '" alt="Responsive Background Image" class="responsive-background">';
|
||||
|
||||
$post_thumb .= '</picture>';
|
||||
}
|
||||
|
||||
$has_background_image = (2 + 2 == 4) ? 'lcp-has-background-image' : '';
|
||||
|
||||
// Output the content wrapped in the div with the random class and padding styles
|
||||
return $style_tag . sprintf(
|
||||
'<div class="lcp-container %s">%s</div>',
|
||||
esc_attr( $random_class ),
|
||||
$content
|
||||
'<div class="lcp-dynamic-container %s %s">%s%s</div>',
|
||||
esc_attr( $random_class ), // The random class
|
||||
esc_attr( $has_background_image), // Conditionally add 'lcp-has-background-image' class
|
||||
$post_thumb, // Add the $post_thumb (responsive image) here,
|
||||
$content // Keep the original content
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
|
||||
|
||||
export default function Save() {
|
||||
// Block props
|
||||
const blockProps = useBlockProps.save();
|
||||
|
||||
return (
|
||||
<div {...blockProps}>
|
||||
<InnerBlocks.Content />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
import { InnerBlocks } from '@wordpress/block-editor';
|
||||
export default function save() {
|
||||
return (<InnerBlocks.Content/>); // No content is saved in the database for dynamic blocks
|
||||
}
|
||||
@ -10,3 +10,20 @@
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.lcp-dynamic-container.lcp-has-background-image {
|
||||
position:relative;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.lcp-dynamic-container.lcp-has-background-image > .lcp-background-image {
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover; /* Cover the container like a background */
|
||||
object-position: center center; /* Center the image */
|
||||
|
||||
}
|
||||
@ -9,9 +9,16 @@
|
||||
"description": "A dynamic or static gallery based on the Lightgallery javascript plugin",
|
||||
"example": {},
|
||||
"supports": {
|
||||
"html": false
|
||||
"html": false,
|
||||
"color": {
|
||||
"background": true,
|
||||
"text": false
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"backgroundColor": {
|
||||
"type": "string"
|
||||
},
|
||||
"parseElementForItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
|
||||
@ -125,6 +125,30 @@ function validate_media_ids($input) {
|
||||
|
||||
// Return an array of Media IDs
|
||||
function get_media_ids($attributes) {
|
||||
// If post_gallery meta field
|
||||
if (!$attributes['sources'] == "postGallery") {
|
||||
$post_id = get_the_ID();
|
||||
$lcp_post_gallery = get_post_meta( $post_id, 'lcp_gallery', true );
|
||||
|
||||
// Check if the meta field is not empty and unserialize the value
|
||||
if ( ! empty( $lcp_post_gallery ) ) {
|
||||
// Unserialize the meta field value to convert it into an array
|
||||
$gallery_array = $lcp_post_gallery;
|
||||
|
||||
// Initialize an empty array to hold the media IDs
|
||||
$media_ids = array();
|
||||
|
||||
// Loop through the gallery array and extract the media_id values
|
||||
foreach ( $gallery_array as $item ) {
|
||||
// Check if the 'media_id' key exists
|
||||
if ( isset( $item['media_id'] ) ) {
|
||||
$media_ids[] = $item['media_id']; // Add the media_id to the array
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $media_ids;
|
||||
}
|
||||
// Manual Source
|
||||
if ($attributes['source'] == "manual" && isset($attributes['galleryItems'])) {
|
||||
// Extract 'id' from each item in the 'galleryItems' array
|
||||
|
||||
@ -2,7 +2,10 @@ import { __ } from '@wordpress/i18n';
|
||||
import {
|
||||
InspectorControls,
|
||||
MediaUpload,
|
||||
MediaUploadCheck
|
||||
MediaUploadCheck,
|
||||
useBlockProps,
|
||||
withColors,
|
||||
PanelColorSettings
|
||||
} from '@wordpress/block-editor';
|
||||
import { useState,
|
||||
useEffect,
|
||||
@ -65,9 +68,6 @@ const galleryElements = [
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Aspect ratio options
|
||||
const aspectRatioOptions = [
|
||||
{ value: '1-1', label: __('1:1', metadata.textdomain) },
|
||||
@ -125,8 +125,8 @@ const MultiMediaUpload = ({ onSelect }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default function Edit(props) {
|
||||
const { attributes, setAttributes } = props;
|
||||
function Edit(props) {
|
||||
const { attributes, setAttributes, backgroundColor, setBackgroundColor } = props;
|
||||
const {
|
||||
galleryItems = [],
|
||||
source,
|
||||
@ -314,11 +314,17 @@ const { isTemplate, postType, postId } = useSelect((select) => {
|
||||
togglePlugin('lgZoom', value); // Add/Remove lgZoom plugin based on toggle value
|
||||
};
|
||||
|
||||
const blockProps = useBlockProps({
|
||||
style: {
|
||||
backgroundColor: backgroundColor?.color,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
{/* The Gallery */}
|
||||
<LightGallery {...attributes.lgSettings} />
|
||||
<LcpGallery {...attributes.lgSettings} />
|
||||
|
||||
<InspectorControls>
|
||||
{/* Settings and Style Tabs */}
|
||||
@ -717,6 +723,16 @@ const { isTemplate, postType, postId } = useSelect((select) => {
|
||||
if (name === 'style') {
|
||||
return (
|
||||
<PanelBody title={__('Style Settings')}>
|
||||
<PanelColorSettings
|
||||
title={__('Color settings', 'lcp')}
|
||||
colorSettings={[
|
||||
{
|
||||
value: backgroundColor?.color,
|
||||
onChange: setBackgroundColor,
|
||||
label: __('Background color', 'lcp'),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{initialLayout === 'inline' && (
|
||||
<>
|
||||
<UnitControl
|
||||
@ -857,3 +873,4 @@ const { isTemplate, postType, postId } = useSelect((select) => {
|
||||
);
|
||||
}
|
||||
|
||||
export default withColors('backgroundColor')(Edit);
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-i18n'), 'version' => 'e74f7d37dca7635e59f9');
|
||||
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-i18n'), 'version' => '7b19c7f88a697fc64c09');
|
||||
|
||||
@ -1 +1 @@
|
||||
(()=>{"use strict";var e,n={998:()=>{const e=window.wp.blocks,n=window.wp.i18n,t=window.wp.blockEditor,r=window.wp.components,i=window.ReactJSXRuntime,s=JSON.parse('{"UU":"lcp/main-area"}');(0,e.registerBlockType)(s.UU,{edit:function(e){const{attributes:s,setAttributes:a}=e,{maxWidth:o="100%",expandVertical:l=!0}=s,c=(0,t.useBlockProps)(),p=(0,t.useInnerBlocksProps)(c);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.InspectorControls,{children:(0,i.jsx)(r.PanelBody,{title:(0,n.__)("Max Width Settings","lcp"),initialOpen:!0,children:(0,i.jsxs)("div",{className:"max-width-settings",children:[(0,i.jsx)(r.__experimentalUnitControl,{onChange:e=>{a({maxWidth:e})},value:o,defaultUnit:"px"}),(0,i.jsx)(r.ToggleControl,{label:(0,n.__)("Enable Vertical Expansion","lcp"),checked:l,onChange:e=>{a({expandVertical:e})}})]})})}),(0,i.jsx)("div",{...p,id:"lcp-main-container",style:{minHeight:"200px"},children:(0,i.jsx)(t.InnerBlocks,{...p})})]})},save:function({attributes:e}){const{maxWidth:n="100%",expandVertical:r}=e,s=t.useBlockProps.save(),a=r?`${s.className} lcp-grow-vertical`:s.className,o={maxWidth:n};return(0,i.jsx)("div",{...s,id:"lcp-main-container",className:a,style:o,children:(0,i.jsx)(t.InnerBlocks.Content,{})})}})}},t={};function r(e){var i=t[e];if(void 0!==i)return i.exports;var s=t[e]={exports:{}};return n[e](s,s.exports,r),s.exports}r.m=n,e=[],r.O=(n,t,i,s)=>{if(!t){var a=1/0;for(p=0;p<e.length;p++){t=e[p][0],i=e[p][1],s=e[p][2];for(var o=!0,l=0;l<t.length;l++)(!1&s||a>=s)&&Object.keys(r.O).every((e=>r.O[e](t[l])))?t.splice(l--,1):(o=!1,s<a&&(a=s));if(o){e.splice(p--,1);var c=i();void 0!==c&&(n=c)}}return n}s=s||0;for(var p=e.length;p>0&&e[p-1][2]>s;p--)e[p]=e[p-1];e[p]=[t,i,s]},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={57:0,350:0};r.O.j=n=>0===e[n];var n=(n,t)=>{var i,s,a=t[0],o=t[1],l=t[2],c=0;if(a.some((n=>0!==e[n]))){for(i in o)r.o(o,i)&&(r.m[i]=o[i]);if(l)var p=l(r)}for(n&&n(t);c<a.length;c++)s=a[c],r.o(e,s)&&e[s]&&e[s][0](),e[s]=0;return r.O(p)},t=self.webpackChunklcp_viewport=self.webpackChunklcp_viewport||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})();var i=r.O(void 0,[350],(()=>r(998)));i=r.O(i)})();
|
||||
(()=>{"use strict";var e,n={998:()=>{const e=window.wp.blocks,n=window.wp.i18n,t=window.wp.blockEditor,i=window.wp.components,r=window.ReactJSXRuntime,s=JSON.parse('{"UU":"lcp/main-area"}');(0,e.registerBlockType)(s.UU,{edit:function(e){const{attributes:s,setAttributes:a}=e,{maxWidth:o="100%",expandVertical:l=!0}=s,c=(0,t.useBlockProps)(),p=(0,t.useInnerBlocksProps)(c);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.InspectorControls,{children:(0,r.jsx)(i.PanelBody,{title:(0,n.__)("Max Width Settings","lcp"),initialOpen:!0,children:(0,r.jsxs)("div",{className:"max-width-settings",children:[(0,r.jsx)(i.__experimentalUnitControl,{onChange:e=>{a({maxWidth:e})},value:o,defaultUnit:"px"}),(0,r.jsx)(i.ToggleControl,{label:(0,n.__)("Enable Vertical Expansion","lcp"),checked:l,onChange:e=>{a({expandVertical:e})}})]})})}),(0,r.jsx)("div",{...p,id:"lcp-main-container",style:{minHeight:"200px"},children:(0,r.jsx)(t.InnerBlocks,{...p})})]})},save:function({attributes:e}){const{maxWidth:n="100%",expandVertical:i}=e,s=t.useBlockProps.save(),a=i?`${s.className} lcp-grow-vertical`:s.className,o={maxWidth:n};return(0,r.jsx)("div",{...s,id:"lcp-main-container",className:a,style:o,children:(0,r.jsx)("div",{id:"lcp-main-container-inner",children:(0,r.jsx)(t.InnerBlocks.Content,{})})})}})}},t={};function i(e){var r=t[e];if(void 0!==r)return r.exports;var s=t[e]={exports:{}};return n[e](s,s.exports,i),s.exports}i.m=n,e=[],i.O=(n,t,r,s)=>{if(!t){var a=1/0;for(p=0;p<e.length;p++){t=e[p][0],r=e[p][1],s=e[p][2];for(var o=!0,l=0;l<t.length;l++)(!1&s||a>=s)&&Object.keys(i.O).every((e=>i.O[e](t[l])))?t.splice(l--,1):(o=!1,s<a&&(a=s));if(o){e.splice(p--,1);var c=r();void 0!==c&&(n=c)}}return n}s=s||0;for(var p=e.length;p>0&&e[p-1][2]>s;p--)e[p]=e[p-1];e[p]=[t,r,s]},i.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={57:0,350:0};i.O.j=n=>0===e[n];var n=(n,t)=>{var r,s,a=t[0],o=t[1],l=t[2],c=0;if(a.some((n=>0!==e[n]))){for(r in o)i.o(o,r)&&(i.m[r]=o[r]);if(l)var p=l(i)}for(n&&n(t);c<a.length;c++)s=a[c],i.o(e,s)&&e[s]&&e[s][0](),e[s]=0;return i.O(p)},t=self.webpackChunklcp_viewport=self.webpackChunklcp_viewport||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})();var r=i.O(void 0,[350],(()=>i(998)));r=i.O(r)})();
|
||||
@ -16,7 +16,9 @@ export default function Save( { attributes } ) {
|
||||
|
||||
return (
|
||||
<div {...blockProps} id="lcp-main-container" className={className} style={style}>
|
||||
<InnerBlocks.Content />
|
||||
<div id="lcp-main-container-inner">
|
||||
<InnerBlocks.Content />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => '9fbf94ac3507c2365b0a');
|
||||
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => 'e510dd9214b81b305e13');
|
||||
|
||||
@ -1 +1 @@
|
||||
(()=>{"use strict";var e,n={650:()=>{const e=window.wp.blocks,n=(window.wp.i18n,window.wp.blockEditor),r=window.ReactJSXRuntime,o=JSON.parse('{"UU":"lcp/sidecontent"}');(0,e.registerBlockType)(o.UU,{edit:function(){return(0,n.useBlockProps)(),(0,r.jsx)("div",{...n.useBlockProps,children:(0,r.jsx)("div",{id:"lcp-sidecontent",children:(0,r.jsx)(n.InnerBlocks,{renderAppender:()=>(0,r.jsx)(n.InnerBlocks.ButtonBlockAppender,{})})})})},save:function(){const e=n.useBlockProps.save();return(0,r.jsx)("div",{...e,id:"lcp-sidecontent",children:(0,r.jsx)(n.InnerBlocks.Content,{})})}})}},r={};function o(e){var t=r[e];if(void 0!==t)return t.exports;var s=r[e]={exports:{}};return n[e](s,s.exports,o),s.exports}o.m=n,e=[],o.O=(n,r,t,s)=>{if(!r){var i=1/0;for(d=0;d<e.length;d++){r=e[d][0],t=e[d][1],s=e[d][2];for(var c=!0,l=0;l<r.length;l++)(!1&s||i>=s)&&Object.keys(o.O).every((e=>o.O[e](r[l])))?r.splice(l--,1):(c=!1,s<i&&(i=s));if(c){e.splice(d--,1);var p=t();void 0!==p&&(n=p)}}return n}s=s||0;for(var d=e.length;d>0&&e[d-1][2]>s;d--)e[d]=e[d-1];e[d]=[r,t,s]},o.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={57:0,350:0};o.O.j=n=>0===e[n];var n=(n,r)=>{var t,s,i=r[0],c=r[1],l=r[2],p=0;if(i.some((n=>0!==e[n]))){for(t in c)o.o(c,t)&&(o.m[t]=c[t]);if(l)var d=l(o)}for(n&&n(r);p<i.length;p++)s=i[p],o.o(e,s)&&e[s]&&e[s][0](),e[s]=0;return o.O(d)},r=self.webpackChunklcp_sidecontent=self.webpackChunklcp_sidecontent||[];r.forEach(n.bind(null,0)),r.push=n.bind(null,r.push.bind(r))})();var t=o.O(void 0,[350],(()=>o(650)));t=o.O(t)})();
|
||||
(()=>{"use strict";var e,n={650:()=>{const e=window.wp.blocks,n=(window.wp.i18n,window.wp.blockEditor),r=window.ReactJSXRuntime,o=JSON.parse('{"UU":"lcp/sidecontent"}');(0,e.registerBlockType)(o.UU,{edit:function(){return(0,n.useBlockProps)(),(0,r.jsx)("div",{...n.useBlockProps,children:(0,r.jsx)("div",{id:"lcp-sidecontent",children:(0,r.jsx)(n.InnerBlocks,{renderAppender:()=>(0,r.jsx)(n.InnerBlocks.ButtonBlockAppender,{})})})})},save:function(){const e=n.useBlockProps.save();return(0,r.jsx)("div",{...e,id:"lcp-sidecontent",children:(0,r.jsx)("div",{id:"lcp-sidecontent-inner",children:(0,r.jsx)(n.InnerBlocks.Content,{})})})}})}},r={};function o(e){var t=r[e];if(void 0!==t)return t.exports;var i=r[e]={exports:{}};return n[e](i,i.exports,o),i.exports}o.m=n,e=[],o.O=(n,r,t,i)=>{if(!r){var s=1/0;for(p=0;p<e.length;p++){r=e[p][0],t=e[p][1],i=e[p][2];for(var c=!0,l=0;l<r.length;l++)(!1&i||s>=i)&&Object.keys(o.O).every((e=>o.O[e](r[l])))?r.splice(l--,1):(c=!1,i<s&&(s=i));if(c){e.splice(p--,1);var d=t();void 0!==d&&(n=d)}}return n}i=i||0;for(var p=e.length;p>0&&e[p-1][2]>i;p--)e[p]=e[p-1];e[p]=[r,t,i]},o.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={57:0,350:0};o.O.j=n=>0===e[n];var n=(n,r)=>{var t,i,s=r[0],c=r[1],l=r[2],d=0;if(s.some((n=>0!==e[n]))){for(t in c)o.o(c,t)&&(o.m[t]=c[t]);if(l)var p=l(o)}for(n&&n(r);d<s.length;d++)i=s[d],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return o.O(p)},r=self.webpackChunklcp_sidecontent=self.webpackChunklcp_sidecontent||[];r.forEach(n.bind(null,0)),r.push=n.bind(null,r.push.bind(r))})();var t=o.O(void 0,[350],(()=>o(650)));t=o.O(t)})();
|
||||
@ -20,11 +20,12 @@ export default function Save() {
|
||||
|
||||
return (
|
||||
<div {...blockProps} id="lcp-sidecontent">
|
||||
<div id="lcp-sidecontent-inner">
|
||||
|
||||
|
||||
|
||||
<InnerBlocks.Content />
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => 'b8ff5a7ac1d726017948');
|
||||
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '432795d467d88e7a501f');
|
||||
|
||||
@ -1 +1 @@
|
||||
(()=>{"use strict";var e,t={798:()=>{const e=window.wp.blocks,t=window.wp.i18n,o=window.wp.blockEditor,n=(window.wp.hooks,window.wp.components),c=window.wp.element,r=window.wp.data,i=window.ReactJSXRuntime,s=JSON.parse('{"UU":"lcp/viewport"}');(0,e.registerBlockType)(s.UU,{edit:function({attributes:s,setAttributes:l,clientId:a}){const{hasSidecontent:d,headerContainerStickyType:p}=s,[u,w]=(0,c.useState)(!1),[h,k]=(0,c.useState)(!1),[v,f]=(0,c.useState)(!1),[b,B]=(0,c.useState)(null),m=(0,o.useBlockProps)({className:d?"has-sidecontent":""}),x=[d?["lcp/sidecontent"]:null,["lcp/header-container"],["lcp/main-area"],["lcp/footer-container"]].filter(Boolean);(0,c.useEffect)((()=>{if(d){const t=(0,e.createBlock)("lcp/sidecontent",{});wp.data.dispatch("core/block-editor").insertBlocks(t,1,a)}}),[d,a]),(0,c.useEffect)((()=>{const e=(0,r.subscribe)((()=>{const e=wp.data.select("core/block-editor").getBlocks();if(h||v)return;const t=e.find((e=>e.clientId!==a&&!wp.data.select("core/block-editor").getBlockParents(e.clientId).includes(a)));t&&(B(t),w(!0),f(!0))}));return()=>{e()}}),[a,h,v]);const y=()=>{if(b){const e=wp.data.select("core/block-editor").getBlocks(a).find((e=>"lcp/main-area"===e.name));e&&(console.log(e),wp.data.dispatch("core/block-editor").insertBlocks(b,e.clientId,0))}w(!1)};(0,c.useEffect)((()=>{v&&k(!1)}),[v]);const j=(0,r.useSelect)((e=>e("core/block-editor").getBlocks(a)),[a]);return(0,c.useEffect)((()=>{const e=j.find((e=>"lcp/header-container"===e.name));j.find((e=>"lcp/header-sidecontent"===e.name)),e&&e.attributes&&void 0!==e.attributes.sticky&&l({headerContainerStickyType:e.attributes.sticky})}),[j,a,l]),(0,i.jsxs)("div",{...m,children:[(0,i.jsx)(o.InspectorControls,{children:(0,i.jsx)(n.ToggleControl,{label:(0,t.__)("Include Side Content","lcp-viewport"),checked:d,onChange:e=>l({hasSidecontent:e})})}),(0,i.jsx)("div",{id:"lcp-viewport-outer",children:(0,i.jsx)("div",{id:"lcp-viewport-inner",children:(0,i.jsx)(o.InnerBlocks,{renderAppender:()=>(0,i.jsx)(o.InnerBlocks.ButtonBlockAppender,{}),template:x})})}),u&&!h&&(0,i.jsxs)(n.Modal,{title:(0,t.__)("Block Outside Viewport","lcp-viewport"),onRequestClose:y,className:"block-outside-popup",children:[(0,i.jsx)("p",{children:(0,t.__)("You added a block outside of the lcp/viewport container. Please make sure the block is inside the appropriate area.","lcp-viewport")}),(0,i.jsx)(n.Button,{isPrimary:!0,onClick:y,children:(0,t.__)("Close","lcp-viewport")}),(0,i.jsx)(n.Button,{isSecondary:!0,onClick:()=>{k(!0),w(!1)},children:(0,t.__)("Ignore","lcp-viewport")})]})]})},save:function({attributes:e}){const{hasSidecontent:t,headerContainerStickyType:n}=e;o.useBlockProps.save();let c="";return t&&(c+="lcp-has-sidecontent "),"always"===n?c+="lcp-has-sticky-header ":"onScroll"===n&&(c+="lcp-has-sticky-on-scroll-header "),(0,i.jsx)("div",{className:c,id:"lcp-viewport-outer",children:(0,i.jsx)("div",{id:"lcp-viewport-inner",className:c,children:(0,i.jsx)(o.InnerBlocks.Content,{})})})}})}},o={};function n(e){var c=o[e];if(void 0!==c)return c.exports;var r=o[e]={exports:{}};return t[e](r,r.exports,n),r.exports}n.m=t,e=[],n.O=(t,o,c,r)=>{if(!o){var i=1/0;for(d=0;d<e.length;d++){o=e[d][0],c=e[d][1],r=e[d][2];for(var s=!0,l=0;l<o.length;l++)(!1&r||i>=r)&&Object.keys(n.O).every((e=>n.O[e](o[l])))?o.splice(l--,1):(s=!1,r<i&&(i=r));if(s){e.splice(d--,1);var a=c();void 0!==a&&(t=a)}}return t}r=r||0;for(var d=e.length;d>0&&e[d-1][2]>r;d--)e[d]=e[d-1];e[d]=[o,c,r]},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};n.O.j=t=>0===e[t];var t=(t,o)=>{var c,r,i=o[0],s=o[1],l=o[2],a=0;if(i.some((t=>0!==e[t]))){for(c in s)n.o(s,c)&&(n.m[c]=s[c]);if(l)var d=l(n)}for(t&&t(o);a<i.length;a++)r=i[a],n.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return n.O(d)},o=self.webpackChunklcp_viewport=self.webpackChunklcp_viewport||[];o.forEach(t.bind(null,0)),o.push=t.bind(null,o.push.bind(o))})();var c=n.O(void 0,[350],(()=>n(798)));c=n.O(c)})();
|
||||
(()=>{"use strict";var e,t={798:()=>{const e=window.wp.blocks,t=window.wp.i18n,o=window.wp.blockEditor,n=(window.wp.hooks,window.wp.components),r=window.wp.element,i=window.wp.data,c=window.ReactJSXRuntime,s=JSON.parse('{"UU":"lcp/viewport"}');(0,e.registerBlockType)(s.UU,{edit:function({attributes:s,setAttributes:l,clientId:a}){const{hasSidecontent:p,headerContainerStickyType:d}=s,[u,h]=(0,r.useState)(!1),[w,v]=(0,r.useState)(!1),[k,f]=(0,r.useState)(!1),[b,x]=(0,r.useState)(null),y=(0,o.useBlockProps)({className:p?"has-sidecontent":""}),j=[p?["lcp/sidecontent"]:null,["lcp/header-container"],["lcp/main-area"],["lcp/footer-container"]].filter(Boolean);(0,r.useEffect)((()=>{if(p){const t=(0,e.createBlock)("lcp/sidecontent",{});wp.data.dispatch("core/block-editor").insertBlocks(t,1,a)}}),[p,a]);const m=(0,i.useSelect)((e=>e("core/block-editor").getBlocks(a)),[a]);return(0,r.useEffect)((()=>{const e=m.find((e=>"lcp/header-container"===e.name));m.find((e=>"lcp/header-sidecontent"===e.name)),e&&e.attributes&&void 0!==e.attributes.sticky&&l({headerContainerStickyType:e.attributes.sticky})}),[m,a,l]),(0,c.jsxs)("div",{...y,children:[(0,c.jsx)(o.InspectorControls,{children:(0,c.jsx)(n.ToggleControl,{label:(0,t.__)("Include Side Content","lcp-viewport"),checked:p,onChange:e=>l({hasSidecontent:e})})}),(0,c.jsx)("div",{id:"lcp-viewport-outer",children:(0,c.jsx)("div",{id:"lcp-viewport-inner",children:(0,c.jsx)(o.InnerBlocks,{renderAppender:()=>(0,c.jsx)(o.InnerBlocks.ButtonBlockAppender,{}),template:j})})}),u&&!w&&(0,c.jsxs)(n.Modal,{title:(0,t.__)("Block Outside Viewport","lcp-viewport"),onRequestClose:closePopup,className:"block-outside-popup",children:[(0,c.jsx)("p",{children:(0,t.__)("You added a block outside of the lcp/viewport container. Please make sure the block is inside the appropriate area.","lcp-viewport")}),(0,c.jsx)(n.Button,{isPrimary:!0,onClick:closePopup,children:(0,t.__)("Close","lcp-viewport")}),(0,c.jsx)(n.Button,{isSecondary:!0,onClick:ignorePopup,children:(0,t.__)("Ignore","lcp-viewport")})]})]})},save:function({attributes:e}){const{hasSidecontent:t,headerContainerStickyType:n}=e;o.useBlockProps.save();let r="";return t&&(r+="lcp-has-sidecontent "),"always"===n?r+="lcp-has-sticky-header ":"onScroll"===n&&(r+="lcp-has-sticky-on-scroll-header "),(0,c.jsx)("div",{className:r,id:"lcp-viewport-outer",children:(0,c.jsx)("div",{id:"lcp-viewport-inner",className:r,children:(0,c.jsx)(o.InnerBlocks.Content,{})})})}})}},o={};function n(e){var r=o[e];if(void 0!==r)return r.exports;var i=o[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.m=t,e=[],n.O=(t,o,r,i)=>{if(!o){var c=1/0;for(p=0;p<e.length;p++){o=e[p][0],r=e[p][1],i=e[p][2];for(var s=!0,l=0;l<o.length;l++)(!1&i||c>=i)&&Object.keys(n.O).every((e=>n.O[e](o[l])))?o.splice(l--,1):(s=!1,i<c&&(c=i));if(s){e.splice(p--,1);var a=r();void 0!==a&&(t=a)}}return t}i=i||0;for(var p=e.length;p>0&&e[p-1][2]>i;p--)e[p]=e[p-1];e[p]=[o,r,i]},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};n.O.j=t=>0===e[t];var t=(t,o)=>{var r,i,c=o[0],s=o[1],l=o[2],a=0;if(c.some((t=>0!==e[t]))){for(r in s)n.o(s,r)&&(n.m[r]=s[r]);if(l)var p=l(n)}for(t&&t(o);a<c.length;a++)i=c[a],n.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return n.O(p)},o=self.webpackChunklcp_viewport=self.webpackChunklcp_viewport||[];o.forEach(t.bind(null,0)),o.push=t.bind(null,o.push.bind(o))})();var r=n.O(void 0,[350],(()=>n(798)));r=n.O(r)})();
|
||||
@ -44,80 +44,16 @@ export default function Edit({ attributes, setAttributes, clientId }) {
|
||||
}
|
||||
}, [hasSidecontent, clientId]); // Only runs when `hasSidecontent` or `clientId` changes
|
||||
|
||||
// Track block additions and show popup if block is outside the lcp/viewport
|
||||
useEffect(() => {
|
||||
const unsubscribe = subscribe(() => {
|
||||
const blocks = wp.data.select('core/block-editor').getBlocks(); // Get all blocks
|
||||
|
||||
// If the popup is ignored, don't check for outside blocks
|
||||
if (hasIgnoredPopup || blockAdded) return;
|
||||
|
||||
// Check if any block added is outside the lcp/viewport (excluding lcp/viewport itself)
|
||||
const addedBlockOutside = blocks.find((block) => {
|
||||
if (block.clientId === clientId) {
|
||||
// Skip the current block (lcp/viewport)
|
||||
return false;
|
||||
}
|
||||
const parent = wp.data.select('core/block-editor').getBlockParents(block.clientId);
|
||||
// If the block is not inside lcp/viewport or its children, show popup
|
||||
return !parent.includes(clientId);
|
||||
});
|
||||
|
||||
if (addedBlockOutside) {
|
||||
setAddedBlock(addedBlockOutside); // Store the added block
|
||||
setIsPopupVisible(true); // Show the popup if block is outside
|
||||
setBlockAdded(true); // Mark that a block has been added
|
||||
}
|
||||
});
|
||||
|
||||
// Cleanup the subscription on component unmount
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [clientId, hasIgnoredPopup, blockAdded]); // Reset check when block is added or state changes
|
||||
|
||||
// Handle the popup close
|
||||
const closePopup = () => {
|
||||
// Check if an added block exists
|
||||
if (addedBlock) {
|
||||
// Retrieve the parent block (main area)
|
||||
const mainAreaBlock = wp.data.select('core/block-editor').getBlocks(clientId)
|
||||
.find(block => block.name === 'lcp/main-area'); // Find the 'lcp/main-area' block
|
||||
|
||||
if (mainAreaBlock) {
|
||||
console.log(mainAreaBlock)
|
||||
// Insert the block into the 'lcp/main-area'
|
||||
wp.data.dispatch('core/block-editor').insertBlocks(
|
||||
addedBlock, // The block to insert
|
||||
mainAreaBlock.clientId, // Specify the clientId of the main-area block
|
||||
0 // Insert at the start (index 0) of the main-area block's InnerBlocks
|
||||
);
|
||||
}
|
||||
}
|
||||
// Close the popup after moving the block
|
||||
setIsPopupVisible(false);
|
||||
};
|
||||
|
||||
// Handle the "Ignore" button click to dismiss popup and not show again until next block addition
|
||||
const ignorePopup = () => {
|
||||
setHasIgnoredPopup(true); // Set the state to indicate the user has ignored the popup
|
||||
setIsPopupVisible(false); // Close the popup
|
||||
};
|
||||
|
||||
// Reset the "Ignore" state when a new block is added (for the next block addition)
|
||||
useEffect(() => {
|
||||
if (blockAdded) {
|
||||
// Reset ignore state after a new block has been added
|
||||
setHasIgnoredPopup(false);
|
||||
}
|
||||
}, [blockAdded]); // Trigger when blockAdded state changes
|
||||
|
||||
|
||||
// Use useSelect to subscribe to the state of inner blocks
|
||||
const innerBlocks = useSelect((select) => {
|
||||
return select('core/block-editor').getBlocks(clientId);
|
||||
}, [clientId]);
|
||||
|
||||
// useEffect to log "Header present" when the lcp/header-container block is found
|
||||
// useEffect to handle sticky header
|
||||
useEffect(() => {
|
||||
const headerBlock = innerBlocks.find((block) => block.name === 'lcp/header-container');
|
||||
const sidecontentBlock = innerBlocks.find((block) => block.name === 'lcp/header-sidecontent');
|
||||
|
||||
@ -47,7 +47,16 @@ function lcp_custom_svgs_field() {
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
function custom_image_size_settings_page() {
|
||||
add_options_page(
|
||||
'Custom Image Sizes', // Page title
|
||||
'Custom Image Sizes', // Menu title
|
||||
'manage_options', // Capability
|
||||
'custom-image-sizes', // Menu slug
|
||||
'display_custom_image_size_form' // Callback function to display the form
|
||||
);
|
||||
}
|
||||
add_action('admin_menu', 'custom_image_size_settings_page');
|
||||
|
||||
|
||||
|
||||
@ -241,12 +250,14 @@ function render_lcp_theme_settings_page() {
|
||||
<h1>Theme Settings</h1>
|
||||
|
||||
<!-- Tab Structure -->
|
||||
<div class="tab-container">
|
||||
<div class="lcp-tab-container lcp-support-hash">
|
||||
<!-- Tabs -->
|
||||
<ul class="tabs">
|
||||
<li class="tab-link active" data-tab="custom-meta">Custom Meta</li>
|
||||
<li class="tab-link" data-tab="icons">Icons</li>
|
||||
<li class="tab-link" data-tab="custom-code">Custom Code</li>
|
||||
<li class="tab-link" data-tab="images">Images</li>
|
||||
<li class="tab-link" data-tab="misc">Miscellaneous</li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab Panes -->
|
||||
@ -258,7 +269,7 @@ function render_lcp_theme_settings_page() {
|
||||
<?php
|
||||
// Output necessary settings fields for the 'Icons' tab
|
||||
// This outputs all the fields defined by add_settings_field
|
||||
mytheme_display_icon_sets();
|
||||
lcp_display_icon_sets();
|
||||
?>
|
||||
|
||||
|
||||
@ -300,6 +311,47 @@ function render_lcp_theme_settings_page() {
|
||||
<?php submit_button(); ?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="images" class="tab-pane">
|
||||
<h3> Image Sizes </h3>
|
||||
|
||||
|
||||
<div class="lcp-repeater">
|
||||
<div class="lcp-repeater-row">
|
||||
<input data-lcp-repeater-key="name" placeholder="Enter Name">
|
||||
<input type="number" data-lcp-repeater-key="width" data-lcp-required="true" placeholder="Enter Width (pixels)">
|
||||
<input type="number" data-lcp-repeater-key="height" data-lcp-required-for-new-row="true" placeholder="Enter Height (pixels)">
|
||||
<label for="crop-toggle">Crop</label>
|
||||
<input type="checkbox" data-lcp-repeater-key="crop">
|
||||
</div>
|
||||
<button class="lcp-button lcp-repeater-add-row" id="add-repeater-row">Add Row</button>
|
||||
<button class="lcp-button lcp-repeater-submit" data-lcp-action="lcpUpdateImageSizes"id="submit-repeater">Submit Repeater</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Misc Settings Tab -->
|
||||
<div id="misc" class="tab-pane">
|
||||
<!-- Misc Settings -->
|
||||
<h2>Miscellaneous Settings</h2>
|
||||
|
||||
<!-- Button to trigger the AJAX import demo posts -->
|
||||
<h3> Demo Posts </h3>
|
||||
<?php
|
||||
// Get the 'lcp_demo_posts' option from the database
|
||||
$demo_posts_data = get_option('lcp_demo_posts', false);
|
||||
|
||||
// Check if the lcp_demo_posts option exists
|
||||
if ($demo_posts_data) {
|
||||
echo '<span>' . count($demo_posts_data['post_ids']) . ' Demo posts have been imported.</span>';
|
||||
// If demo posts have been imported, display the "Delete Demo Posts" button (this can be disabled or hidden based on your logic)
|
||||
echo '<button class="lcp" id="delete-demo-posts" class="button">Delete Demo Posts</button>';
|
||||
} else {
|
||||
// If demo posts have NOT been imported, display the "Import Demo Posts" button
|
||||
echo '<button class="lcp" id="import-demo-posts" class="button button-primary" >Import Demo Posts</button>';
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -321,23 +373,4 @@ function highlight_to_share_popup() {
|
||||
";
|
||||
}
|
||||
|
||||
/* HOOKS */
|
||||
//Move to custom hooks class or file in future
|
||||
function lcp_wp_head_hooks(){
|
||||
// Define lcp_theme_settings array from wp_options
|
||||
$options = get_option('lcp_theme_settings', array());
|
||||
// Echo highlight-to-share markup and enqueue javascript
|
||||
// Highlight-to-share css is already in style.css
|
||||
if ( isset($options['enable_highlight_to_share']) && $options['enable_highlight_to_share'] ) {
|
||||
highlight_to_share_popup();
|
||||
wp_enqueue_script( 'lcp-highlight-to-share', get_template_directory_uri() . '/assets/js/highlight-to-share.js', array(), null, true );
|
||||
}
|
||||
}
|
||||
|
||||
add_action('wp_head', 'lcp_wp_head_hooks');
|
||||
|
||||
|
||||
|
||||
|
||||
/* ICONS */
|
||||
|
||||
|
||||
@ -1,15 +1,112 @@
|
||||
<?php
|
||||
|
||||
|
||||
// Register the function to run when the theme is switched (deactivated)
|
||||
add_action('switch_theme', 'drop_lcp_icons_table');
|
||||
|
||||
|
||||
// Hook into theme activation to call the function
|
||||
function lcp_activate() {
|
||||
// Call the function to import the default icon sets
|
||||
lcp_install_icon_set(true);
|
||||
}
|
||||
|
||||
function lcp_theme_deactivate() {
|
||||
lcp_delete_demo_posts();
|
||||
}
|
||||
// Register the function to run when the theme is switched (deactivated)
|
||||
add_action('switch_theme', 'lcp_theme_deactivate');
|
||||
|
||||
|
||||
|
||||
|
||||
// Add the action hook to run the function when the theme is activated
|
||||
add_action('after_switch_theme', 'lcp_activate');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function lcp_enqueue_dashboard_scripts($hook) {
|
||||
// Only load the script on the icon-management page
|
||||
|
||||
|
||||
// Enqueue JavaScript for AJAX
|
||||
wp_enqueue_script(
|
||||
'icon-import-script',
|
||||
get_template_directory_uri() . '/assets/js/icon-import.js',
|
||||
array(), // No dependencies for vanilla JS
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
// Pass the AJAX URL to the script
|
||||
wp_localize_script('icon-import-script', 'lcp_ajax', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php')
|
||||
));
|
||||
}
|
||||
add_action('admin_enqueue_scripts', 'lcp_enqueue_dashboard_scripts');
|
||||
|
||||
function lcp_backend_enqueue() {
|
||||
// Enqueue the theme's main stylesheet (style.css)
|
||||
wp_enqueue_style('lcp-style', get_stylesheet_uri());
|
||||
wp_enqueue_script('lcp-script', get_template_directory_uri() . '/script.js');
|
||||
wp_enqueue_script('lcp-ui', get_template_directory_uri() . '/assets/js/lcp-ui.js');
|
||||
|
||||
// Enqueue custom script to handle the Demo post import AJAX request
|
||||
wp_enqueue_script('lcp-import-demo-posts-ajax', get_template_directory_uri() . '/assets/js/demo-posts-import.js', array(), null, true);
|
||||
|
||||
// Add the AJAX URL and nonce as JavaScript variables
|
||||
wp_localize_script('lcp-import-demo-posts-ajax', 'lcp_ajax_obj', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'), // This is the URL that we’ll send the AJAX request to
|
||||
'nonce' => wp_create_nonce('lcp_import_demo_posts_nonce') // Security nonce for validation
|
||||
));
|
||||
|
||||
/* --- Image Sizes --- */
|
||||
// Enqueue the JavaScript file
|
||||
wp_enqueue_script('custom-image-sizes', get_template_directory_uri() . '/assets/js/custom-image-sizes.js', array(), null, true);
|
||||
|
||||
// Localize script to pass the nonce and ajaxurl to JavaScript
|
||||
wp_localize_script('custom-image-sizes', 'customImageSizeAjax', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'), // The URL to send the request to
|
||||
'nonce' => wp_create_nonce('custom_image_sizes_nonce') // Create the nonce and pass it
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
add_action('admin_enqueue_scripts', 'lcp_backend_enqueue');
|
||||
|
||||
|
||||
|
||||
function lcp_send_headers_hooks(){
|
||||
lcp_set_visited_posts_cookie();
|
||||
}
|
||||
add_action('send_headers','lcp_send_headers_hooks');
|
||||
|
||||
|
||||
function lcp_after_setup_theme() {
|
||||
lcp_register_custom_image_sizes();
|
||||
|
||||
}
|
||||
add_action('after_setup_theme', 'lcp_after_setup_theme');
|
||||
|
||||
function lcp_init_hooks() {
|
||||
lcp_register_pattern_categories();
|
||||
lcp_register_patterns();
|
||||
}
|
||||
|
||||
add_action('init', 'lcp_init_hooks');
|
||||
|
||||
// Register pattern categories
|
||||
function lcp_register_pattern_categories() {
|
||||
register_block_pattern_category( 'lcp/customss', array(
|
||||
'label' => __( 'Theme Name: Local Content Pro', 'lcp' ),
|
||||
'description' => __( 'Custom patterns for Local Content Pro.', 'lcp' )
|
||||
) );
|
||||
}
|
||||
|
||||
// Register block pattern
|
||||
function lcp_register_patterns() {
|
||||
register_block_pattern(
|
||||
'lcp/post-content', // Unique slug
|
||||
array(
|
||||
'title' => __( 'Post Content', 'lcp' ),
|
||||
'description' => __( 'A pattern for displaying post content', 'lcp' ),
|
||||
'content' => file_get_contents( get_template_directory() . '/patterns/post-content.php' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
1
parts/footer.html
Normal file
1
parts/footer.html
Normal file
@ -0,0 +1 @@
|
||||
<!-- wp:pattern {"slug":"twentytwentyfive/footer"} /-->
|
||||
1
parts/header.html
Normal file
1
parts/header.html
Normal file
@ -0,0 +1 @@
|
||||
<!-- wp:pattern {"slug":"twentytwentyfive/header"} /-->
|
||||
27
patterns/post-content.php
Normal file
27
patterns/post-content.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Post Content
|
||||
* Slug: twentytwentyfive/banner-about-book
|
||||
* Categories: banner
|
||||
* Description: Banner with book description and accompanying image for promotion.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Twenty_Twenty_Five
|
||||
* @since Twenty Twenty-Five 1.0
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<!-- wp:comment-author-name {"fontSize":"small"} /-->
|
||||
|
||||
<!-- wp:group {"style":{"spacing":{"margin":{"top":"0px","bottom":"0px"}}},"layout":{"type":"flex"}} -->
|
||||
<div class="wp-block-group" style="margin-top:0px;margin-bottom:0px">
|
||||
<!-- wp:comment-date {"fontSize":"small"} /-->
|
||||
<!-- wp:comment-edit-link {"fontSize":"small"} /-->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:comment-content /-->
|
||||
|
||||
<!-- wp:comment-reply-link {"fontSize":"small"} /-->
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Viewport With Sidecontent
|
||||
* Slug: localcontentpro/viewport-with-sidecontent
|
||||
* Categories: banner
|
||||
* Description: A viewport with side content
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Local_Content_Pro
|
||||
* @since Local Content Pro 1.0
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
41
style.css
41
style.css
@ -2,9 +2,12 @@
|
||||
Theme Name: Local Content Pro
|
||||
Theme URI: https://localcontentpro.com
|
||||
Description: A simple Block Theme for local content publishers.
|
||||
Version: 1.0
|
||||
Version: 0.0.1
|
||||
*/
|
||||
|
||||
|
||||
/* Main */
|
||||
.lcp {display:block}
|
||||
/* Main viewport container */
|
||||
#lcp-viewport-outer {
|
||||
overflow: hidden; /* Hide overflow */
|
||||
@ -38,7 +41,7 @@ Version: 1.0
|
||||
|
||||
|
||||
/* Main Content */
|
||||
.lcp-has-sidecontent #lcp-main-container > * > *{ padding:20px
|
||||
.lcp-has-sidecontent #lcp-main-container > *{ padding-left:40px
|
||||
|
||||
}
|
||||
|
||||
@ -50,15 +53,23 @@ Version: 1.0
|
||||
overflow:auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 340px;
|
||||
height: 100%;
|
||||
height: calc(100vh - var(--lcp--header--height));
|
||||
background: #fff;
|
||||
border-right: 2px solid #eee;
|
||||
z-index: 2;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
}
|
||||
#lcp-sidecontent #lcp-sidecontent-inner {
|
||||
padding:10px
|
||||
}
|
||||
.admin-bar #lcp-sidecontent {
|
||||
height:calc(100vh - var(--lcp--header--height) - 32px)
|
||||
}
|
||||
#lcp-sidecontent:not(.lcp-fixed) {
|
||||
top:0
|
||||
}
|
||||
#lcp-viewport-outer.lcp-has-sticky-header #lcp-sidecontent {
|
||||
top: var(--lcp--header--height);
|
||||
position:fixed!important;
|
||||
@ -113,10 +124,10 @@ Version: 1.0
|
||||
width: 100%
|
||||
}
|
||||
#lcp-sidecontent {top:var(--lcp---header--height)}
|
||||
#lcp-sidecontent {
|
||||
#lcp-sidecontent:not(.lcp-fixed) {
|
||||
top: calc(var(--lcp--header--height) );
|
||||
}
|
||||
.admin-bar #lcp-sidecontent.lcp-fixed {
|
||||
#lcp-viewport-outer:not(.lcp-has-sticky-header).admin-bar #lcp-sidecontent.lcp-fixed {
|
||||
top: calc(var(--lcp--header--height) + 32px);
|
||||
}
|
||||
|
||||
@ -127,7 +138,12 @@ Version: 1.0
|
||||
right: 0;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
#lcp-header-sidecontent.lcp-fixed {
|
||||
height:100vh
|
||||
}
|
||||
.admin-bar #lcp-sidecontent.lcp-fixed {
|
||||
height:calc(100vh - 32px)
|
||||
}
|
||||
#lcp-header-container.lcp-sticky-on-scroll.lcp-fixed {
|
||||
position: fixed;
|
||||
top:32px;
|
||||
@ -303,3 +319,12 @@ Version: 1.0
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#lcp-sidecontent {
|
||||
|
||||
scrollbar-color: red orange;
|
||||
scrollbar-width: thin;
|
||||
border-radius:5px
|
||||
}
|
||||
|
||||
|
||||
17
theme.json
17
theme.json
@ -5,6 +5,7 @@
|
||||
|
||||
],
|
||||
"settings": {
|
||||
|
||||
"appearanceTools": true,
|
||||
"color": {
|
||||
"defaultDuotone": false,
|
||||
@ -43,18 +44,23 @@
|
||||
},
|
||||
{
|
||||
"color": "#00E080",
|
||||
"name": "Accent",
|
||||
"slug": "accent"
|
||||
"name": "Accent - 1",
|
||||
"slug": "accent-1"
|
||||
},
|
||||
{
|
||||
"color": "#00FC90",
|
||||
"name": "Accent 2",
|
||||
"slug": "accent-2"
|
||||
"name": "Accent Light - 1",
|
||||
"slug": "accent-light-1"
|
||||
},
|
||||
{
|
||||
"color": "#232323",
|
||||
"name": "Font 1",
|
||||
"slug": "font-color-1"
|
||||
},
|
||||
{
|
||||
"color": "#a0a0a0",
|
||||
"name": "Font Light 1",
|
||||
"slug": "font-light-1"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -200,6 +206,7 @@
|
||||
"useRootPaddingAwareAlignments": true
|
||||
},
|
||||
"styles": {
|
||||
|
||||
"color": {
|
||||
"background": "var:preset|color|base",
|
||||
"text": "var:preset|color|contrast"
|
||||
@ -213,7 +220,7 @@
|
||||
},
|
||||
"typography": {
|
||||
"fontFamily": "var:preset|font-family|manrope",
|
||||
"fontSize": "var:preset|font-size|large",
|
||||
"fontSize": "var:preset|font-size|medium",
|
||||
"fontWeight": "300",
|
||||
"letterSpacing": "-0.1px",
|
||||
"lineHeight": "1.4"
|
||||
|
||||
@ -14,7 +14,8 @@ const excludedDirs = [
|
||||
'package-lock.json',
|
||||
'theme.zip',
|
||||
'.git',
|
||||
'react'
|
||||
'react',
|
||||
'zip-theme.js'
|
||||
];
|
||||
|
||||
// Helper function to check if a file or directory should be excluded
|
||||
|
||||
Reference in New Issue
Block a user