initial
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="23" height="24" fill="none" xmlns:v="https://vecta.io/nano"><path d="M11.5.45a11.26 11.26 0 0 0-5.796 1.564 11.64 11.64 0 0 0-4.14 4.14A11.26 11.26 0 0 0 0 11.95a11.26 11.26 0 0 0 1.564 5.796 11.64 11.64 0 0 0 4.14 4.14c1.779 1.043 3.711 1.564 5.796 1.564s4.017-.521 5.796-1.564a11.64 11.64 0 0 0 4.14-4.14C22.479 15.967 23 14.035 23 11.95s-.521-4.017-1.564-5.796a11.64 11.64 0 0 0-4.14-4.14A11.26 11.26 0 0 0 11.5.45zM8.625 16.734H6.716V7.166h1.909v9.568zm7.659 0h-5.75v-1.909h5.75v1.909zm0-3.818h-5.75v-1.932h5.75v1.932zm0-3.841h-5.75V7.166h5.75v1.909z" fill="#93003f"/></svg>
|
||||
|
After Width: | Height: | Size: 625 B |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.8 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'wp-api', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => '9c316c32b84478443dcb');
|
||||
@@ -0,0 +1 @@
|
||||
#hello-elementor-settings .components-placeholder{background:#f1f1f1}#hello-elementor-settings .hello_elementor__header{background-color:#fff;box-shadow:0 1px 0 hsla(0,0%,84%,.5),0 1px 2px #eee;margin-inline-start:-2em;padding:20px 10px}#hello-elementor-settings .hello_elementor__header .hello_elementor__container{margin:0 auto;max-width:750px}#hello-elementor-settings .hello_elementor__header .hello_elementor__container .hello_elementor__title{align-items:center;display:flex;gap:10px;justify-content:center}#hello-elementor-settings .hello_elementor__header .hello_elementor__container .hello_elementor__title .dashicon{color:#757575}#hello-elementor-settings .hello_elementor__main{margin-inline-end:auto;margin-inline-start:auto;max-width:750px}#hello-elementor-settings .hello_elementor__main .components-panel{background:none;border:none}#hello-elementor-settings .hello_elementor__main .components-panel__body{background:#fff;border:1px solid #e2e4e7;margin:1rem 0}#hello-elementor-settings .hello_elementor__main .components-notice{margin:0;margin-block-end:20px}#hello-elementor-settings .hello_elementor__main .components-notice .dashicon{color:#f0b849;padding-inline-end:10px}#hello-elementor-settings .hello_elementor__main .components-notice button{display:none}#hello-elementor-settings .hello_elementor__main .code-example{border-radius:4px;display:inline-block;font-size:10px;margin-block-end:.25rem}#hello-elementor-settings .hello_elementor__main .code-example+:not(.code-example){margin-block-start:1.25rem}#hello-elementor-settings .components-base-control__help{margin-block-start:.5rem}#hello-elementor-settings .hello_elementor__notices .components-snackbar{bottom:.5rem;position:fixed}#hello-elementor-settings .hello_elementor__action_links{margin-block-end:20px;margin-block-start:50px;text-align:center}#hello-elementor-settings .hello_elementor__action_links__title{font-weight:700}#hello-elementor-settings .hello_elementor__action_links__message{font-weight:400}
|
||||
@@ -0,0 +1,439 @@
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ 696:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports.ActionLinks = void 0;
|
||||
const ActionLinks = _ref => {
|
||||
let {
|
||||
image,
|
||||
alt,
|
||||
title,
|
||||
message,
|
||||
button,
|
||||
link
|
||||
} = _ref;
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: "hello_elementor__action_links"
|
||||
}, /*#__PURE__*/React.createElement("img", {
|
||||
src: image,
|
||||
alt: alt
|
||||
}), /*#__PURE__*/React.createElement("p", {
|
||||
className: "hello_elementor__action_links__title"
|
||||
}, title), /*#__PURE__*/React.createElement("p", {
|
||||
className: "hello_elementor__action_links__message"
|
||||
}, message), /*#__PURE__*/React.createElement("a", {
|
||||
className: "components-button is-secondary",
|
||||
href: link,
|
||||
target: "_blank",
|
||||
rel: "noreferrer"
|
||||
}, button));
|
||||
};
|
||||
exports.ActionLinks = ActionLinks;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 19:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var _interopRequireDefault = __webpack_require__(994);
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports.SettingsPage = void 0;
|
||||
var _react = __webpack_require__(609);
|
||||
var _notices = __webpack_require__(692);
|
||||
var _data = __webpack_require__(143);
|
||||
var _i18n = __webpack_require__(723);
|
||||
var _api = _interopRequireDefault(__webpack_require__(863));
|
||||
var _components = __webpack_require__(427);
|
||||
var _settingsPanel = __webpack_require__(425);
|
||||
var _actionLinksPanel = __webpack_require__(442);
|
||||
const Notices = () => {
|
||||
const notices = (0, _data.useSelect)(select => select(_notices.store).getNotices().filter(notice => 'snackbar' === notice.type), []);
|
||||
const {
|
||||
removeNotice
|
||||
} = (0, _data.useDispatch)(_notices.store);
|
||||
return /*#__PURE__*/React.createElement(_components.SnackbarList, {
|
||||
className: "edit-site-notices",
|
||||
notices: notices,
|
||||
onRemove: removeNotice
|
||||
});
|
||||
};
|
||||
const SETTINGS = {
|
||||
DESCRIPTION_META_TAG: '_description_meta_tag',
|
||||
SKIP_LINK: '_skip_link',
|
||||
HEADER_FOOTER: '_header_footer',
|
||||
PAGE_TITLE: '_page_title',
|
||||
HELLO_STYLE: '_hello_style',
|
||||
HELLO_THEME: '_hello_theme'
|
||||
};
|
||||
const SettingsPage = () => {
|
||||
const [hasLoaded, setHasLoaded] = (0, _react.useState)(false);
|
||||
const [settingsData, setSettingsData] = (0, _react.useState)({});
|
||||
const settingsPrefix = 'hello_elementor_settings';
|
||||
|
||||
/**
|
||||
* Update settings data.
|
||||
*
|
||||
* @param {string} settingsName
|
||||
* @param {string} settingsValue
|
||||
*/
|
||||
const updateSettings = (settingsName, settingsValue) => {
|
||||
setSettingsData({
|
||||
...settingsData,
|
||||
[settingsName]: settingsValue
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Save settings to server.
|
||||
*/
|
||||
const saveSettings = () => {
|
||||
const data = {};
|
||||
Object.values(SETTINGS).forEach(value => data[`${settingsPrefix}${value}`] = settingsData[value] ? 'true' : '');
|
||||
const settings = new _api.default.models.Settings(data);
|
||||
settings.save();
|
||||
(0, _data.dispatch)('core/notices').createNotice('success', (0, _i18n.__)('Settings Saved', 'hello-elementor'), {
|
||||
type: 'snackbar',
|
||||
isDismissible: true
|
||||
});
|
||||
};
|
||||
(0, _react.useEffect)(() => {
|
||||
const fetchSettings = async () => {
|
||||
try {
|
||||
await _api.default.loadPromise;
|
||||
const settings = new _api.default.models.Settings();
|
||||
const response = await settings.fetch();
|
||||
const data = {};
|
||||
Object.values(SETTINGS).forEach(value => data[value] = response[`${settingsPrefix}${value}`]);
|
||||
setSettingsData(data);
|
||||
setHasLoaded(true);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
if (hasLoaded) {
|
||||
return;
|
||||
}
|
||||
fetchSettings();
|
||||
}, [settingsData]);
|
||||
if (!hasLoaded) {
|
||||
return /*#__PURE__*/React.createElement(_components.Placeholder, null, /*#__PURE__*/React.createElement(_components.Spinner, null));
|
||||
}
|
||||
return /*#__PURE__*/React.createElement(_react.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
||||
className: "hello_elementor__header"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "hello_elementor__container"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "hello_elementor__title"
|
||||
}, /*#__PURE__*/React.createElement("h1", null, (0, _i18n.__)('Hello Theme Settings', 'hello-elementor')), /*#__PURE__*/React.createElement(_components.Button, {
|
||||
size: 'small',
|
||||
variant: 'link',
|
||||
onClick: () => {
|
||||
const dialog = document.getElementById('hello-elementor-notifications-dialog');
|
||||
if (dialog) {
|
||||
dialog.showModal();
|
||||
}
|
||||
}
|
||||
}, (0, _i18n.__)('Changelog', 'hello-elementor'))))), /*#__PURE__*/React.createElement("div", {
|
||||
className: "hello_elementor__main"
|
||||
}, /*#__PURE__*/React.createElement(_components.Panel, null, /*#__PURE__*/React.createElement(_settingsPanel.SettingsPanel, {
|
||||
SETTINGS,
|
||||
settingsData,
|
||||
updateSettings
|
||||
}), /*#__PURE__*/React.createElement(_components.Button, {
|
||||
isPrimary: true,
|
||||
onClick: saveSettings
|
||||
}, (0, _i18n.__)('Save Settings', 'hello-elementor'))), /*#__PURE__*/React.createElement(_actionLinksPanel.ActionLinksPanel, null)), /*#__PURE__*/React.createElement("div", {
|
||||
className: "hello_elementor__notices"
|
||||
}, /*#__PURE__*/React.createElement(Notices, null)));
|
||||
};
|
||||
exports.SettingsPage = SettingsPage;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 442:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports.ActionLinksPanel = void 0;
|
||||
var _i18n = __webpack_require__(723);
|
||||
var _actionLinks = __webpack_require__(696);
|
||||
const actionLinks = {
|
||||
'install-elementor': {
|
||||
image: helloAdminData.templateDirectoryURI + '/assets/images/elementor.svg',
|
||||
alt: (0, _i18n.__)('Elementor', 'hello-elementor'),
|
||||
title: (0, _i18n.__)('Install Elementor', 'hello-elementor'),
|
||||
message: (0, _i18n.__)('Create cross-site header & footer using Elementor.', 'hello-elementor'),
|
||||
button: (0, _i18n.__)('Install Elementor', 'hello-elementor'),
|
||||
link: helloAdminData.actionLinkURL
|
||||
},
|
||||
'activate-elementor': {
|
||||
image: helloAdminData.templateDirectoryURI + '/assets/images/elementor.svg',
|
||||
alt: (0, _i18n.__)('Elementor', 'hello-elementor'),
|
||||
title: (0, _i18n.__)('Activate Elementor', 'hello-elementor'),
|
||||
message: (0, _i18n.__)('Create cross-site header & footer using Elementor.', 'hello-elementor'),
|
||||
button: (0, _i18n.__)('Activate Elementor', 'hello-elementor'),
|
||||
link: helloAdminData.actionLinkURL
|
||||
},
|
||||
'activate-header-footer-experiment': {
|
||||
image: helloAdminData.templateDirectoryURI + '/assets/images/elementor.svg',
|
||||
alt: (0, _i18n.__)('Elementor', 'hello-elementor'),
|
||||
title: (0, _i18n.__)('Style using Elementor', 'hello-elementor'),
|
||||
message: (0, _i18n.__)('Design your cross-site header & footer from Elementor’s "Site Settings" panel.', 'hello-elementor'),
|
||||
button: (0, _i18n.__)('Activate header & footer experiment', 'hello-elementor'),
|
||||
link: helloAdminData.actionLinkURL
|
||||
},
|
||||
'style-header-footer': {
|
||||
image: helloAdminData.templateDirectoryURI + '/assets/images/elementor.svg',
|
||||
alt: (0, _i18n.__)('Elementor', 'hello-elementor'),
|
||||
title: (0, _i18n.__)('Style cross-site header & footer', 'hello-elementor'),
|
||||
message: (0, _i18n.__)('Customize your cross-site header & footer from Elementor’s "Site Settings" panel.', 'hello-elementor'),
|
||||
button: (0, _i18n.__)('Start Designing', 'hello-elementor'),
|
||||
link: helloAdminData.actionLinkURL
|
||||
}
|
||||
};
|
||||
const ActionLinksPanel = () => {
|
||||
if (!helloAdminData.actionLinkType) {
|
||||
return;
|
||||
}
|
||||
return /*#__PURE__*/React.createElement(_actionLinks.ActionLinks, actionLinks[helloAdminData.actionLinkType]);
|
||||
};
|
||||
exports.ActionLinksPanel = ActionLinksPanel;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 425:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports.SettingsPanel = void 0;
|
||||
var _i18n = __webpack_require__(723);
|
||||
var _components = __webpack_require__(427);
|
||||
const SettingsPanel = _ref => {
|
||||
let {
|
||||
SETTINGS,
|
||||
settingsData,
|
||||
updateSettings
|
||||
} = _ref;
|
||||
const protocol = window.location.protocol || 'https:';
|
||||
const hostname = window.location.hostname || 'example.com';
|
||||
const prefix = protocol + '//' + hostname;
|
||||
return /*#__PURE__*/React.createElement(_components.PanelBody, {
|
||||
title: (0, _i18n.__)('Hello Theme Settings', 'hello-elementor')
|
||||
}, /*#__PURE__*/React.createElement(_components.Notice, {
|
||||
status: "warning",
|
||||
isDismissible: "false"
|
||||
}, /*#__PURE__*/React.createElement(_components.Dashicon, {
|
||||
icon: "flag"
|
||||
}), (0, _i18n.__)('Be cautious, disabling some of the following options may break your website.', 'hello-elementor')), /*#__PURE__*/React.createElement(_components.ToggleControl, {
|
||||
label: (0, _i18n.__)('Disable description meta tag', 'hello-elementor'),
|
||||
help: (0, _i18n.__)('Remove the description meta tag in singular content pages that contain an excerpt.', 'hello-elementor'),
|
||||
checked: !!settingsData[SETTINGS.DESCRIPTION_META_TAG] || false,
|
||||
onChange: value => updateSettings(SETTINGS.DESCRIPTION_META_TAG, value)
|
||||
}), /*#__PURE__*/React.createElement("code", {
|
||||
className: "code-example"
|
||||
}, " <meta name=\"description\" content=\"...\" /> "), /*#__PURE__*/React.createElement(_components.ToggleControl, {
|
||||
label: (0, _i18n.__)('Disable skip link', 'hello-elementor'),
|
||||
help: (0, _i18n.__)('Remove the "Skip to content" link used by screen-readers and users navigating with a keyboard.', 'hello-elementor'),
|
||||
checked: !!settingsData[SETTINGS.SKIP_LINK] || false,
|
||||
onChange: value => updateSettings(SETTINGS.SKIP_LINK, value)
|
||||
}), /*#__PURE__*/React.createElement("code", {
|
||||
className: "code-example"
|
||||
}, " <a class=\"skip-link screen-reader-text\" href=\"#content\"> Skip to content </a> "), /*#__PURE__*/React.createElement(_components.ToggleControl, {
|
||||
label: (0, _i18n.__)('Disable cross-site header & footer', 'hello-elementor'),
|
||||
help: (0, _i18n.__)('Remove the header & footer sections from all pages, and their CSS/JS files.', 'hello-elementor'),
|
||||
checked: !!settingsData[SETTINGS.HEADER_FOOTER] || false,
|
||||
onChange: value => updateSettings(SETTINGS.HEADER_FOOTER, value)
|
||||
}), /*#__PURE__*/React.createElement("code", {
|
||||
className: "code-example"
|
||||
}, " <header id=\"site-header\" class=\"site-header\"> ... </header> "), /*#__PURE__*/React.createElement("code", {
|
||||
className: "code-example"
|
||||
}, " <footer id=\"site-footer\" class=\"site-footer\"> ... </footer> "), /*#__PURE__*/React.createElement(_components.ToggleControl, {
|
||||
label: (0, _i18n.__)('Disable page title', 'hello-elementor'),
|
||||
help: (0, _i18n.__)('Remove the section above the content that contains the main heading of the page.', 'hello-elementor'),
|
||||
checked: !!settingsData[SETTINGS.PAGE_TITLE] || false,
|
||||
onChange: value => updateSettings(SETTINGS.PAGE_TITLE, value)
|
||||
}), /*#__PURE__*/React.createElement("code", {
|
||||
className: "code-example"
|
||||
}, " <div class=\"page-header\"> <h1 class=\"entry-title\"> Post title </h1> </div> "), /*#__PURE__*/React.createElement(_components.ToggleControl, {
|
||||
label: (0, _i18n.__)('Unregister Hello style.css', 'hello-elementor'),
|
||||
help: (0, _i18n.__)("Disable Hello theme's style.css file which contains CSS reset rules for unified cross-browser view.", 'hello-elementor'),
|
||||
checked: !!settingsData[SETTINGS.HELLO_STYLE] || false,
|
||||
onChange: value => updateSettings(SETTINGS.HELLO_STYLE, value)
|
||||
}), /*#__PURE__*/React.createElement("code", {
|
||||
className: "code-example"
|
||||
}, " <link rel=\"stylesheet\" href=\"", prefix, "/wp-content/themes/hello-elementor/style.min.css\" /> "), /*#__PURE__*/React.createElement(_components.ToggleControl, {
|
||||
label: (0, _i18n.__)('Unregister Hello theme.css', 'hello-elementor'),
|
||||
help: (0, _i18n.__)("Disable Hello theme's theme.css file which contains CSS rules that style WordPress elements.", 'hello-elementor'),
|
||||
checked: !!settingsData[SETTINGS.HELLO_THEME] || false,
|
||||
onChange: value => updateSettings(SETTINGS.HELLO_THEME, value)
|
||||
}), /*#__PURE__*/React.createElement("code", {
|
||||
className: "code-example"
|
||||
}, " <link rel=\"stylesheet\" href=\"", prefix, "/wp-content/themes/hello-elementor/theme.min.css\" /> "));
|
||||
};
|
||||
exports.SettingsPanel = SettingsPanel;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 374:
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
// extracted by mini-css-extract-plugin
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 609:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = window["React"];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 863:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = window["wp"]["api"];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 427:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = window["wp"]["components"];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 143:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = window["wp"]["data"];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 87:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = window["wp"]["element"];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 723:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = window["wp"]["i18n"];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 692:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = window["wp"]["notices"];
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 994:
|
||||
/***/ ((module) => {
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
"default": obj
|
||||
};
|
||||
}
|
||||
module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
var __webpack_exports__ = {};
|
||||
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
|
||||
(() => {
|
||||
"use strict";
|
||||
|
||||
|
||||
__webpack_require__(374);
|
||||
var _element = __webpack_require__(87);
|
||||
var _settingsPage = __webpack_require__(19);
|
||||
const App = () => {
|
||||
return /*#__PURE__*/React.createElement(_settingsPage.SettingsPage, null);
|
||||
};
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const rootElement = document.getElementById('hello-elementor-settings');
|
||||
if (rootElement) {
|
||||
(0, _element.render)( /*#__PURE__*/React.createElement(App, null), rootElement);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
/******/ })()
|
||||
;
|
||||
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'wp-api', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => '223149ed2e62fccffebf');
|
||||
@@ -0,0 +1 @@
|
||||
#hello-elementor-settings .components-placeholder{background:#f1f1f1}#hello-elementor-settings .hello_elementor__header{background-color:#fff;box-shadow:0 1px 0 hsla(0,0%,84%,.5),0 1px 2px #eee;margin-inline-start:-2em;padding:20px 10px}#hello-elementor-settings .hello_elementor__header .hello_elementor__container{margin:0 auto;max-width:750px}#hello-elementor-settings .hello_elementor__header .hello_elementor__container .hello_elementor__title{align-items:center;display:flex;gap:10px;justify-content:center}#hello-elementor-settings .hello_elementor__header .hello_elementor__container .hello_elementor__title .dashicon{color:#757575}#hello-elementor-settings .hello_elementor__main{margin-inline-end:auto;margin-inline-start:auto;max-width:750px}#hello-elementor-settings .hello_elementor__main .components-panel{background:none;border:none}#hello-elementor-settings .hello_elementor__main .components-panel__body{background:#fff;border:1px solid #e2e4e7;margin:1rem 0}#hello-elementor-settings .hello_elementor__main .components-notice{margin:0;margin-block-end:20px}#hello-elementor-settings .hello_elementor__main .components-notice .dashicon{color:#f0b849;padding-inline-end:10px}#hello-elementor-settings .hello_elementor__main .components-notice button{display:none}#hello-elementor-settings .hello_elementor__main .code-example{border-radius:4px;display:inline-block;font-size:10px;margin-block-end:.25rem}#hello-elementor-settings .hello_elementor__main .code-example+:not(.code-example){margin-block-start:1.25rem}#hello-elementor-settings .components-base-control__help{margin-block-start:.5rem}#hello-elementor-settings .hello_elementor__notices .components-snackbar{bottom:.5rem;position:fixed}#hello-elementor-settings .hello_elementor__action_links{margin-block-end:20px;margin-block-start:50px;text-align:center}#hello-elementor-settings .hello_elementor__action_links__title{font-weight:700}#hello-elementor-settings .hello_elementor__action_links__message{font-weight:400}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => 'e78d65f4c12a29fb3a94');
|
||||
@@ -0,0 +1,396 @@
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ 706:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var _interopRequireDefault = __webpack_require__(994);
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(__webpack_require__(693));
|
||||
var _controlsHook = _interopRequireDefault(__webpack_require__(239));
|
||||
class _default extends $e.modules.ComponentBase {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
(0, _defineProperty2.default)(this, "pages", {});
|
||||
}
|
||||
getNamespace() {
|
||||
return 'hello-elementor';
|
||||
}
|
||||
defaultHooks() {
|
||||
return this.importHooks({
|
||||
ControlsHook: _controlsHook.default
|
||||
});
|
||||
}
|
||||
}
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 239:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
class ControlsHook extends $e.modules.hookUI.After {
|
||||
getCommand() {
|
||||
// Command to listen.
|
||||
return 'document/elements/settings';
|
||||
}
|
||||
getId() {
|
||||
// Unique id for the hook.
|
||||
return 'hello-elementor-editor-controls-handler';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Hello Elementor Theme Controls
|
||||
*
|
||||
* Returns an object in which the keys are control IDs, and the values are the selectors of the elements that need
|
||||
* to be targeted in the apply() method.
|
||||
*
|
||||
* Example return value:
|
||||
* {
|
||||
* hello_elementor_show_logo: '.site-header .site-header-logo',
|
||||
* hello_elementor_show_menu: '.site-header .site-header-menu',
|
||||
* }
|
||||
*/
|
||||
getHelloThemeControls() {
|
||||
return {
|
||||
hello_header_logo_display: {
|
||||
selector: '.site-header .site-logo, .site-header .site-title',
|
||||
callback: ($element, args) => {
|
||||
this.toggleShowHideClass($element, args.settings.hello_header_logo_display);
|
||||
}
|
||||
},
|
||||
hello_header_menu_display: {
|
||||
selector: '.site-header .site-navigation, .site-header .site-navigation-toggle-holder',
|
||||
callback: ($element, args) => {
|
||||
this.toggleShowHideClass($element, args.settings.hello_header_menu_display);
|
||||
}
|
||||
},
|
||||
hello_header_tagline_display: {
|
||||
selector: '.site-header .site-description',
|
||||
callback: ($element, args) => {
|
||||
this.toggleShowHideClass($element, args.settings.hello_header_tagline_display);
|
||||
}
|
||||
},
|
||||
hello_header_logo_type: {
|
||||
selector: '.site-header .site-branding',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'show-',
|
||||
inputOptions = args.container.controls.hello_header_logo_type.options,
|
||||
inputValue = args.settings.hello_header_logo_type;
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_header_layout: {
|
||||
selector: '.site-header',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'header-',
|
||||
inputOptions = args.container.controls.hello_header_layout.options,
|
||||
inputValue = args.settings.hello_header_layout;
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_header_width: {
|
||||
selector: '.site-header',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'header-',
|
||||
inputOptions = args.container.controls.hello_header_width.options,
|
||||
inputValue = args.settings.hello_header_width;
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_header_menu_layout: {
|
||||
selector: '.site-header',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'menu-layout-',
|
||||
inputOptions = args.container.controls.hello_header_menu_layout.options,
|
||||
inputValue = args.settings.hello_header_menu_layout;
|
||||
|
||||
// No matter what, close the mobile menu
|
||||
$element.find('.site-navigation-toggle-holder').removeClass('elementor-active');
|
||||
$element.find('.site-navigation-dropdown').removeClass('show');
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_header_menu_dropdown: {
|
||||
selector: '.site-header',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'menu-dropdown-',
|
||||
inputOptions = args.container.controls.hello_header_menu_dropdown.options,
|
||||
inputValue = args.settings.hello_header_menu_dropdown;
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_footer_logo_display: {
|
||||
selector: '.site-footer .site-logo, .site-footer .site-title',
|
||||
callback: ($element, args) => {
|
||||
this.toggleShowHideClass($element, args.settings.hello_footer_logo_display);
|
||||
}
|
||||
},
|
||||
hello_footer_tagline_display: {
|
||||
selector: '.site-footer .site-description',
|
||||
callback: ($element, args) => {
|
||||
this.toggleShowHideClass($element, args.settings.hello_footer_tagline_display);
|
||||
}
|
||||
},
|
||||
hello_footer_menu_display: {
|
||||
selector: '.site-footer .site-navigation',
|
||||
callback: ($element, args) => {
|
||||
this.toggleShowHideClass($element, args.settings.hello_footer_menu_display);
|
||||
}
|
||||
},
|
||||
hello_footer_copyright_display: {
|
||||
selector: '.site-footer .copyright',
|
||||
callback: ($element, args) => {
|
||||
const $footerContainer = $element.closest('#site-footer'),
|
||||
inputValue = args.settings.hello_footer_copyright_display;
|
||||
this.toggleShowHideClass($element, inputValue);
|
||||
$footerContainer.toggleClass('footer-has-copyright', 'yes' === inputValue);
|
||||
}
|
||||
},
|
||||
hello_footer_logo_type: {
|
||||
selector: '.site-footer .site-branding',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'show-',
|
||||
inputOptions = args.container.controls.hello_footer_logo_type.options,
|
||||
inputValue = args.settings.hello_footer_logo_type;
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_footer_layout: {
|
||||
selector: '.site-footer',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'footer-',
|
||||
inputOptions = args.container.controls.hello_footer_layout.options,
|
||||
inputValue = args.settings.hello_footer_layout;
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_footer_width: {
|
||||
selector: '.site-footer',
|
||||
callback: ($element, args) => {
|
||||
const classPrefix = 'footer-',
|
||||
inputOptions = args.container.controls.hello_footer_width.options,
|
||||
inputValue = args.settings.hello_footer_width;
|
||||
this.toggleLayoutClass($element, classPrefix, inputOptions, inputValue);
|
||||
}
|
||||
},
|
||||
hello_footer_copyright_text: {
|
||||
selector: '.site-footer .copyright',
|
||||
callback: ($element, args) => {
|
||||
const inputValue = args.settings.hello_footer_copyright_text;
|
||||
$element.find('p').text(inputValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle show and hide classes on containers
|
||||
*
|
||||
* This will remove the .show and .hide clases from the element, then apply the new class
|
||||
*
|
||||
* @param {jQuery} element
|
||||
* @param {string} inputValue
|
||||
*/
|
||||
toggleShowHideClass(element, inputValue) {
|
||||
element.removeClass('hide').removeClass('show').addClass(inputValue ? 'show' : 'hide');
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle layout classes on containers
|
||||
*
|
||||
* This will cleanly set classes onto which ever container we want to target, removing the old classes and adding the new one
|
||||
*
|
||||
* @param {jQuery} element
|
||||
* @param {string} classPrefix
|
||||
* @param {Object} inputOptions
|
||||
* @param {string} inputValue
|
||||
*
|
||||
*/
|
||||
toggleLayoutClass(element, classPrefix, inputOptions, inputValue) {
|
||||
// Loop through the possible classes and remove the one that's not in use
|
||||
Object.entries(inputOptions).forEach(_ref => {
|
||||
let [key] = _ref;
|
||||
element.removeClass(classPrefix + key);
|
||||
});
|
||||
|
||||
// Append the class which we want to use onto the element
|
||||
if ('' !== inputValue) {
|
||||
element.addClass(classPrefix + inputValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the conditions under which the hook will run.
|
||||
*
|
||||
* @param {Object} args
|
||||
*/
|
||||
getConditions(args) {
|
||||
const isKit = 'kit' === elementor.documents.getCurrent().config.type,
|
||||
changedControls = Object.keys(args.settings),
|
||||
isSingleSetting = 1 === changedControls.length;
|
||||
|
||||
// If the document is not a kit, or there are no changed settings, or there is more than one single changed
|
||||
// setting, don't run the hook.
|
||||
if (!isKit || !args.settings || !isSingleSetting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the changed control is in the list of theme controls, return true to run the hook.
|
||||
// Otherwise, return false so the hook doesn't run.
|
||||
return !!Object.keys(this.getHelloThemeControls()).includes(changedControls[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The hook logic.
|
||||
*
|
||||
* @param {Object} args
|
||||
*/
|
||||
apply(args) {
|
||||
const allThemeControls = this.getHelloThemeControls(),
|
||||
// Extract the control ID from the passed args
|
||||
controlId = Object.keys(args.settings)[0],
|
||||
controlConfig = allThemeControls[controlId],
|
||||
// Find the element that needs to be targeted by the control.
|
||||
$element = elementor.$previewContents.find(controlConfig.selector);
|
||||
controlConfig.callback($element, args);
|
||||
}
|
||||
}
|
||||
exports["default"] = ControlsHook;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 693:
|
||||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||
|
||||
var toPropertyKey = __webpack_require__(736);
|
||||
function _defineProperty(obj, key, value) {
|
||||
key = toPropertyKey(key);
|
||||
if (key in obj) {
|
||||
Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
} else {
|
||||
obj[key] = value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 994:
|
||||
/***/ ((module) => {
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
"default": obj
|
||||
};
|
||||
}
|
||||
module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 45:
|
||||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||
|
||||
var _typeof = (__webpack_require__(738)["default"]);
|
||||
function toPrimitive(t, r) {
|
||||
if ("object" != _typeof(t) || !t) return t;
|
||||
var e = t[Symbol.toPrimitive];
|
||||
if (void 0 !== e) {
|
||||
var i = e.call(t, r || "default");
|
||||
if ("object" != _typeof(i)) return i;
|
||||
throw new TypeError("@@toPrimitive must return a primitive value.");
|
||||
}
|
||||
return ("string" === r ? String : Number)(t);
|
||||
}
|
||||
module.exports = toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 736:
|
||||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||
|
||||
var _typeof = (__webpack_require__(738)["default"]);
|
||||
var toPrimitive = __webpack_require__(45);
|
||||
function toPropertyKey(t) {
|
||||
var i = toPrimitive(t, "string");
|
||||
return "symbol" == _typeof(i) ? i : i + "";
|
||||
}
|
||||
module.exports = toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 738:
|
||||
/***/ ((module) => {
|
||||
|
||||
function _typeof(o) {
|
||||
"@babel/helpers - typeof";
|
||||
|
||||
return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
|
||||
return typeof o;
|
||||
} : function (o) {
|
||||
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
||||
}, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(o);
|
||||
}
|
||||
module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
var __webpack_exports__ = {};
|
||||
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
|
||||
(() => {
|
||||
"use strict";
|
||||
|
||||
|
||||
var _interopRequireDefault = __webpack_require__(994);
|
||||
var _component = _interopRequireDefault(__webpack_require__(706));
|
||||
$e.components.register(new _component.default());
|
||||
})();
|
||||
|
||||
/******/ })()
|
||||
;
|
||||
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => '0eec8e66880717bf7da1');
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => '2f03dc39ec58b53d53c8');
|
||||
@@ -0,0 +1,69 @@
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
var __webpack_exports__ = {};
|
||||
|
||||
|
||||
class elementorHelloThemeHandler {
|
||||
constructor() {
|
||||
this.initSettings();
|
||||
this.initElements();
|
||||
this.bindEvents();
|
||||
}
|
||||
initSettings() {
|
||||
this.settings = {
|
||||
selectors: {
|
||||
menuToggle: '.site-header .site-navigation-toggle',
|
||||
menuToggleHolder: '.site-header .site-navigation-toggle-holder',
|
||||
dropdownMenu: '.site-header .site-navigation-dropdown'
|
||||
}
|
||||
};
|
||||
}
|
||||
initElements() {
|
||||
this.elements = {
|
||||
window,
|
||||
menuToggle: document.querySelector(this.settings.selectors.menuToggle),
|
||||
menuToggleHolder: document.querySelector(this.settings.selectors.menuToggleHolder),
|
||||
dropdownMenu: document.querySelector(this.settings.selectors.dropdownMenu)
|
||||
};
|
||||
}
|
||||
bindEvents() {
|
||||
var _this$elements$menuTo;
|
||||
if (!this.elements.menuToggleHolder || (_this$elements$menuTo = this.elements.menuToggleHolder) !== null && _this$elements$menuTo !== void 0 && _this$elements$menuTo.classList.contains('hide')) {
|
||||
return;
|
||||
}
|
||||
this.elements.menuToggle.addEventListener('click', () => this.handleMenuToggle());
|
||||
this.elements.dropdownMenu.querySelectorAll('.menu-item-has-children > a').forEach(anchorElement => anchorElement.addEventListener('click', event => this.handleMenuChildren(event)));
|
||||
}
|
||||
closeMenuItems() {
|
||||
this.elements.menuToggleHolder.classList.remove('elementor-active');
|
||||
this.elements.window.removeEventListener('resize', () => this.closeMenuItems());
|
||||
}
|
||||
handleMenuToggle() {
|
||||
const isDropdownVisible = !this.elements.menuToggleHolder.classList.contains('elementor-active');
|
||||
this.elements.menuToggle.setAttribute('aria-expanded', isDropdownVisible);
|
||||
this.elements.dropdownMenu.setAttribute('aria-hidden', !isDropdownVisible);
|
||||
this.elements.dropdownMenu.inert = !isDropdownVisible;
|
||||
this.elements.menuToggleHolder.classList.toggle('elementor-active', isDropdownVisible);
|
||||
|
||||
// Always close all sub active items.
|
||||
this.elements.dropdownMenu.querySelectorAll('.elementor-active').forEach(item => item.classList.remove('elementor-active'));
|
||||
if (isDropdownVisible) {
|
||||
this.elements.window.addEventListener('resize', () => this.closeMenuItems());
|
||||
} else {
|
||||
this.elements.window.removeEventListener('resize', () => this.closeMenuItems());
|
||||
}
|
||||
}
|
||||
handleMenuChildren(event) {
|
||||
const anchor = event.currentTarget;
|
||||
const parentLi = anchor.parentElement;
|
||||
if (!(parentLi !== null && parentLi !== void 0 && parentLi.classList)) {
|
||||
return;
|
||||
}
|
||||
parentLi.classList.toggle('elementor-active');
|
||||
}
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new elementorHelloThemeHandler();
|
||||
});
|
||||
/******/ })()
|
||||
;
|
||||
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => '1d92b8a230e0f487fd38');
|
||||
@@ -0,0 +1 @@
|
||||
(()=>{"use strict";class elementorHelloThemeHandler{constructor(){this.initSettings(),this.initElements(),this.bindEvents()}initSettings(){this.settings={selectors:{menuToggle:".site-header .site-navigation-toggle",menuToggleHolder:".site-header .site-navigation-toggle-holder",dropdownMenu:".site-header .site-navigation-dropdown"}}}initElements(){this.elements={window,menuToggle:document.querySelector(this.settings.selectors.menuToggle),menuToggleHolder:document.querySelector(this.settings.selectors.menuToggleHolder),dropdownMenu:document.querySelector(this.settings.selectors.dropdownMenu)}}bindEvents(){var e;!this.elements.menuToggleHolder||null!==(e=this.elements.menuToggleHolder)&&void 0!==e&&e.classList.contains("hide")||(this.elements.menuToggle.addEventListener("click",(()=>this.handleMenuToggle())),this.elements.dropdownMenu.querySelectorAll(".menu-item-has-children > a").forEach((e=>e.addEventListener("click",(e=>this.handleMenuChildren(e))))))}closeMenuItems(){this.elements.menuToggleHolder.classList.remove("elementor-active"),this.elements.window.removeEventListener("resize",(()=>this.closeMenuItems()))}handleMenuToggle(){const e=!this.elements.menuToggleHolder.classList.contains("elementor-active");this.elements.menuToggle.setAttribute("aria-expanded",e),this.elements.dropdownMenu.setAttribute("aria-hidden",!e),this.elements.dropdownMenu.inert=!e,this.elements.menuToggleHolder.classList.toggle("elementor-active",e),this.elements.dropdownMenu.querySelectorAll(".elementor-active").forEach((e=>e.classList.remove("elementor-active"))),e?this.elements.window.addEventListener("resize",(()=>this.closeMenuItems())):this.elements.window.removeEventListener("resize",(()=>this.closeMenuItems()))}handleMenuChildren(e){const t=e.currentTarget.parentElement;null!=t&&t.classList&&t.classList.toggle("elementor-active")}}document.addEventListener("DOMContentLoaded",(()=>{new elementorHelloThemeHandler}))})();
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying the list of comments and the comment form.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
if ( ! post_type_supports( get_post_type(), 'comments' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! have_comments() && ! comments_open() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Comment Reply Script.
|
||||
if ( comments_open() && get_option( 'thread_comments' ) ) {
|
||||
wp_enqueue_script( 'comment-reply' );
|
||||
}
|
||||
?>
|
||||
<section id="comments" class="comments-area">
|
||||
|
||||
<?php if ( have_comments() ) : ?>
|
||||
<h2 class="title-comments">
|
||||
<?php
|
||||
$comments_number = get_comments_number();
|
||||
if ( '1' === $comments_number ) {
|
||||
printf( esc_html_x( 'One Response', 'comments title', 'hello-elementor' ) );
|
||||
} else {
|
||||
printf(
|
||||
/* translators: %s: Number of comments. */
|
||||
esc_html(
|
||||
_nx(
|
||||
'%s Response',
|
||||
'%s Responses',
|
||||
$comments_number,
|
||||
'comments title',
|
||||
'hello-elementor'
|
||||
)
|
||||
),
|
||||
esc_html( number_format_i18n( $comments_number ) )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</h2>
|
||||
|
||||
<?php the_comments_navigation(); ?>
|
||||
|
||||
<ol class="comment-list">
|
||||
<?php
|
||||
wp_list_comments(
|
||||
[
|
||||
'style' => 'ol',
|
||||
'short_ping' => true,
|
||||
'avatar_size' => 42,
|
||||
]
|
||||
);
|
||||
?>
|
||||
</ol>
|
||||
|
||||
<?php the_comments_navigation(); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
comment_form(
|
||||
[
|
||||
'title_reply_before' => '<h2 id="reply-title" class="comment-reply-title">',
|
||||
'title_reply_after' => '</h2>',
|
||||
]
|
||||
);
|
||||
?>
|
||||
|
||||
</section>
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Style for your Customizer editor.
|
||||
*/
|
||||
#accordion-section-hello-options .accordion-section-title {
|
||||
color: #c36;
|
||||
}
|
||||
#accordion-section-hello-options .accordion-section-title:after {
|
||||
color: #c36;
|
||||
}
|
||||
|
||||
#customize-control-hello-header-footer .hello-action-links {
|
||||
margin: 15px auto;
|
||||
text-align: center;
|
||||
}
|
||||
#customize-control-hello-header-footer .hello-action-links-title {
|
||||
font-weight: 600;
|
||||
margin: 10px 0;
|
||||
}
|
||||
#customize-control-hello-header-footer .hello-action-links-message {
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
#accordion-section-hello-upsell-elementor-pro {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin: 20px 20px 30px;
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
box-shadow: 2px 8px 20px 0px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
#accordion-section-hello-upsell-elementor-pro h3,
|
||||
#accordion-section-hello-upsell-elementor-pro p {
|
||||
background-color: transparent !important;
|
||||
border: 0 !important;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
#accordion-section-hello-upsell-elementor-pro h3 {
|
||||
font-weight: bold;
|
||||
}
|
||||
#accordion-section-hello-upsell-elementor-pro .accordion-section-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
margin-block-start: 16px;
|
||||
}
|
||||
#accordion-section-hello-upsell-elementor-pro .accordion-section-buttons a {
|
||||
color: #fff;
|
||||
background-color: #92003B;
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#accordion-section-hello-options .accordion-section-title,#accordion-section-hello-options .accordion-section-title:after{color:#c36}#customize-control-hello-header-footer .hello-action-links{margin:15px auto;text-align:center}#customize-control-hello-header-footer .hello-action-links-title{font-weight:600;margin:10px 0}#customize-control-hello-header-footer .hello-action-links-message{margin:0 0 20px}#accordion-section-hello-upsell-elementor-pro{display:flex!important;flex-direction:column;gap:8px;margin:20px 20px 30px;padding:16px;background-color:#fff;box-shadow:2px 8px 20px 0 rgba(0,0,0,.2)}#accordion-section-hello-upsell-elementor-pro h3,#accordion-section-hello-upsell-elementor-pro p{background-color:transparent!important;border:0!important;padding:0;margin:0;text-decoration:none}#accordion-section-hello-upsell-elementor-pro h3{font-weight:700}#accordion-section-hello-upsell-elementor-pro .accordion-section-buttons{display:flex;justify-content:flex-end;gap:8px;margin-block-start:16px}#accordion-section-hello-upsell-elementor-pro .accordion-section-buttons a{color:#fff;background-color:#92003b;border-radius:4px;padding:8px 16px;text-decoration:none}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* WordPress editor styles
|
||||
*/
|
||||
/**
|
||||
* Loading first in the style.scss & classic-editor.scss
|
||||
*/
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
}
|
||||
|
||||
p {
|
||||
margin-block-end: 0.75rem;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: monospace;
|
||||
font-size: 1em;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}p{margin-block-end:.75rem}img{max-width:100%;height:auto;vertical-align:middle;border-style:none}pre{font-family:monospace;font-size:1em;white-space:pre-wrap}code,kbd,pre,samp{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem}blockquote{font-style:italic}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Elementor editor styling
|
||||
*/
|
||||
.hello-elementor.elementor-nerd-box .elementor-nerd-box-title {
|
||||
margin-block-start: 24px;
|
||||
}
|
||||
.hello-elementor.elementor-nerd-box .elementor-nerd-box-message {
|
||||
margin-block-start: 12px;
|
||||
}
|
||||
.hello-elementor.elementor-nerd-box .elementor-nerd-box-link {
|
||||
margin-block-start: 24px;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.hello-elementor.elementor-nerd-box .elementor-nerd-box-title{margin-block-start:24px}.hello-elementor.elementor-nerd-box .elementor-nerd-box-message{margin-block-start:12px}.hello-elementor.elementor-nerd-box .elementor-nerd-box-link{margin-block-start:24px}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying the footer.
|
||||
*
|
||||
* Contains the body & html closing tags.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'elementor_theme_do_location' ) || ! elementor_theme_do_location( 'footer' ) ) {
|
||||
if ( hello_elementor_display_header_footer() ) {
|
||||
if ( did_action( 'elementor/loaded' ) && hello_header_footer_experiment_active() ) {
|
||||
get_template_part( 'template-parts/dynamic-footer' );
|
||||
} else {
|
||||
get_template_part( 'template-parts/footer' );
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<?php wp_footer(); ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
/**
|
||||
* Theme functions and definitions
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
|
||||
use Elementor\WPNotificationsPackage\V110\Notifications as ThemeNotifications;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
define( 'HELLO_ELEMENTOR_VERSION', '3.3.0' );
|
||||
|
||||
if ( ! isset( $content_width ) ) {
|
||||
$content_width = 800; // Pixels.
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_setup' ) ) {
|
||||
/**
|
||||
* Set up theme support.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_elementor_setup() {
|
||||
if ( is_admin() ) {
|
||||
hello_maybe_update_theme_version_in_db();
|
||||
}
|
||||
|
||||
if ( apply_filters( 'hello_elementor_register_menus', true ) ) {
|
||||
register_nav_menus( [ 'menu-1' => esc_html__( 'Header', 'hello-elementor' ) ] );
|
||||
register_nav_menus( [ 'menu-2' => esc_html__( 'Footer', 'hello-elementor' ) ] );
|
||||
}
|
||||
|
||||
if ( apply_filters( 'hello_elementor_post_type_support', true ) ) {
|
||||
add_post_type_support( 'page', 'excerpt' );
|
||||
}
|
||||
|
||||
if ( apply_filters( 'hello_elementor_add_theme_support', true ) ) {
|
||||
add_theme_support( 'post-thumbnails' );
|
||||
add_theme_support( 'automatic-feed-links' );
|
||||
add_theme_support( 'title-tag' );
|
||||
add_theme_support(
|
||||
'html5',
|
||||
[
|
||||
'search-form',
|
||||
'comment-form',
|
||||
'comment-list',
|
||||
'gallery',
|
||||
'caption',
|
||||
'script',
|
||||
'style',
|
||||
]
|
||||
);
|
||||
add_theme_support(
|
||||
'custom-logo',
|
||||
[
|
||||
'height' => 100,
|
||||
'width' => 350,
|
||||
'flex-height' => true,
|
||||
'flex-width' => true,
|
||||
]
|
||||
);
|
||||
add_theme_support( 'align-wide' );
|
||||
add_theme_support( 'responsive-embeds' );
|
||||
|
||||
/*
|
||||
* Editor Styles
|
||||
*/
|
||||
add_theme_support( 'editor-styles' );
|
||||
add_editor_style( 'editor-styles.css' );
|
||||
|
||||
/*
|
||||
* WooCommerce.
|
||||
*/
|
||||
if ( apply_filters( 'hello_elementor_add_woocommerce_support', true ) ) {
|
||||
// WooCommerce in general.
|
||||
add_theme_support( 'woocommerce' );
|
||||
// Enabling WooCommerce product gallery features (are off by default since WC 3.0.0).
|
||||
// zoom.
|
||||
add_theme_support( 'wc-product-gallery-zoom' );
|
||||
// lightbox.
|
||||
add_theme_support( 'wc-product-gallery-lightbox' );
|
||||
// swipe.
|
||||
add_theme_support( 'wc-product-gallery-slider' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'after_setup_theme', 'hello_elementor_setup' );
|
||||
|
||||
function hello_maybe_update_theme_version_in_db() {
|
||||
$theme_version_option_name = 'hello_theme_version';
|
||||
// The theme version saved in the database.
|
||||
$hello_theme_db_version = get_option( $theme_version_option_name );
|
||||
|
||||
// If the 'hello_theme_version' option does not exist in the DB, or the version needs to be updated, do the update.
|
||||
if ( ! $hello_theme_db_version || version_compare( $hello_theme_db_version, HELLO_ELEMENTOR_VERSION, '<' ) ) {
|
||||
update_option( $theme_version_option_name, HELLO_ELEMENTOR_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_display_header_footer' ) ) {
|
||||
/**
|
||||
* Check whether to display header footer.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function hello_elementor_display_header_footer() {
|
||||
$hello_elementor_header_footer = true;
|
||||
|
||||
return apply_filters( 'hello_elementor_header_footer', $hello_elementor_header_footer );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_scripts_styles' ) ) {
|
||||
/**
|
||||
* Theme Scripts & Styles.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_elementor_scripts_styles() {
|
||||
$min_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
if ( apply_filters( 'hello_elementor_enqueue_style', true ) ) {
|
||||
wp_enqueue_style(
|
||||
'hello-elementor',
|
||||
get_template_directory_uri() . '/style' . $min_suffix . '.css',
|
||||
[],
|
||||
HELLO_ELEMENTOR_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
if ( apply_filters( 'hello_elementor_enqueue_theme_style', true ) ) {
|
||||
wp_enqueue_style(
|
||||
'hello-elementor-theme-style',
|
||||
get_template_directory_uri() . '/theme' . $min_suffix . '.css',
|
||||
[],
|
||||
HELLO_ELEMENTOR_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
if ( hello_elementor_display_header_footer() ) {
|
||||
wp_enqueue_style(
|
||||
'hello-elementor-header-footer',
|
||||
get_template_directory_uri() . '/header-footer' . $min_suffix . '.css',
|
||||
[],
|
||||
HELLO_ELEMENTOR_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'wp_enqueue_scripts', 'hello_elementor_scripts_styles' );
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_register_elementor_locations' ) ) {
|
||||
/**
|
||||
* Register Elementor Locations.
|
||||
*
|
||||
* @param ElementorPro\Modules\ThemeBuilder\Classes\Locations_Manager $elementor_theme_manager theme manager.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_elementor_register_elementor_locations( $elementor_theme_manager ) {
|
||||
if ( apply_filters( 'hello_elementor_register_elementor_locations', true ) ) {
|
||||
$elementor_theme_manager->register_all_core_location();
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'elementor/theme/register_locations', 'hello_elementor_register_elementor_locations' );
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_content_width' ) ) {
|
||||
/**
|
||||
* Set default content width.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_elementor_content_width() {
|
||||
$GLOBALS['content_width'] = apply_filters( 'hello_elementor_content_width', 800 );
|
||||
}
|
||||
}
|
||||
add_action( 'after_setup_theme', 'hello_elementor_content_width', 0 );
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_add_description_meta_tag' ) ) {
|
||||
/**
|
||||
* Add description meta tag with excerpt text.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_elementor_add_description_meta_tag() {
|
||||
if ( ! apply_filters( 'hello_elementor_description_meta_tag', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! is_singular() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post = get_queried_object();
|
||||
if ( empty( $post->post_excerpt ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<meta name="description" content="' . esc_attr( wp_strip_all_tags( $post->post_excerpt ) ) . '">' . "\n";
|
||||
}
|
||||
}
|
||||
add_action( 'wp_head', 'hello_elementor_add_description_meta_tag' );
|
||||
|
||||
// Admin notice
|
||||
if ( is_admin() ) {
|
||||
require get_template_directory() . '/includes/admin-functions.php';
|
||||
}
|
||||
|
||||
// Settings page
|
||||
require get_template_directory() . '/includes/settings-functions.php';
|
||||
|
||||
// Header & footer styling option, inside Elementor
|
||||
require get_template_directory() . '/includes/elementor-functions.php';
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_customizer' ) ) {
|
||||
// Customizer controls
|
||||
function hello_elementor_customizer() {
|
||||
if ( ! is_customize_preview() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! hello_elementor_display_header_footer() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
require get_template_directory() . '/includes/customizer-functions.php';
|
||||
}
|
||||
}
|
||||
add_action( 'init', 'hello_elementor_customizer' );
|
||||
|
||||
if ( ! function_exists( 'hello_elementor_check_hide_title' ) ) {
|
||||
/**
|
||||
* Check whether to display the page title.
|
||||
*
|
||||
* @param bool $val default value.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function hello_elementor_check_hide_title( $val ) {
|
||||
if ( defined( 'ELEMENTOR_VERSION' ) ) {
|
||||
$current_doc = Elementor\Plugin::instance()->documents->get( get_the_ID() );
|
||||
if ( $current_doc && 'yes' === $current_doc->get_settings( 'hide_title' ) ) {
|
||||
$val = false;
|
||||
}
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
add_filter( 'hello_elementor_page_title', 'hello_elementor_check_hide_title' );
|
||||
|
||||
/**
|
||||
* BC:
|
||||
* In v2.7.0 the theme removed the `hello_elementor_body_open()` from `header.php` replacing it with `wp_body_open()`.
|
||||
* The following code prevents fatal errors in child themes that still use this function.
|
||||
*/
|
||||
if ( ! function_exists( 'hello_elementor_body_open' ) ) {
|
||||
function hello_elementor_body_open() {
|
||||
wp_body_open();
|
||||
}
|
||||
}
|
||||
|
||||
function hello_elementor_get_theme_notifications(): ThemeNotifications {
|
||||
static $notifications = null;
|
||||
|
||||
if ( null === $notifications ) {
|
||||
require get_template_directory() . '/vendor/autoload.php';
|
||||
|
||||
$notifications = new ThemeNotifications(
|
||||
'hello-elementor',
|
||||
HELLO_ELEMENTOR_VERSION,
|
||||
'theme'
|
||||
);
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
|
||||
hello_elementor_get_theme_notifications();
|
||||
@@ -0,0 +1,351 @@
|
||||
@charset "UTF-8";
|
||||
/**
|
||||
* Loading first in the style.scss & classic-editor.scss
|
||||
*/
|
||||
/**
|
||||
* Header styling and layout
|
||||
*/
|
||||
.site-header {
|
||||
/* Backwards compat for Hello 2.3.0 */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
padding-block-start: 1rem;
|
||||
padding-block-end: 1rem;
|
||||
position: relative;
|
||||
}
|
||||
.site-header .site-title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.site-header .site-branding {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.site-header .header-inner {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.site-header .header-inner .custom-logo-link {
|
||||
display: block;
|
||||
}
|
||||
.site-header .header-inner .site-branding .site-title,
|
||||
.site-header .header-inner .site-branding .site-description {
|
||||
margin: 0;
|
||||
}
|
||||
.site-header .header-inner .site-branding .site-logo img {
|
||||
display: block;
|
||||
}
|
||||
.site-header .header-inner .site-branding.show-title .site-logo {
|
||||
display: none !important;
|
||||
}
|
||||
.site-header .header-inner .site-branding.show-logo .site-title {
|
||||
display: none !important;
|
||||
}
|
||||
.site-header.header-inverted .header-inner {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.site-header.header-inverted .header-inner .site-branding {
|
||||
text-align: end;
|
||||
}
|
||||
.site-header.header-stacked .header-inner {
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/**
|
||||
* Footer styling and layout
|
||||
*/
|
||||
.site-footer {
|
||||
padding-block-start: 1rem;
|
||||
padding-block-end: 1rem;
|
||||
position: relative;
|
||||
}
|
||||
.site-footer .site-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.site-footer .site-branding {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.site-footer .footer-inner {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.site-footer .footer-inner .custom-logo-link {
|
||||
display: block;
|
||||
}
|
||||
.site-footer .footer-inner .site-branding .site-title,
|
||||
.site-footer .footer-inner .site-branding .site-description {
|
||||
margin: 0;
|
||||
}
|
||||
.site-footer .footer-inner .site-branding .site-logo img {
|
||||
display: block;
|
||||
}
|
||||
.site-footer .footer-inner .site-branding.show-title .site-logo {
|
||||
display: none !important;
|
||||
}
|
||||
.site-footer .footer-inner .site-branding.show-logo .site-title {
|
||||
display: none !important;
|
||||
}
|
||||
.site-footer .footer-inner .copyright {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.site-footer .footer-inner .copyright p {
|
||||
margin: 0;
|
||||
}
|
||||
.site-footer.footer-inverted .footer-inner {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.site-footer.footer-inverted .footer-inner .site-branding {
|
||||
text-align: end;
|
||||
}
|
||||
.site-footer.footer-stacked .footer-inner {
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
.site-footer.footer-stacked .footer-inner .site-branding .site-title {
|
||||
text-align: center;
|
||||
}
|
||||
.site-footer.footer-stacked .footer-inner .site-navigation .menu {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.site-footer:not(.footer-stacked) .footer-inner .site-branding,
|
||||
.site-footer:not(.footer-stacked) .footer-inner .site-navigation,
|
||||
.site-footer:not(.footer-stacked) .footer-inner .copyright {
|
||||
display: block;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.site-footer .footer-inner .site-navigation ul.menu {
|
||||
justify-content: center;
|
||||
}
|
||||
.site-footer .footer-inner .site-navigation ul.menu li {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Navigation Menus
|
||||
*/
|
||||
.site-header.header-stacked .site-navigation-toggle-holder {
|
||||
justify-content: center;
|
||||
max-width: 100%;
|
||||
}
|
||||
.site-header.menu-layout-dropdown .site-navigation {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-navigation-toggle-holder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 15px;
|
||||
}
|
||||
.site-navigation-toggle-holder .site-navigation-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
border: 0 solid;
|
||||
border-radius: 3px;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
color: #494c4f;
|
||||
}
|
||||
.site-navigation-toggle-holder .site-navigation-toggle-icon {
|
||||
display: block;
|
||||
width: 1.25rem;
|
||||
}
|
||||
.site-navigation-toggle-holder .site-navigation-toggle-icon:before, .site-navigation-toggle-holder .site-navigation-toggle-icon:after {
|
||||
content: "";
|
||||
background-color: currentColor;
|
||||
display: block;
|
||||
height: 3px;
|
||||
transition: all 200ms ease-in-out;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.site-navigation-toggle-holder .site-navigation-toggle-icon:before {
|
||||
box-shadow: 0 0.35rem 0 currentColor;
|
||||
margin-block-end: 0.5rem;
|
||||
}
|
||||
.site-navigation-toggle-holder .site-navigation-toggle[aria-expanded=true] .site-navigation-toggle-icon:before {
|
||||
box-shadow: none;
|
||||
transform: translateY(0.35rem) rotate(45deg);
|
||||
}
|
||||
.site-navigation-toggle-holder .site-navigation-toggle[aria-expanded=true] .site-navigation-toggle-icon:after {
|
||||
transform: translateY(-0.35rem) rotate(-45deg);
|
||||
}
|
||||
|
||||
.site-navigation {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.site-navigation ul.menu, .site-navigation ul.menu ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
.site-navigation ul.menu {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.site-navigation ul.menu li {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
.site-navigation ul.menu li a {
|
||||
display: block;
|
||||
padding: 8px 15px;
|
||||
}
|
||||
.site-navigation ul.menu li.menu-item-has-children {
|
||||
padding-inline-end: 15px;
|
||||
}
|
||||
.site-navigation ul.menu li.menu-item-has-children:after {
|
||||
display: flex;
|
||||
content: "▾";
|
||||
font-size: 1.5em;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #666666;
|
||||
text-decoration: none;
|
||||
}
|
||||
.site-navigation ul.menu li.menu-item-has-children:focus-within > ul {
|
||||
display: block;
|
||||
}
|
||||
.site-navigation ul.menu li ul {
|
||||
background: #fff;
|
||||
display: none;
|
||||
min-width: 150px;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
top: 100%;
|
||||
}
|
||||
.site-navigation ul.menu li ul li {
|
||||
border-block-end: #eeeeee 1px solid;
|
||||
}
|
||||
.site-navigation ul.menu li ul li:last-child {
|
||||
border-block-end: none;
|
||||
}
|
||||
.site-navigation ul.menu li ul li.menu-item-has-children a {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.site-navigation ul.menu li ul li.menu-item-has-children:after {
|
||||
transform: translateY(-50%) rotate(-90deg);
|
||||
}
|
||||
.site-navigation ul.menu li ul ul {
|
||||
left: 100%;
|
||||
top: 0;
|
||||
}
|
||||
.site-navigation ul.menu li:hover > ul {
|
||||
display: block;
|
||||
}
|
||||
|
||||
footer .site-navigation ul.menu li ul {
|
||||
top: auto;
|
||||
bottom: 100%;
|
||||
}
|
||||
footer .site-navigation ul.menu li ul ul {
|
||||
bottom: 0;
|
||||
}
|
||||
footer .site-navigation ul.menu a {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.site-navigation-dropdown {
|
||||
margin-block-start: 10px;
|
||||
transition: max-height 0.3s, transform 0.3s;
|
||||
transform-origin: top;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10000;
|
||||
width: 100%;
|
||||
}
|
||||
.site-navigation-toggle-holder:not(.elementor-active) + .site-navigation-dropdown {
|
||||
transform: scaleY(0);
|
||||
max-height: 0;
|
||||
}
|
||||
.site-navigation-toggle-holder.elementor-active + .site-navigation-dropdown {
|
||||
transform: scaleY(1);
|
||||
max-height: 100vh;
|
||||
}
|
||||
.site-navigation-dropdown ul {
|
||||
padding: 0;
|
||||
}
|
||||
.site-navigation-dropdown ul.menu {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: white;
|
||||
}
|
||||
.site-navigation-dropdown ul.menu li {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.site-navigation-dropdown ul.menu li a {
|
||||
display: block;
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
color: #55595c;
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.1019607843);
|
||||
}
|
||||
.site-navigation-dropdown ul.menu li.current-menu-item a {
|
||||
color: white;
|
||||
background: #55595c;
|
||||
}
|
||||
.site-navigation-dropdown ul.menu > li li {
|
||||
transition: max-height 0.3s, transform 0.3s;
|
||||
transform-origin: top;
|
||||
transform: scaleY(0);
|
||||
max-height: 0;
|
||||
}
|
||||
.site-navigation-dropdown ul.menu li.elementor-active > ul > li {
|
||||
transform: scaleY(1);
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.site-header.menu-dropdown-mobile:not(.menu-layout-dropdown) .site-navigation {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.site-header.menu-dropdown-mobile:not(.menu-layout-dropdown) .site-navigation-toggle-holder {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 576px) and (max-width: 767px) {
|
||||
.site-header.menu-dropdown-mobile:not(.menu-layout-dropdown) .site-navigation {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.site-header.menu-dropdown-tablet:not(.menu-layout-dropdown) .site-navigation-toggle-holder {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@media (max-width: 992px) {
|
||||
.site-header.menu-dropdown-tablet:not(.menu-layout-dropdown) .site-navigation {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
.site-header.menu-dropdown-none:not(.menu-layout-dropdown) .site-navigation-toggle-holder {
|
||||
display: none !important;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying the header
|
||||
*
|
||||
* This is the template that displays all of the <head> section, opens the <body> tag and adds the site's header.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
$viewport_content = apply_filters( 'hello_elementor_viewport_content', 'width=device-width, initial-scale=1' );
|
||||
$enable_skip_link = apply_filters( 'hello_elementor_enable_skip_link', true );
|
||||
$skip_link_url = apply_filters( 'hello_elementor_skip_link_url', '#content' );
|
||||
?>
|
||||
<!doctype html>
|
||||
<html <?php language_attributes(); ?>>
|
||||
<head>
|
||||
<meta charset="<?php bloginfo( 'charset' ); ?>">
|
||||
<meta name="viewport" content="<?php echo esc_attr( $viewport_content ); ?>">
|
||||
<link rel="profile" href="https://gmpg.org/xfn/11">
|
||||
<?php wp_head(); ?>
|
||||
</head>
|
||||
<body <?php body_class(); ?>>
|
||||
|
||||
<?php wp_body_open(); ?>
|
||||
|
||||
<?php if ( $enable_skip_link ) { ?>
|
||||
<a class="skip-link screen-reader-text" href="<?php echo esc_url( $skip_link_url ); ?>"><?php echo esc_html__( 'Skip to content', 'hello-elementor' ); ?></a>
|
||||
<?php } ?>
|
||||
|
||||
<?php
|
||||
if ( ! function_exists( 'elementor_theme_do_location' ) || ! elementor_theme_do_location( 'header' ) ) {
|
||||
if ( hello_elementor_display_header_footer() ) {
|
||||
if ( did_action( 'elementor/loaded' ) && hello_header_footer_experiment_active() ) {
|
||||
get_template_part( 'template-parts/dynamic-header' );
|
||||
} else {
|
||||
get_template_part( 'template-parts/header' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Show in WP Dashboard notice about the plugin is not activated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_elementor_fail_load_admin_notice() {
|
||||
// Leave to Elementor Pro to manage this.
|
||||
if ( function_exists( 'elementor_pro_load_plugin' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
if ( isset( $screen->parent_file ) && 'plugins.php' === $screen->parent_file && 'update' === $screen->id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'true' === get_user_meta( get_current_user_id(), '_hello_elementor_install_notice', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugin = 'elementor/elementor.php';
|
||||
|
||||
$installed_plugins = get_plugins();
|
||||
|
||||
$is_elementor_installed = isset( $installed_plugins[ $plugin ] );
|
||||
|
||||
$message = esc_html__( 'The Hello Theme is a lightweight starter theme that works perfectly with the Elementor award-winning site builder plugin.', 'hello-elementor' );
|
||||
|
||||
if ( $is_elementor_installed ) {
|
||||
if ( ! current_user_can( 'activate_plugins' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message .= ' ' . esc_html__( 'Once you activate the plugin, you are only one click away from building an amazing website.', 'hello-elementor' );
|
||||
|
||||
$button_text = esc_html__( 'Activate Elementor', 'hello-elementor' );
|
||||
$button_link = wp_nonce_url( 'plugins.php?action=activate&plugin=' . $plugin . '&plugin_status=all&paged=1&s', 'activate-plugin_' . $plugin );
|
||||
} else {
|
||||
if ( ! current_user_can( 'install_plugins' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message .= ' ' . esc_html__( 'Once you download and activate the plugin, you are only one click away from building an amazing website.', 'hello-elementor' );
|
||||
|
||||
$button_text = esc_html__( 'Install Elementor', 'hello-elementor' );
|
||||
$button_link = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=elementor' ), 'install-plugin_elementor' );
|
||||
}
|
||||
|
||||
?>
|
||||
<style>
|
||||
.notice.hello-elementor-notice {
|
||||
border: 1px solid #ccd0d4;
|
||||
border-inline-start: 4px solid #9b0a46 !important;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.15);
|
||||
display: flex;
|
||||
padding: 0;
|
||||
}
|
||||
.notice.hello-elementor-notice.hello-elementor-install-elementor {
|
||||
padding: 0;
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-notice-aside {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
justify-content: center;
|
||||
padding: 20px 10px;
|
||||
background: rgba(215,43,63,0.04);
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-notice-aside img {
|
||||
width: 1.5rem;
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-notice-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-notice-content h3,
|
||||
.notice.hello-elementor-notice .hello-elementor-notice-content p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-information-link {
|
||||
align-self: start;
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-install-button {
|
||||
align-self: start;
|
||||
background-color: #127DB8;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
padding: 0.4375rem 0.75rem;
|
||||
margin-block-start: 15px;
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-install-button:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.notice.hello-elementor-notice .hello-elementor-notice-aside {
|
||||
padding: 10px;
|
||||
}
|
||||
.notice.hello-elementor-notice .hello-elementor-notice-content {
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.addEventListener( 'load', () => {
|
||||
const dismissNotice = document.querySelector( '.notice.hello-elementor-install-elementor button.notice-dismiss' );
|
||||
dismissNotice.addEventListener( 'click', async ( event ) => {
|
||||
event.preventDefault();
|
||||
|
||||
var formData = new FormData();
|
||||
formData.append( 'action', 'hello_elementor_set_admin_notice_viewed' );
|
||||
formData.append( 'dismiss_nonce', '<?php echo esc_js( wp_create_nonce( 'hello_elementor_dismiss_install_notice' ) ); ?>' );
|
||||
|
||||
await fetch( ajaxurl, { method: 'POST', body: formData } );
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
<div class="notice updated is-dismissible hello-elementor-notice hello-elementor-install-elementor">
|
||||
<div class="hello-elementor-notice-aside">
|
||||
<img src="<?php echo esc_url( get_template_directory_uri() . '/assets/images/elementor-notice-icon.svg' ); ?>" alt="<?php echo esc_attr__( 'Get Elementor', 'hello-elementor' ); ?>" />
|
||||
</div>
|
||||
<div class="hello-elementor-notice-content">
|
||||
<h3><?php echo esc_html__( 'Thanks for installing the Hello Theme!', 'hello-elementor' ); ?></h3>
|
||||
<p><?php echo esc_html( $message ); ?></p>
|
||||
<a class="hello-elementor-information-link" href="https://go.elementor.com/hello-theme-learn/" target="_blank"><?php echo esc_html__( 'Explore Elementor Site Builder Plugin', 'hello-elementor' ); ?></a>
|
||||
<a class="hello-elementor-install-button" href="<?php echo esc_attr( $button_link ); ?>"><?php echo esc_html( $button_text ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dismissed admin notice as viewed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function ajax_hello_elementor_set_admin_notice_viewed() {
|
||||
check_ajax_referer( 'hello_elementor_dismiss_install_notice', 'dismiss_nonce' );
|
||||
|
||||
update_user_meta( get_current_user_id(), '_hello_elementor_install_notice', 'true' );
|
||||
die;
|
||||
}
|
||||
add_action( 'wp_ajax_hello_elementor_set_admin_notice_viewed', 'ajax_hello_elementor_set_admin_notice_viewed' );
|
||||
|
||||
if ( ! did_action( 'elementor/loaded' ) ) {
|
||||
add_action( 'admin_notices', 'hello_elementor_fail_load_admin_notice' );
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Customizer controls for header & footer.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_customizer_register( $wp_customize ) {
|
||||
require_once get_template_directory() . '/includes/customizer/customizer-action-links.php';
|
||||
|
||||
$wp_customize->add_section(
|
||||
'hello-options',
|
||||
[
|
||||
'title' => esc_html__( 'Header & Footer', 'hello-elementor' ),
|
||||
'capability' => 'edit_theme_options',
|
||||
]
|
||||
);
|
||||
|
||||
$wp_customize->add_setting(
|
||||
'hello-header-footer',
|
||||
[
|
||||
'sanitize_callback' => false,
|
||||
'transport' => 'refresh',
|
||||
]
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
new HelloElementor\Includes\Customizer\Hello_Customizer_Action_Links(
|
||||
$wp_customize,
|
||||
'hello-header-footer',
|
||||
[
|
||||
'section' => 'hello-options',
|
||||
'priority' => 20,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
add_action( 'customize_register', 'hello_customizer_register' );
|
||||
|
||||
/**
|
||||
* Register Customizer controls for Elementor Pro upsell.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_customizer_register_elementor_pro_upsell( $wp_customize ) {
|
||||
if ( function_exists( 'elementor_pro_load_plugin' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
require_once get_template_directory() . '/includes/customizer/customizer-upsell.php';
|
||||
|
||||
$wp_customize->add_section(
|
||||
new HelloElementor\Includes\Customizer\Hello_Customizer_Upsell(
|
||||
$wp_customize,
|
||||
'hello-upsell-elementor-pro',
|
||||
[
|
||||
'heading' => esc_html__( 'Customize your entire website with Elementor Pro', 'hello-elementor' ),
|
||||
'description' => esc_html__( 'Build and customize every part of your website, including Theme Parts with Elementor Pro.', 'hello-elementor' ),
|
||||
'button_text' => esc_html__( 'Upgrade Now', 'hello-elementor' ),
|
||||
'button_url' => 'https://elementor.com/pro/?utm_source=hello-theme-customize&utm_campaign=gopro&utm_medium=wp-dash',
|
||||
'priority' => 999999,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
add_action( 'customize_register', 'hello_customizer_register_elementor_pro_upsell' );
|
||||
|
||||
/**
|
||||
* Enqueue Customizer CSS.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function hello_customizer_styles() {
|
||||
|
||||
$min_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
wp_enqueue_style(
|
||||
'hello-elementor-customizer',
|
||||
get_template_directory_uri() . '/customizer' . $min_suffix . '.css',
|
||||
[],
|
||||
HELLO_ELEMENTOR_VERSION
|
||||
);
|
||||
}
|
||||
add_action( 'admin_enqueue_scripts', 'hello_customizer_styles' );
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
namespace HelloElementor\Includes\Customizer;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Hello_Customizer_Action_Links extends \WP_Customize_Control {
|
||||
|
||||
// Whitelist content parameter
|
||||
public $content = '';
|
||||
|
||||
/**
|
||||
* Render the control's content.
|
||||
*
|
||||
* Allows the content to be overridden without having to rewrite the wrapper.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_content() {
|
||||
$this->print_customizer_action_links();
|
||||
|
||||
if ( isset( $this->description ) ) {
|
||||
echo '<span class="description customize-control-description">' . wp_kses_post( $this->description ) . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print customizer action links.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function print_customizer_action_links() {
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$action_link_data = [];
|
||||
$action_link_type = '';
|
||||
$installed_plugins = get_plugins();
|
||||
|
||||
if ( ! isset( $installed_plugins['elementor/elementor.php'] ) ) {
|
||||
$action_link_type = 'install-elementor';
|
||||
} elseif ( ! defined( 'ELEMENTOR_VERSION' ) ) {
|
||||
$action_link_type = 'activate-elementor';
|
||||
} elseif ( ! hello_header_footer_experiment_active() ) {
|
||||
$action_link_type = 'activate-header-footer-experiment';
|
||||
} else {
|
||||
$action_link_type = 'style-header-footer';
|
||||
}
|
||||
|
||||
switch ( $action_link_type ) {
|
||||
case 'install-elementor':
|
||||
$action_link_data = [
|
||||
'image' => get_template_directory_uri() . '/assets/images/elementor.svg',
|
||||
'alt' => esc_attr__( 'Elementor', 'hello-elementor' ),
|
||||
'title' => esc_html__( 'Install Elementor', 'hello-elementor' ),
|
||||
'message' => esc_html__( 'Create cross-site header & footer using Elementor.', 'hello-elementor' ),
|
||||
'button' => esc_html__( 'Install Elementor', 'hello-elementor' ),
|
||||
'link' => wp_nonce_url(
|
||||
add_query_arg(
|
||||
[
|
||||
'action' => 'install-plugin',
|
||||
'plugin' => 'elementor',
|
||||
],
|
||||
admin_url( 'update.php' )
|
||||
),
|
||||
'install-plugin_elementor'
|
||||
),
|
||||
];
|
||||
break;
|
||||
case 'activate-elementor':
|
||||
$action_link_data = [
|
||||
'image' => get_template_directory_uri() . '/assets/images/elementor.svg',
|
||||
'alt' => esc_attr__( 'Elementor', 'hello-elementor' ),
|
||||
'title' => esc_html__( 'Activate Elementor', 'hello-elementor' ),
|
||||
'message' => esc_html__( 'Create cross-site header & footer using Elementor.', 'hello-elementor' ),
|
||||
'button' => esc_html__( 'Activate Elementor', 'hello-elementor' ),
|
||||
'link' => wp_nonce_url( 'plugins.php?action=activate&plugin=elementor/elementor.php', 'activate-plugin_elementor/elementor.php' ),
|
||||
];
|
||||
break;
|
||||
case 'activate-header-footer-experiment':
|
||||
$action_link_data = [
|
||||
'image' => get_template_directory_uri() . '/assets/images/elementor.svg',
|
||||
'alt' => esc_attr__( 'Elementor', 'hello-elementor' ),
|
||||
'title' => esc_html__( 'Style using Elementor', 'hello-elementor' ),
|
||||
'message' => esc_html__( 'Design your cross-site header & footer from Elementor’s "Site Settings" panel.', 'hello-elementor' ),
|
||||
'button' => esc_html__( 'Activate header & footer experiment', 'hello-elementor' ),
|
||||
'link' => wp_nonce_url( 'admin.php?page=elementor#tab-experiments' ),
|
||||
];
|
||||
break;
|
||||
case 'style-header-footer':
|
||||
$action_link_data = [
|
||||
'image' => get_template_directory_uri() . '/assets/images/elementor.svg',
|
||||
'alt' => esc_attr__( 'Elementor', 'hello-elementor' ),
|
||||
'title' => esc_html__( 'Style cross-site header & footer', 'hello-elementor' ),
|
||||
'message' => esc_html__( 'Customize your cross-site header & footer from Elementor’s "Site Settings" panel.', 'hello-elementor' ),
|
||||
'button' => esc_html__( 'Start Designing', 'hello-elementor' ),
|
||||
'link' => wp_nonce_url( 'post.php?post=' . get_option( 'elementor_active_kit' ) . '&action=elementor' ),
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
$customizer_content = $this->get_customizer_action_links_html( $action_link_data );
|
||||
|
||||
echo wp_kses_post( $customizer_content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the customizer action links HTML.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_customizer_action_links_html( $data ) {
|
||||
if (
|
||||
empty( $data )
|
||||
|| ! isset( $data['image'] )
|
||||
|| ! isset( $data['alt'] )
|
||||
|| ! isset( $data['title'] )
|
||||
|| ! isset( $data['message'] )
|
||||
|| ! isset( $data['link'] )
|
||||
|| ! isset( $data['button'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<div class="hello-action-links">
|
||||
<img src="%1$s" alt="%2$s">
|
||||
<p class="hello-action-links-title">%3$s</p>
|
||||
<p class="hello-action-links-message">%4$s</p>
|
||||
<a class="button button-primary" target="_blank" href="%5$s">%6$s</a>
|
||||
</div>',
|
||||
$data['image'],
|
||||
$data['alt'],
|
||||
$data['title'],
|
||||
$data['message'],
|
||||
$data['link'],
|
||||
$data['button'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace HelloElementor\Includes\Customizer;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Hello_Customizer_Upsell extends \WP_Customize_Section {
|
||||
|
||||
public $heading;
|
||||
|
||||
public $description;
|
||||
|
||||
public $button_text;
|
||||
|
||||
public $button_url;
|
||||
|
||||
/**
|
||||
* Render the section, and the controls that have been added to it.
|
||||
*/
|
||||
protected function render() {
|
||||
?>
|
||||
<li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="accordion-section control-section control-section-<?php echo esc_attr( $this->id ); ?> cannot-expand">
|
||||
<h3 class="accordion-section-title"><?php echo esc_html( $this->heading ); ?></h3>
|
||||
<p class="accordion-section-description"><?php echo esc_html( $this->description ); ?></p>
|
||||
<div class="accordion-section-buttons">
|
||||
<a href="<?php echo esc_url( $this->button_url ); ?>" target="_blank"><?php echo esc_html( $this->button_text ); ?></a>
|
||||
</div>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Site Settings Controls.
|
||||
*/
|
||||
|
||||
add_action( 'elementor/init', 'hello_elementor_settings_init' );
|
||||
|
||||
function hello_elementor_settings_init() {
|
||||
if ( ! hello_header_footer_experiment_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
require 'settings/settings-header.php';
|
||||
require 'settings/settings-footer.php';
|
||||
|
||||
add_action( 'elementor/kit/register_tabs', function( \Elementor\Core\Kits\Documents\Kit $kit ) {
|
||||
if ( ! hello_elementor_display_header_footer() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$kit->register_tab( 'hello-settings-header', HelloElementor\Includes\Settings\Settings_Header::class );
|
||||
$kit->register_tab( 'hello-settings-footer', HelloElementor\Includes\Settings\Settings_Footer::class );
|
||||
}, 1, 40 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return a setting.
|
||||
*
|
||||
* Saves 2 lines to get kit, then get setting. Also caches the kit and setting.
|
||||
*
|
||||
* @param string $setting_id
|
||||
* @return string|array same as the Elementor internal function does.
|
||||
*/
|
||||
function hello_elementor_get_setting( $setting_id ) {
|
||||
global $hello_elementor_settings;
|
||||
|
||||
$return = '';
|
||||
|
||||
if ( ! isset( $hello_elementor_settings['kit_settings'] ) ) {
|
||||
$kit = \Elementor\Plugin::$instance->kits_manager->get_active_kit();
|
||||
$hello_elementor_settings['kit_settings'] = $kit->get_settings();
|
||||
}
|
||||
|
||||
if ( isset( $hello_elementor_settings['kit_settings'][ $setting_id ] ) ) {
|
||||
$return = $hello_elementor_settings['kit_settings'][ $setting_id ];
|
||||
}
|
||||
|
||||
return apply_filters( 'hello_elementor_' . $setting_id, $return );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to show/hide elements
|
||||
*
|
||||
* This works with switches, if the setting ID that has been passed is toggled on, we'll return show, otherwise we'll return hide
|
||||
*
|
||||
* @param string $setting_id
|
||||
* @return string|array same as the Elementor internal function does.
|
||||
*/
|
||||
function hello_show_or_hide( $setting_id ) {
|
||||
return ( 'yes' === hello_elementor_get_setting( $setting_id ) ? 'show' : 'hide' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to translate the header layout setting into a class name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function hello_get_header_layout_class() {
|
||||
$layout_classes = [];
|
||||
|
||||
$header_layout = hello_elementor_get_setting( 'hello_header_layout' );
|
||||
if ( 'inverted' === $header_layout ) {
|
||||
$layout_classes[] = 'header-inverted';
|
||||
} elseif ( 'stacked' === $header_layout ) {
|
||||
$layout_classes[] = 'header-stacked';
|
||||
}
|
||||
|
||||
$header_width = hello_elementor_get_setting( 'hello_header_width' );
|
||||
if ( 'full-width' === $header_width ) {
|
||||
$layout_classes[] = 'header-full-width';
|
||||
}
|
||||
|
||||
$header_menu_dropdown = hello_elementor_get_setting( 'hello_header_menu_dropdown' );
|
||||
if ( 'tablet' === $header_menu_dropdown ) {
|
||||
$layout_classes[] = 'menu-dropdown-tablet';
|
||||
} elseif ( 'mobile' === $header_menu_dropdown ) {
|
||||
$layout_classes[] = 'menu-dropdown-mobile';
|
||||
} elseif ( 'none' === $header_menu_dropdown ) {
|
||||
$layout_classes[] = 'menu-dropdown-none';
|
||||
}
|
||||
|
||||
$hello_header_menu_layout = hello_elementor_get_setting( 'hello_header_menu_layout' );
|
||||
if ( 'dropdown' === $hello_header_menu_layout ) {
|
||||
$layout_classes[] = 'menu-layout-dropdown';
|
||||
}
|
||||
|
||||
return implode( ' ', $layout_classes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to translate the footer layout setting into a class name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function hello_get_footer_layout_class() {
|
||||
$footer_layout = hello_elementor_get_setting( 'hello_footer_layout' );
|
||||
|
||||
$layout_classes = [];
|
||||
|
||||
if ( 'inverted' === $footer_layout ) {
|
||||
$layout_classes[] = 'footer-inverted';
|
||||
} elseif ( 'stacked' === $footer_layout ) {
|
||||
$layout_classes[] = 'footer-stacked';
|
||||
}
|
||||
|
||||
$footer_width = hello_elementor_get_setting( 'hello_footer_width' );
|
||||
|
||||
if ( 'full-width' === $footer_width ) {
|
||||
$layout_classes[] = 'footer-full-width';
|
||||
}
|
||||
|
||||
if ( hello_elementor_get_setting( 'hello_footer_copyright_display' ) && '' !== hello_elementor_get_setting( 'hello_footer_copyright_text' ) ) {
|
||||
$layout_classes[] = 'footer-has-copyright';
|
||||
}
|
||||
|
||||
return implode( ' ', $layout_classes );
|
||||
}
|
||||
|
||||
add_action( 'elementor/editor/after_enqueue_scripts', function() {
|
||||
if ( ! hello_header_footer_experiment_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
wp_enqueue_script(
|
||||
'hello-theme-editor',
|
||||
get_template_directory_uri() . '/assets/js/hello-editor' . $suffix . '.js',
|
||||
[ 'jquery', 'elementor-editor' ],
|
||||
HELLO_ELEMENTOR_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'hello-editor',
|
||||
get_template_directory_uri() . '/editor' . $suffix . '.css',
|
||||
[],
|
||||
HELLO_ELEMENTOR_VERSION
|
||||
);
|
||||
} );
|
||||
|
||||
add_action( 'wp_enqueue_scripts', function() {
|
||||
if ( ! hello_elementor_display_header_footer() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! hello_header_footer_experiment_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
wp_enqueue_script(
|
||||
'hello-theme-frontend',
|
||||
get_template_directory_uri() . '/assets/js/hello-frontend' . $suffix . '.js',
|
||||
[],
|
||||
HELLO_ELEMENTOR_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
\Elementor\Plugin::$instance->kits_manager->frontend_before_enqueue_styles();
|
||||
} );
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to decide whether to output the header template.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function hello_get_header_display() {
|
||||
$is_editor = isset( $_GET['elementor-preview'] );
|
||||
|
||||
return (
|
||||
$is_editor
|
||||
|| hello_elementor_get_setting( 'hello_header_logo_display' )
|
||||
|| hello_elementor_get_setting( 'hello_header_tagline_display' )
|
||||
|| hello_elementor_get_setting( 'hello_header_menu_display' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to decide whether to output the footer template.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function hello_get_footer_display() {
|
||||
$is_editor = isset( $_GET['elementor-preview'] );
|
||||
|
||||
return (
|
||||
$is_editor
|
||||
|| hello_elementor_get_setting( 'hello_footer_logo_display' )
|
||||
|| hello_elementor_get_setting( 'hello_footer_tagline_display' )
|
||||
|| hello_elementor_get_setting( 'hello_footer_menu_display' )
|
||||
|| hello_elementor_get_setting( 'hello_footer_copyright_display' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Hello Elementor theme Header & Footer to Experiments.
|
||||
*/
|
||||
add_action( 'elementor/experiments/default-features-registered', function( \Elementor\Core\Experiments\Manager $experiments_manager ) {
|
||||
$experiments_manager->add_feature( [
|
||||
'name' => 'hello-theme-header-footer',
|
||||
'title' => esc_html__( 'Header & Footer', 'hello-elementor' ),
|
||||
'tag' => esc_html__( 'Hello Theme', 'hello-elementor' ),
|
||||
'description' => sprintf(
|
||||
'%1$s <a href="%2$s" target="_blank">%3$s</a>',
|
||||
esc_html__( 'Customize and style the builtin Hello Theme’s cross-site header & footer from the Elementor "Site Settings" panel.', 'hello-elementor' ),
|
||||
'https://go.elementor.com/wp-dash-header-footer',
|
||||
esc_html__( 'Learn More', 'hello-elementor' )
|
||||
),
|
||||
'release_status' => $experiments_manager::RELEASE_STATUS_STABLE,
|
||||
'new_site' => [
|
||||
'minimum_installation_version' => '3.3.0',
|
||||
'default_active' => $experiments_manager::STATE_ACTIVE,
|
||||
],
|
||||
] );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Helper function to check if Header & Footer Experiment is Active/Inactive
|
||||
*/
|
||||
function hello_header_footer_experiment_active() {
|
||||
// If Elementor is not active, return false
|
||||
if ( ! did_action( 'elementor/loaded' ) ) {
|
||||
return false;
|
||||
}
|
||||
// Backwards compat.
|
||||
if ( ! method_exists( \Elementor\Plugin::$instance->experiments, 'is_feature_active' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) ( \Elementor\Plugin::$instance->experiments->is_feature_active( 'hello-theme-header-footer' ) );
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
add_action( 'admin_menu', 'hello_elementor_settings_page' );
|
||||
add_action( 'init', 'hello_elementor_tweak_settings', 0 );
|
||||
|
||||
/**
|
||||
* Register theme settings page.
|
||||
*/
|
||||
function hello_elementor_settings_page() {
|
||||
|
||||
$menu_hook = '';
|
||||
|
||||
$menu_hook = add_theme_page(
|
||||
esc_html__( 'Hello Theme Settings', 'hello-elementor' ),
|
||||
esc_html__( 'Theme Settings', 'hello-elementor' ),
|
||||
'manage_options',
|
||||
'hello-theme-settings',
|
||||
'hello_elementor_settings_page_render'
|
||||
);
|
||||
|
||||
add_action( 'load-' . $menu_hook, function() {
|
||||
add_action( 'admin_enqueue_scripts', 'hello_elementor_settings_page_scripts', 10 );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register settings page scripts.
|
||||
*/
|
||||
function hello_elementor_settings_page_scripts() {
|
||||
|
||||
$dir = get_template_directory() . '/assets/js';
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
$handle = 'hello-admin';
|
||||
$asset_path = "$dir/hello-admin.asset.php";
|
||||
$asset_url = get_template_directory_uri() . '/assets/js';
|
||||
if ( ! file_exists( $asset_path ) ) {
|
||||
throw new \Error( 'You need to run `npm run build` for the "hello-theme" first.' );
|
||||
}
|
||||
$script_asset = require( $asset_path );
|
||||
|
||||
wp_enqueue_script(
|
||||
$handle,
|
||||
"$asset_url/$handle$suffix.js",
|
||||
$script_asset['dependencies'],
|
||||
$script_asset['version']
|
||||
);
|
||||
|
||||
wp_set_script_translations( $handle, 'hello-elementor' );
|
||||
|
||||
wp_enqueue_style(
|
||||
$handle,
|
||||
"$asset_url/$handle$suffix.css",
|
||||
[ 'wp-components' ],
|
||||
$script_asset['version']
|
||||
);
|
||||
|
||||
$plugins = get_plugins();
|
||||
|
||||
if ( ! isset( $plugins['elementor/elementor.php'] ) ) {
|
||||
$action_link_type = 'install-elementor';
|
||||
$action_link_url = wp_nonce_url(
|
||||
add_query_arg(
|
||||
[
|
||||
'action' => 'install-plugin',
|
||||
'plugin' => 'elementor',
|
||||
],
|
||||
admin_url( 'update.php' )
|
||||
),
|
||||
'install-plugin_elementor'
|
||||
);
|
||||
} elseif ( ! defined( 'ELEMENTOR_VERSION' ) ) {
|
||||
$action_link_type = 'activate-elementor';
|
||||
$action_link_url = wp_nonce_url( 'plugins.php?action=activate&plugin=elementor/elementor.php', 'activate-plugin_elementor/elementor.php' );
|
||||
} elseif ( hello_header_footer_experiment_active() && ! hello_header_footer_experiment_active() ) {
|
||||
$action_link_type = 'activate-header-footer-experiment';
|
||||
$action_link_url = wp_nonce_url( 'admin.php?page=elementor#tab-experiments' );
|
||||
} elseif ( hello_header_footer_experiment_active() ) {
|
||||
$action_link_type = 'style-header-footer';
|
||||
$action_link_url = wp_nonce_url( 'post.php?post=' . get_option( 'elementor_active_kit' ) . '&action=elementor' );
|
||||
} else {
|
||||
$action_link_type = '';
|
||||
$action_link_url = '';
|
||||
}
|
||||
|
||||
wp_localize_script(
|
||||
$handle,
|
||||
'helloAdminData',
|
||||
[
|
||||
'actionLinkType' => $action_link_type,
|
||||
'actionLinkURL' => $action_link_url,
|
||||
'templateDirectoryURI' => get_template_directory_uri(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render settings page wrapper element.
|
||||
*/
|
||||
function hello_elementor_settings_page_render() {
|
||||
?>
|
||||
<div id="hello-elementor-settings"></div>
|
||||
<?php
|
||||
|
||||
add_action( 'admin_footer', 'hello_elementor_settings_page_footer' );
|
||||
}
|
||||
|
||||
function hello_elementor_settings_page_footer() {
|
||||
$notifications = hello_elementor_get_theme_notifications()->get_notifications_by_conditions();
|
||||
?>
|
||||
<style>
|
||||
#hello-elementor-notifications-dialog {
|
||||
max-height: 80vh;
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
#hello-elementor-notifications-dialog::backdrop {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
#hello-elementor-notifications-dialog h2 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
#hello-elementor-notifications-dialog h3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
#hello-elementor-notifications-dialog .close-notifications-dialog {
|
||||
position: absolute;
|
||||
inset-block-start: 20px;
|
||||
inset-inline-end: 20px;
|
||||
font-size: 26px;
|
||||
background: none;
|
||||
border: none;
|
||||
aspect-ratio: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener( 'DOMContentLoaded', function() {
|
||||
const closeDialogBtn = document.querySelector( '#hello-elementor-notifications-dialog button.close-notifications-dialog' );
|
||||
const dialog = document.getElementById( 'hello-elementor-notifications-dialog' );
|
||||
|
||||
closeDialogBtn.addEventListener( 'click', function() {
|
||||
dialog.close();
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
<dialog id="hello-elementor-notifications-dialog" aria-labelledby="hello-elementor-notifications-dialog-heading">
|
||||
<button autofocus class="close-notifications-dialog" aria-label="<?php echo esc_attr__( 'Close changelog', 'hello-elementor' ); ?>"> × </button>
|
||||
<h2 id="hello-elementor-notifications-dialog-heading"><?php echo esc_html__( 'Changelog:', 'hello-elementor' ); ?></h2>
|
||||
<?php foreach ( $notifications as $item ) : ?>
|
||||
<h3><?php echo esc_html( $item['title'] ); ?></h3>
|
||||
<p><?php echo wp_kses_post( $item['description'] ); ?></p>
|
||||
<?php endforeach; ?>
|
||||
</dialog>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme tweaks & settings.
|
||||
*/
|
||||
function hello_elementor_tweak_settings() {
|
||||
|
||||
$settings_group = 'hello_elementor_settings';
|
||||
|
||||
$settings = [
|
||||
'DESCRIPTION_META_TAG' => '_description_meta_tag',
|
||||
'SKIP_LINK' => '_skip_link',
|
||||
'HEADER_FOOTER' => '_header_footer',
|
||||
'PAGE_TITLE' => '_page_title',
|
||||
'HELLO_STYLE' => '_hello_style',
|
||||
'HELLO_THEME' => '_hello_theme',
|
||||
];
|
||||
|
||||
hello_elementor_register_settings( $settings_group, $settings );
|
||||
hello_elementor_render_tweaks( $settings_group, $settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register theme settings.
|
||||
*/
|
||||
function hello_elementor_register_settings( $settings_group, $settings ) {
|
||||
|
||||
foreach ( $settings as $setting_key => $setting_value ) {
|
||||
register_setting(
|
||||
$settings_group,
|
||||
$settings_group . $setting_value,
|
||||
[
|
||||
'default' => '',
|
||||
'show_in_rest' => true,
|
||||
'type' => 'string',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a tweek only if the user requested it.
|
||||
*/
|
||||
function hello_elementor_do_tweak( $setting, $tweak_callback ) {
|
||||
|
||||
$option = get_option( $setting );
|
||||
if ( isset( $option ) && ( 'true' === $option ) && is_callable( $tweak_callback ) ) {
|
||||
$tweak_callback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Render theme tweaks.
|
||||
*/
|
||||
function hello_elementor_render_tweaks( $settings_group, $settings ) {
|
||||
|
||||
hello_elementor_do_tweak( $settings_group . $settings['DESCRIPTION_META_TAG'], function() {
|
||||
remove_action( 'wp_head', 'hello_elementor_add_description_meta_tag' );
|
||||
} );
|
||||
|
||||
hello_elementor_do_tweak( $settings_group . $settings['SKIP_LINK'], function() {
|
||||
add_filter( 'hello_elementor_enable_skip_link', '__return_false' );
|
||||
} );
|
||||
|
||||
hello_elementor_do_tweak( $settings_group . $settings['HEADER_FOOTER'], function() {
|
||||
add_filter( 'hello_elementor_header_footer', '__return_false' );
|
||||
} );
|
||||
|
||||
hello_elementor_do_tweak( $settings_group . $settings['PAGE_TITLE'], function() {
|
||||
add_filter( 'hello_elementor_page_title', '__return_false' );
|
||||
} );
|
||||
|
||||
hello_elementor_do_tweak( $settings_group . $settings['HELLO_STYLE'], function() {
|
||||
add_filter( 'hello_elementor_enqueue_style', '__return_false' );
|
||||
} );
|
||||
|
||||
hello_elementor_do_tweak( $settings_group . $settings['HELLO_THEME'], function() {
|
||||
add_filter( 'hello_elementor_enqueue_theme_style', '__return_false' );
|
||||
} );
|
||||
|
||||
}
|
||||
@@ -0,0 +1,756 @@
|
||||
<?php
|
||||
|
||||
namespace HelloElementor\Includes\Settings;
|
||||
|
||||
use Elementor\Controls_Manager;
|
||||
use Elementor\Group_Control_Background;
|
||||
use Elementor\Group_Control_Text_Shadow;
|
||||
use Elementor\Group_Control_Text_Stroke;
|
||||
use Elementor\Group_Control_Typography;
|
||||
use Elementor\Core\Kits\Documents\Tabs\Tab_Base;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Settings_Footer extends Tab_Base {
|
||||
|
||||
public function get_id() {
|
||||
return 'hello-settings-footer';
|
||||
}
|
||||
|
||||
public function get_title() {
|
||||
return esc_html__( 'Hello Theme Footer', 'hello-elementor' );
|
||||
}
|
||||
|
||||
public function get_icon() {
|
||||
return 'eicon-footer';
|
||||
}
|
||||
|
||||
public function get_help_url() {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function get_group() {
|
||||
return 'theme-style';
|
||||
}
|
||||
|
||||
protected function register_tab_controls() {
|
||||
$start = is_rtl() ? 'right' : 'left';
|
||||
$end = ! is_rtl() ? 'right' : 'left';
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_footer_section',
|
||||
[
|
||||
'tab' => 'hello-settings-footer',
|
||||
'label' => esc_html__( 'Footer', 'hello-elementor' ),
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_logo_display',
|
||||
[
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'label' => esc_html__( 'Site Logo', 'hello-elementor' ),
|
||||
'default' => 'yes',
|
||||
'label_on' => esc_html__( 'Show', 'hello-elementor' ),
|
||||
'label_off' => esc_html__( 'Hide', 'hello-elementor' ),
|
||||
'selector' => '.site-footer .site-branding',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_tagline_display',
|
||||
[
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'label' => esc_html__( 'Tagline', 'hello-elementor' ),
|
||||
'default' => 'yes',
|
||||
'label_on' => esc_html__( 'Show', 'hello-elementor' ),
|
||||
'label_off' => esc_html__( 'Hide', 'hello-elementor' ),
|
||||
'selector' => '.site-footer .site-description',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_menu_display',
|
||||
[
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'label' => esc_html__( 'Menu', 'hello-elementor' ),
|
||||
'default' => 'yes',
|
||||
'label_on' => esc_html__( 'Show', 'hello-elementor' ),
|
||||
'label_off' => esc_html__( 'Hide', 'hello-elementor' ),
|
||||
'selector' => '.site-footer .site-navigation',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_copyright_display',
|
||||
[
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'label' => esc_html__( 'Copyright', 'hello-elementor' ),
|
||||
'default' => 'yes',
|
||||
'label_on' => esc_html__( 'Show', 'hello-elementor' ),
|
||||
'label_off' => esc_html__( 'Hide', 'hello-elementor' ),
|
||||
'selector' => '.site-footer .copyright',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_disable_note',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'warning',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens the theme settings page. */
|
||||
__( 'Note: Hiding all the elements, only hides them visually. To disable them completely go to <a href="%s">Theme Settings</a> .', 'hello-elementor' ),
|
||||
admin_url( 'themes.php?page=hello-theme-settings' )
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => '',
|
||||
'hello_footer_tagline_display' => '',
|
||||
'hello_footer_menu_display' => '',
|
||||
'hello_footer_copyright_display' => '',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_layout',
|
||||
[
|
||||
'type' => Controls_Manager::CHOOSE,
|
||||
'label' => esc_html__( 'Layout', 'hello-elementor' ),
|
||||
'options' => [
|
||||
'inverted' => [
|
||||
'title' => esc_html__( 'Inverted', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$start",
|
||||
],
|
||||
'stacked' => [
|
||||
'title' => esc_html__( 'Centered', 'hello-elementor' ),
|
||||
'icon' => 'eicon-h-align-center',
|
||||
],
|
||||
'default' => [
|
||||
'title' => esc_html__( 'Default', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$end",
|
||||
],
|
||||
],
|
||||
'toggle' => false,
|
||||
'selector' => '.site-footer',
|
||||
'default' => 'default',
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_footer_tagline_position',
|
||||
[
|
||||
'type' => Controls_Manager::CHOOSE,
|
||||
'label' => esc_html__( 'Tagline Position', 'hello-elementor' ),
|
||||
'options' => [
|
||||
'before' => [
|
||||
'title' => esc_html__( 'Before', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$start",
|
||||
],
|
||||
'below' => [
|
||||
'title' => esc_html__( 'Below', 'hello-elementor' ),
|
||||
'icon' => 'eicon-arrow-down',
|
||||
],
|
||||
'after' => [
|
||||
'title' => esc_html__( 'After', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$end",
|
||||
],
|
||||
],
|
||||
'toggle' => false,
|
||||
'default' => 'below',
|
||||
'selectors_dictionary' => [
|
||||
'before' => 'flex-direction: row-reverse; align-items: center;',
|
||||
'below' => 'flex-direction: column; align-items: stretch;',
|
||||
'after' => 'flex-direction: row; align-items: center;',
|
||||
],
|
||||
'condition' => [
|
||||
'hello_footer_tagline_display' => 'yes',
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .site-branding' => '{{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_footer_tagline_gap',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Tagline Gap', 'hello-elementor' ),
|
||||
'size_units' => [ 'px', 'em ', 'rem', 'custom' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 10,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 10,
|
||||
],
|
||||
],
|
||||
'condition' => [
|
||||
'hello_footer_tagline_display' => 'yes',
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .site-branding' => 'gap: {{SIZE}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_width',
|
||||
[
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'label' => esc_html__( 'Width', 'hello-elementor' ),
|
||||
'options' => [
|
||||
'boxed' => esc_html__( 'Boxed', 'hello-elementor' ),
|
||||
'full-width' => esc_html__( 'Full Width', 'hello-elementor' ),
|
||||
],
|
||||
'selector' => '.site-footer',
|
||||
'default' => 'boxed',
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_footer_custom_width',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Content Width', 'hello-elementor' ),
|
||||
'size_units' => [ '%', 'px', 'em', 'rem', 'vw', 'custom' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 2000,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'condition' => [
|
||||
'hello_footer_width' => 'boxed',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .footer-inner' => 'width: {{SIZE}}{{UNIT}}; max-width: 100%;',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_footer_gap',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Side Margins', 'hello-elementor' ),
|
||||
'size_units' => [ '%', 'px', 'em ', 'rem', 'vw', 'custom' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 5,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 5,
|
||||
],
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer' => 'padding-inline-end: {{SIZE}}{{UNIT}}; padding-inline-start: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'condition' => [
|
||||
'hello_footer_layout!' => 'stacked',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Background::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_background',
|
||||
'label' => esc_html__( 'Background', 'hello-elementor' ),
|
||||
'types' => [ 'classic', 'gradient' ],
|
||||
'separator' => 'before',
|
||||
'selector' => '.site-footer',
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_footer_logo_section',
|
||||
[
|
||||
'tab' => 'hello-settings-footer',
|
||||
'label' => esc_html__( 'Site Logo', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_logo_display!' => '',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_logo_link',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens Elementor's "Site Identity" panel. */
|
||||
__( 'Go to <a href="%s">Site Identity</a> to manage your site\'s logo', 'hello-elementor' ),
|
||||
"javascript:\$e.route('panel/global/settings-site-identity')"
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'logo',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_title_link',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens Elementor's "Site Identity" panel. */
|
||||
__( 'Go to <a href="%s">Site Identity</a> to manage your site\'s title', 'hello-elementor' ),
|
||||
"javascript:\$e.route('panel/global/settings-site-identity')"
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_logo_type',
|
||||
[
|
||||
'label' => esc_html__( 'Type', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => 'logo',
|
||||
'options' => [
|
||||
'logo' => esc_html__( 'Logo', 'hello-elementor' ),
|
||||
'title' => esc_html__( 'Title', 'hello-elementor' ),
|
||||
],
|
||||
'frontend_available' => true,
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_footer_logo_width',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Logo Width', 'hello-elementor' ),
|
||||
'size_units' => [ '%', 'px', 'em', 'rem', 'vw', 'custom' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 1000,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'logo',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .site-branding .site-logo img' => 'width: {{SIZE}}{{UNIT}}; max-width: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Typography::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_title_typography',
|
||||
'label' => esc_html__( 'Typography', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
'selector' => '.site-footer .site-title',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Shadow::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_title_text_shadow',
|
||||
'label' => esc_html__( 'Text Shadow', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
'selector' => '.site-footer .site-title a',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Stroke::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_title_text_stroke',
|
||||
'label' => esc_html__( 'Text Stroke', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
'selector' => '.site-footer .site-title a',
|
||||
]
|
||||
);
|
||||
|
||||
$this->start_controls_tabs( 'hello_footer_title_colors' );
|
||||
|
||||
$this->start_controls_tab(
|
||||
'hello_footer_title_colors_normal',
|
||||
[
|
||||
'label' => esc_html__( 'Normal', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_title_color',
|
||||
[
|
||||
'label' => esc_html__( 'Text Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .site-title a' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_tab();
|
||||
|
||||
$this->start_controls_tab(
|
||||
'hello_footer_title_colors_hover',
|
||||
[
|
||||
'label' => esc_html__( 'Hover', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_title_hover_color',
|
||||
[
|
||||
'label' => esc_html__( 'Text Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_footer_logo_display' => 'yes',
|
||||
'hello_footer_logo_type' => 'title',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .site-title a:hover' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_title_hover_color_transition_duration',
|
||||
[
|
||||
'label' => esc_html__( 'Transition Duration', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'size_units' => [ 's', 'ms', 'custom' ],
|
||||
'default' => [
|
||||
'unit' => 's',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .site-title a' => 'transition-duration: {{SIZE}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_tab();
|
||||
|
||||
$this->end_controls_tabs();
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_footer_tagline',
|
||||
[
|
||||
'tab' => 'hello-settings-footer',
|
||||
'label' => esc_html__( 'Tagline', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_tagline_display' => 'yes',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_tagline_link',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens Elementor's "Site Identity" panel. */
|
||||
__( 'Go to <a href="%s">Site Identity</a> to manage your site\'s tagline', 'hello-elementor' ),
|
||||
"javascript:\$e.route('panel/global/settings-site-identity')"
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_footer_tagline_display' => 'yes',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_tagline_color',
|
||||
[
|
||||
'label' => esc_html__( 'Text Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_footer_tagline_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .site-description' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Typography::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_tagline_typography',
|
||||
'label' => esc_html__( 'Typography', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_tagline_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-footer .site-description',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Shadow::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_tagline_text_shadow',
|
||||
'label' => esc_html__( 'Text Shadow', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_tagline_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-footer .site-description',
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_footer_menu_tab',
|
||||
[
|
||||
'tab' => 'hello-settings-footer',
|
||||
'label' => esc_html__( 'Menu', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_menu_display' => 'yes',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$available_menus = wp_get_nav_menus();
|
||||
|
||||
$menus = [ '0' => esc_html__( '— Select a Menu —', 'hello-elementor' ) ];
|
||||
foreach ( $available_menus as $available_menu ) {
|
||||
$menus[ $available_menu->term_id ] = $available_menu->name;
|
||||
}
|
||||
|
||||
if ( 1 === count( $menus ) ) {
|
||||
$this->add_control(
|
||||
'hello_footer_menu_notice',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'heading' => esc_html__( 'There are no menus in your site.', 'hello-elementor' ),
|
||||
'content' => sprintf(
|
||||
__( 'Go to <a href="%s" target="_blank">Menus screen</a> to create one.', 'hello-elementor' ),
|
||||
admin_url( 'nav-menus.php?action=edit&menu=0' )
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->add_control(
|
||||
'hello_footer_menu_warning',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
__( 'Go to the <a href="%s" target="_blank">Menus screen</a> to manage your menus. Changes will be reflected in the preview only after the page reloads.', 'hello-elementor' ),
|
||||
admin_url( 'nav-menus.php' )
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_menu',
|
||||
[
|
||||
'label' => esc_html__( 'Menu', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'options' => $menus,
|
||||
'default' => array_keys( $menus )[0],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_menu_color',
|
||||
[
|
||||
'label' => esc_html__( 'Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'selectors' => [
|
||||
'footer .footer-inner .site-navigation a' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Typography::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_menu_typography',
|
||||
'label' => esc_html__( 'Typography', 'hello-elementor' ),
|
||||
'selector' => 'footer .footer-inner .site-navigation a',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Shadow::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_menu_text_shadow',
|
||||
'label' => esc_html__( 'Text Shadow', 'hello-elementor' ),
|
||||
'selector' => 'footer .footer-inner .site-navigation a',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_footer_copyright_section',
|
||||
[
|
||||
'tab' => 'hello-settings-footer',
|
||||
'label' => esc_html__( 'Copyright', 'hello-elementor' ),
|
||||
'conditions' => [
|
||||
'relation' => 'and',
|
||||
'terms' => [
|
||||
[
|
||||
'name' => 'hello_footer_copyright_display',
|
||||
'operator' => '=',
|
||||
'value' => 'yes',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_copyright_text',
|
||||
[
|
||||
'type' => Controls_Manager::TEXTAREA,
|
||||
'label' => esc_html__( 'Text', 'hello-elementor' ),
|
||||
'default' => esc_html__( 'All rights reserved', 'hello-elementor' ),
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_footer_copyright_color',
|
||||
[
|
||||
'label' => esc_html__( 'Text Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_footer_copyright_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-footer .copyright p' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Typography::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_copyright_typography',
|
||||
'label' => esc_html__( 'Typography', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_copyright_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-footer .copyright p',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Shadow::get_type(),
|
||||
[
|
||||
'name' => 'hello_footer_copyright_text_shadow',
|
||||
'label' => esc_html__( 'Text Shadow', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_footer_copyright_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-footer .copyright p',
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
}
|
||||
|
||||
public function on_save( $data ) {
|
||||
// Save chosen footer menu to the WP settings.
|
||||
if ( isset( $data['settings']['hello_footer_menu'] ) ) {
|
||||
$menu_id = $data['settings']['hello_footer_menu'];
|
||||
$locations = get_theme_mod( 'nav_menu_locations' );
|
||||
$locations['menu-2'] = (int) $menu_id;
|
||||
set_theme_mod( 'nav_menu_locations', $locations );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_additional_tab_content() {
|
||||
$content_template = '
|
||||
<div class="hello-elementor elementor-nerd-box">
|
||||
<img src="%1$s" class="elementor-nerd-box-icon" alt="%2$s">
|
||||
<p class="elementor-nerd-box-title">%3$s</p>
|
||||
<p class="elementor-nerd-box-message">%4$s</p>
|
||||
<a class="elementor-nerd-box-link elementor-button" target="_blank" href="%5$s">%6$s</a>
|
||||
</div>';
|
||||
|
||||
if ( ! defined( 'ELEMENTOR_PRO_VERSION' ) ) {
|
||||
return sprintf(
|
||||
$content_template,
|
||||
get_template_directory_uri() . '/assets/images/go-pro.svg',
|
||||
esc_attr__( 'Get Elementor Pro', 'hello-elementor' ),
|
||||
esc_html__( 'Create a custom footer with multiple options', 'hello-elementor' ),
|
||||
esc_html__( 'Upgrade to Elementor Pro and enjoy free design and many more features', 'hello-elementor' ),
|
||||
'https://go.elementor.com/hello-theme-footer/',
|
||||
esc_html__( 'Upgrade', 'hello-elementor' )
|
||||
);
|
||||
} else {
|
||||
return sprintf(
|
||||
$content_template,
|
||||
get_template_directory_uri() . '/assets/images/go-pro.svg',
|
||||
esc_attr__( 'Elementor Pro', 'hello-elementor' ),
|
||||
esc_html__( 'Create a custom footer with the Theme Builder', 'hello-elementor' ),
|
||||
esc_html__( 'With the Theme Builder you can jump directly into each part of your site', 'hello-elementor' ),
|
||||
get_admin_url( null, 'admin.php?page=elementor-app#/site-editor/templates/footer' ),
|
||||
esc_html__( 'Create Footer', 'hello-elementor' )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,789 @@
|
||||
<?php
|
||||
|
||||
namespace HelloElementor\Includes\Settings;
|
||||
|
||||
use Elementor\Plugin;
|
||||
use Elementor\Controls_Manager;
|
||||
use Elementor\Group_Control_Background;
|
||||
use Elementor\Group_Control_Text_Shadow;
|
||||
use Elementor\Group_Control_Text_Stroke;
|
||||
use Elementor\Group_Control_Typography;
|
||||
use Elementor\Core\Kits\Documents\Tabs\Tab_Base;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Settings_Header extends Tab_Base {
|
||||
|
||||
public function get_id() {
|
||||
return 'hello-settings-header';
|
||||
}
|
||||
|
||||
public function get_title() {
|
||||
return esc_html__( 'Hello Theme Header', 'hello-elementor' );
|
||||
}
|
||||
|
||||
public function get_icon() {
|
||||
return 'eicon-header';
|
||||
}
|
||||
|
||||
public function get_help_url() {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function get_group() {
|
||||
return 'theme-style';
|
||||
}
|
||||
|
||||
protected function register_tab_controls() {
|
||||
$start = is_rtl() ? 'right' : 'left';
|
||||
$end = ! is_rtl() ? 'right' : 'left';
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_header_section',
|
||||
[
|
||||
'tab' => 'hello-settings-header',
|
||||
'label' => esc_html__( 'Header', 'hello-elementor' ),
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_logo_display',
|
||||
[
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'label' => esc_html__( 'Site Logo', 'hello-elementor' ),
|
||||
'default' => 'yes',
|
||||
'label_on' => esc_html__( 'Show', 'hello-elementor' ),
|
||||
'label_off' => esc_html__( 'Hide', 'hello-elementor' ),
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_tagline_display',
|
||||
[
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'label' => esc_html__( 'Tagline', 'hello-elementor' ),
|
||||
'default' => 'yes',
|
||||
'label_on' => esc_html__( 'Show', 'hello-elementor' ),
|
||||
'label_off' => esc_html__( 'Hide', 'hello-elementor' ),
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_menu_display',
|
||||
[
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'label' => esc_html__( 'Menu', 'hello-elementor' ),
|
||||
'default' => 'yes',
|
||||
'label_on' => esc_html__( 'Show', 'hello-elementor' ),
|
||||
'label_off' => esc_html__( 'Hide', 'hello-elementor' ),
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_disable_note',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'warning',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens the theme settings page. */
|
||||
__( 'Note: Hiding all the elements, only hides them visually. To disable them completely go to <a href="%s">Theme Settings</a> .', 'hello-elementor' ),
|
||||
admin_url( 'themes.php?page=hello-theme-settings' )
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => '',
|
||||
'hello_header_tagline_display' => '',
|
||||
'hello_header_menu_display' => '',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_layout',
|
||||
[
|
||||
'type' => Controls_Manager::CHOOSE,
|
||||
'label' => esc_html__( 'Layout', 'hello-elementor' ),
|
||||
'options' => [
|
||||
'inverted' => [
|
||||
'title' => esc_html__( 'Inverted', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$start",
|
||||
],
|
||||
'stacked' => [
|
||||
'title' => esc_html__( 'Centered', 'hello-elementor' ),
|
||||
'icon' => 'eicon-h-align-center',
|
||||
],
|
||||
'default' => [
|
||||
'title' => esc_html__( 'Default', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$end",
|
||||
],
|
||||
],
|
||||
'toggle' => false,
|
||||
'selector' => '.site-header',
|
||||
'default' => 'default',
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_header_tagline_position',
|
||||
[
|
||||
'type' => Controls_Manager::CHOOSE,
|
||||
'label' => esc_html__( 'Tagline Position', 'hello-elementor' ),
|
||||
'options' => [
|
||||
'before' => [
|
||||
'title' => esc_html__( 'Before', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$start",
|
||||
],
|
||||
'below' => [
|
||||
'title' => esc_html__( 'Below', 'hello-elementor' ),
|
||||
'icon' => 'eicon-arrow-down',
|
||||
],
|
||||
'after' => [
|
||||
'title' => esc_html__( 'After', 'hello-elementor' ),
|
||||
'icon' => "eicon-arrow-$end",
|
||||
],
|
||||
],
|
||||
'toggle' => false,
|
||||
'default' => 'below',
|
||||
'selectors_dictionary' => [
|
||||
'before' => 'flex-direction: row-reverse; align-items: center;',
|
||||
'below' => 'flex-direction: column; align-items: stretch;',
|
||||
'after' => 'flex-direction: row; align-items: center;',
|
||||
],
|
||||
'condition' => [
|
||||
'hello_header_tagline_display' => 'yes',
|
||||
'hello_header_logo_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-branding' => '{{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_header_tagline_gap',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Tagline Gap', 'hello-elementor' ),
|
||||
'size_units' => [ 'px', 'em ', 'rem', 'custom' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 10,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 10,
|
||||
],
|
||||
],
|
||||
'condition' => [
|
||||
'hello_header_tagline_display' => 'yes',
|
||||
'hello_header_logo_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-branding' => 'gap: {{SIZE}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_width',
|
||||
[
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'label' => esc_html__( 'Width', 'hello-elementor' ),
|
||||
'options' => [
|
||||
'boxed' => esc_html__( 'Boxed', 'hello-elementor' ),
|
||||
'full-width' => esc_html__( 'Full Width', 'hello-elementor' ),
|
||||
],
|
||||
'selector' => '.site-header',
|
||||
'default' => 'boxed',
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_header_custom_width',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Content Width', 'hello-elementor' ),
|
||||
'size_units' => [ '%', 'px', 'em', 'rem', 'vw', 'custom' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 2000,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'condition' => [
|
||||
'hello_header_width' => 'boxed',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .header-inner' => 'width: {{SIZE}}{{UNIT}}; max-width: 100%;',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_header_gap',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Side Margins', 'hello-elementor' ),
|
||||
'size_units' => [ '%', 'px', 'em ', 'rem', 'vw', 'custom' ],
|
||||
'default' => [
|
||||
'size' => '0',
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 5,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 5,
|
||||
],
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header' => 'padding-inline-end: {{SIZE}}{{UNIT}}; padding-inline-start: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'conditions' => [
|
||||
'relation' => 'and',
|
||||
'terms' => [
|
||||
[
|
||||
'name' => 'hello_header_layout',
|
||||
'operator' => '!=',
|
||||
'value' => 'stacked',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Background::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_background',
|
||||
'label' => esc_html__( 'Background', 'hello-elementor' ),
|
||||
'types' => [ 'classic', 'gradient' ],
|
||||
'separator' => 'before',
|
||||
'selector' => '.site-header',
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_header_logo_section',
|
||||
[
|
||||
'tab' => 'hello-settings-header',
|
||||
'label' => esc_html__( 'Site Logo', 'hello-elementor' ),
|
||||
'conditions' => [
|
||||
'relation' => 'and',
|
||||
'terms' => [
|
||||
[
|
||||
'name' => 'hello_header_logo_display',
|
||||
'operator' => '=',
|
||||
'value' => 'yes',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_logo_link',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens Elementor's "Site Identity" panel. */
|
||||
__( 'Go to <a href="%s">Site Identity</a> to manage your site\'s logo', 'hello-elementor' ),
|
||||
"javascript:\$e.route('panel/global/settings-site-identity')"
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'logo',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_title_link',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens Elementor's "Site Identity" panel. */
|
||||
__( 'Go to <a href="%s">Site Identity</a> to manage your site\'s title', 'hello-elementor' ),
|
||||
"javascript:\$e.route('panel/global/settings-site-identity')"
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_logo_type',
|
||||
[
|
||||
'label' => esc_html__( 'Type', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => ( has_custom_logo() ? 'logo' : 'title' ),
|
||||
'options' => [
|
||||
'logo' => esc_html__( 'Logo', 'hello-elementor' ),
|
||||
'title' => esc_html__( 'Title', 'hello-elementor' ),
|
||||
],
|
||||
'frontend_available' => true,
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_responsive_control(
|
||||
'hello_header_logo_width',
|
||||
[
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'label' => esc_html__( 'Logo Width', 'hello-elementor' ),
|
||||
'size_units' => [ '%', 'px', 'em', 'rem', 'vw', 'custom' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 1000,
|
||||
],
|
||||
'em' => [
|
||||
'max' => 100,
|
||||
],
|
||||
'rem' => [
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'logo',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-branding .site-logo img' => 'width: {{SIZE}}{{UNIT}}; max-width: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Typography::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_title_typography',
|
||||
'label' => esc_html__( 'Typography', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
'selector' => '.site-header .site-title',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Shadow::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_title_text_shadow',
|
||||
'label' => esc_html__( 'Text Shadow', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
'selector' => '.site-header .site-title a',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Stroke::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_title_text_stroke',
|
||||
'label' => esc_html__( 'Text Stroke', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
'selector' => '.site-header .site-title a',
|
||||
]
|
||||
);
|
||||
|
||||
$this->start_controls_tabs( 'hello_header_title_colors' );
|
||||
|
||||
$this->start_controls_tab(
|
||||
'hello_header_title_colors_normal',
|
||||
[
|
||||
'label' => esc_html__( 'Normal', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_title_color',
|
||||
[
|
||||
'label' => esc_html__( 'Text Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-title a' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_tab();
|
||||
|
||||
$this->start_controls_tab(
|
||||
'hello_header_title_colors_hover',
|
||||
[
|
||||
'label' => esc_html__( 'Hover', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_title_hover_color',
|
||||
[
|
||||
'label' => esc_html__( 'Text Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_header_logo_display' => 'yes',
|
||||
'hello_header_logo_type' => 'title',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-title a:hover' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_title_hover_color_transition_duration',
|
||||
[
|
||||
'label' => esc_html__( 'Transition Duration', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'size_units' => [ 's', 'ms', 'custom' ],
|
||||
'default' => [
|
||||
'unit' => 's',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-title a' => 'transition-duration: {{SIZE}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_tab();
|
||||
|
||||
$this->end_controls_tabs();
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_header_tagline',
|
||||
[
|
||||
'tab' => 'hello-settings-header',
|
||||
'label' => esc_html__( 'Tagline', 'hello-elementor' ),
|
||||
'conditions' => [
|
||||
'relation' => 'and',
|
||||
'terms' => [
|
||||
[
|
||||
'name' => 'hello_header_tagline_display',
|
||||
'operator' => '=',
|
||||
'value' => 'yes',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_tagline_link',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
/* translators: %s: Link that opens Elementor's "Site Identity" panel. */
|
||||
__( 'Go to <a href="%s">Site Identity</a> to manage your site\'s tagline', 'hello-elementor' ),
|
||||
"javascript:\$e.route('panel/global/settings-site-identity')"
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'hello_header_tagline_display' => 'yes',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_tagline_color',
|
||||
[
|
||||
'label' => esc_html__( 'Text Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_header_tagline_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-description' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Typography::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_tagline_typography',
|
||||
'label' => esc_html__( 'Typography', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_tagline_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-header .site-description',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Shadow::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_tagline_text_shadow',
|
||||
'label' => esc_html__( 'Text Shadow', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_tagline_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-header .site-description',
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
$this->start_controls_section(
|
||||
'hello_header_menu_tab',
|
||||
[
|
||||
'tab' => 'hello-settings-header',
|
||||
'label' => esc_html__( 'Menu', 'hello-elementor' ),
|
||||
'conditions' => [
|
||||
'relation' => 'and',
|
||||
'terms' => [
|
||||
[
|
||||
'name' => 'hello_header_menu_display',
|
||||
'operator' => '=',
|
||||
'value' => 'yes',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$available_menus = wp_get_nav_menus();
|
||||
|
||||
$menus = [ '0' => esc_html__( '— Select a Menu —', 'hello-elementor' ) ];
|
||||
foreach ( $available_menus as $available_menu ) {
|
||||
$menus[ $available_menu->term_id ] = $available_menu->name;
|
||||
}
|
||||
|
||||
if ( 1 === count( $menus ) ) {
|
||||
$this->add_control(
|
||||
'hello_header_menu_notice',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'heading' => esc_html__( 'There are no menus in your site.', 'hello-elementor' ),
|
||||
'content' => sprintf(
|
||||
__( 'Go to <a href="%s" target="_blank">Menus screen</a> to create one.', 'hello-elementor' ),
|
||||
admin_url( 'nav-menus.php?action=edit&menu=0' )
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->add_control(
|
||||
'hello_header_menu_warning',
|
||||
[
|
||||
'type' => Controls_Manager::ALERT,
|
||||
'alert_type' => 'info',
|
||||
'content' => sprintf(
|
||||
__( 'Go to the <a href="%s" target="_blank">Menus screen</a> to manage your menus. Changes will be reflected in the preview only after the page reloads.', 'hello-elementor' ),
|
||||
admin_url( 'nav-menus.php' )
|
||||
),
|
||||
'render_type' => 'ui',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_menu',
|
||||
[
|
||||
'label' => esc_html__( 'Menu', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'options' => $menus,
|
||||
'default' => array_keys( $menus )[0],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_menu_layout',
|
||||
[
|
||||
'label' => esc_html__( 'Menu Layout', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => 'horizontal',
|
||||
'options' => [
|
||||
'horizontal' => esc_html__( 'Horizontal', 'hello-elementor' ),
|
||||
'dropdown' => esc_html__( 'Dropdown', 'hello-elementor' ),
|
||||
],
|
||||
'frontend_available' => true,
|
||||
]
|
||||
);
|
||||
|
||||
$dropdown_options = [];
|
||||
$active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
|
||||
$selected_breakpoints = [ 'mobile', 'tablet' ];
|
||||
|
||||
foreach ( $active_breakpoints as $breakpoint_key => $breakpoint_instance ) {
|
||||
if ( ! in_array( $breakpoint_key, $selected_breakpoints, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dropdown_options[ $breakpoint_key ] = sprintf(
|
||||
/* translators: 1: Breakpoint label, 2: Breakpoint value. */
|
||||
esc_html__( '%1$s (> %2$dpx)', 'hello-elementor' ),
|
||||
$breakpoint_instance->get_label(),
|
||||
$breakpoint_instance->get_value()
|
||||
);
|
||||
}
|
||||
|
||||
$dropdown_options['none'] = esc_html__( 'None', 'hello-elementor' );
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_menu_dropdown',
|
||||
[
|
||||
'label' => esc_html__( 'Breakpoint', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => 'tablet',
|
||||
'options' => $dropdown_options,
|
||||
'selector' => '.site-header',
|
||||
'condition' => [
|
||||
'hello_header_menu_layout!' => 'dropdown',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_menu_color',
|
||||
[
|
||||
'label' => esc_html__( 'Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_header_menu_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-navigation ul.menu li a' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_menu_toggle_color',
|
||||
[
|
||||
'label' => esc_html__( 'Toggle Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_header_menu_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-navigation-toggle .site-navigation-toggle-icon' => 'color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'hello_header_menu_toggle_background_color',
|
||||
[
|
||||
'label' => esc_html__( 'Toggle Background Color', 'hello-elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'condition' => [
|
||||
'hello_header_menu_display' => 'yes',
|
||||
],
|
||||
'selectors' => [
|
||||
'.site-header .site-navigation-toggle' => 'background-color: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Typography::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_menu_typography',
|
||||
'label' => esc_html__( 'Typography', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_menu_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-header .site-navigation .menu li',
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_group_control(
|
||||
Group_Control_Text_Shadow::get_type(),
|
||||
[
|
||||
'name' => 'hello_header_menu_text_shadow',
|
||||
'label' => esc_html__( 'Text Shadow', 'hello-elementor' ),
|
||||
'condition' => [
|
||||
'hello_header_menu_display' => 'yes',
|
||||
],
|
||||
'selector' => '.site-header .site-navigation .menu li',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$this->end_controls_section();
|
||||
}
|
||||
|
||||
public function on_save( $data ) {
|
||||
// Save chosen header menu to the WP settings.
|
||||
if ( isset( $data['settings']['hello_header_menu'] ) ) {
|
||||
$menu_id = $data['settings']['hello_header_menu'];
|
||||
$locations = get_theme_mod( 'nav_menu_locations' );
|
||||
$locations['menu-1'] = (int) $menu_id;
|
||||
set_theme_mod( 'nav_menu_locations', $locations );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_additional_tab_content() {
|
||||
$content_template = '
|
||||
<div class="hello-elementor elementor-nerd-box">
|
||||
<img src="%1$s" class="elementor-nerd-box-icon" alt="%2$s">
|
||||
<p class="elementor-nerd-box-title">%3$s</p>
|
||||
<p class="elementor-nerd-box-message">%4$s</p>
|
||||
<a class="elementor-nerd-box-link elementor-button" target="_blank" href="%5$s">%6$s</a>
|
||||
</div>';
|
||||
|
||||
if ( ! defined( 'ELEMENTOR_PRO_VERSION' ) ) {
|
||||
return sprintf(
|
||||
$content_template,
|
||||
get_template_directory_uri() . '/assets/images/go-pro.svg',
|
||||
esc_attr__( 'Get Elementor Pro', 'hello-elementor' ),
|
||||
esc_html__( 'Create a custom header with multiple options', 'hello-elementor' ),
|
||||
esc_html__( 'Upgrade to Elementor Pro and enjoy free design and many more features', 'hello-elementor' ),
|
||||
'https://go.elementor.com/hello-theme-header/',
|
||||
esc_html__( 'Upgrade', 'hello-elementor' )
|
||||
);
|
||||
} else {
|
||||
return sprintf(
|
||||
$content_template,
|
||||
get_template_directory_uri() . '/assets/images/go-pro.svg',
|
||||
esc_attr__( 'Elementor Pro', 'hello-elementor' ),
|
||||
esc_html__( 'Create a custom header with the Theme Builder', 'hello-elementor' ),
|
||||
esc_html__( 'With the Theme Builder you can jump directly into each part of your site', 'hello-elementor' ),
|
||||
get_admin_url( null, 'admin.php?page=elementor-app#/site-editor/templates/header' ),
|
||||
esc_html__( 'Create Header', 'hello-elementor' )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* The site's entry point.
|
||||
*
|
||||
* Loads the relevant template part,
|
||||
* the loop is executed (when needed) by the relevant template part.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
get_header();
|
||||
|
||||
$is_elementor_theme_exist = function_exists( 'elementor_theme_do_location' );
|
||||
|
||||
if ( is_singular() ) {
|
||||
if ( ! $is_elementor_theme_exist || ! elementor_theme_do_location( 'single' ) ) {
|
||||
get_template_part( 'template-parts/single' );
|
||||
}
|
||||
} elseif ( is_archive() || is_home() ) {
|
||||
if ( ! $is_elementor_theme_exist || ! elementor_theme_do_location( 'archive' ) ) {
|
||||
get_template_part( 'template-parts/archive' );
|
||||
}
|
||||
} elseif ( is_search() ) {
|
||||
if ( ! $is_elementor_theme_exist || ! elementor_theme_do_location( 'archive' ) ) {
|
||||
get_template_part( 'template-parts/search' );
|
||||
}
|
||||
} else {
|
||||
if ( ! $is_elementor_theme_exist || ! elementor_theme_do_location( 'single' ) ) {
|
||||
get_template_part( 'template-parts/404' );
|
||||
}
|
||||
}
|
||||
|
||||
get_footer();
|
||||
@@ -0,0 +1,304 @@
|
||||
=== Hello Elementor ===
|
||||
|
||||
Contributors: elemntor, KingYes, ariel.k, bainternet
|
||||
Requires at least: 6.0
|
||||
Tested up to: 6.7
|
||||
Stable tag: 3.3.0
|
||||
Version: 3.3.0
|
||||
Requires PHP: 7.4
|
||||
License: GNU General Public License v3 or later
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
A lightweight and minimalist WordPress theme for Elementor site builder.
|
||||
|
||||
== Description ==
|
||||
|
||||
Hello Elementor is a lightweight and minimalist WordPress theme that was built specifically to work seamlessly with the Elementor site builder plugin. The theme is free, open-source, and designed for users who want a flexible, easy-to-use, and customizable website.
|
||||
|
||||
The theme's main focus is on providing a solid foundation for users to build their own unique designs using the Elementor drag-and-drop site builder. It is optimized for speed and performance, and its simplicity and flexibility make it a great choice for both beginners and experienced website designers.
|
||||
|
||||
The theme supports common WordPress features which can be extended using a child-theme. In addition, there are several ways to add custom styles. It can be done from **Elementor**, using a child-theme, or with an external plugin. To customize the theme further, visit [Elementor developers docs](https://developers.elementor.com/docs/hello-elementor-theme/).
|
||||
|
||||
== Copyright ==
|
||||
|
||||
This theme, like WordPress, is distributed under the terms of GPL.
|
||||
Use it as your springboard to building a site with ***Elementor***.
|
||||
|
||||
Hello Elementor bundles the following third-party resources:
|
||||
|
||||
Font Awesome icons for theme screenshot
|
||||
License: SIL Open Font License, version 1.1.
|
||||
Source: https://fontawesome.com/v4.7.0/
|
||||
|
||||
Image for theme screenshot, Copyright Jason Blackeye
|
||||
License: CC0 1.0 Universal (CC0 1.0)
|
||||
Source: https://stocksnap.io/photo/4B83RD7BV9
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 3.3.0 - 2025-01-21 =
|
||||
* Tweak: Added changelog link in theme settings
|
||||
* Tweak: Updated minimum required Safari version to 15.5
|
||||
* Tweak: Update autoprefixer to latest versions
|
||||
|
||||
= 3.2.1 - 2024-12-16 =
|
||||
* Fix: Gutenberg editor expanded disproportionately after adding support for `theme.json` ([#430](https://github.com/elementor/hello-theme/issues/430))
|
||||
* Fix: Use CSS logical properties in the theme
|
||||
* Fix: Add ARIA attributes to header nav menu
|
||||
|
||||
= 3.2.0 - 2024-12-15 =
|
||||
* Tweak: Convert classic to hybrid theme with block-editor support
|
||||
* Tweak: Added new design options to header/footer
|
||||
* Tweak: Update `Tested up to 6.7`
|
||||
* Fix: Minify JS files ([#419](https://github.com/elementor/hello-theme/issues/419))
|
||||
|
||||
= 3.1.1 - 2024-07-30 =
|
||||
* Fix: Use consistent `<h2>` for comments title and comment form
|
||||
|
||||
= 3.1.0 - 2024-06-19 =
|
||||
* Tweak: Update `Requires PHP 7.4`
|
||||
* Tweak: Update `Tested up to 6.5`
|
||||
* Tweak: Add the ability to style the brand layout
|
||||
* Tweak: Remove deprecated Elementor code
|
||||
* Tweak: Restore default focus styling inside the theme
|
||||
* Tweak: Add `aria-label` attribute to various `<nav>` elements
|
||||
* Tweak: Improve mobile menu keyboard accessibility
|
||||
* Tweak: Semantic mobile menu toggle button
|
||||
* Fix: The header renders redundant `<p>` when tagline is empty
|
||||
* Fix: Single post renders redundant wrapping `<div>` when it has no tags
|
||||
* Fix: Remove redundant wrapping `<div>` from `wp_nav_menu()` output
|
||||
* Fix: Wrap page `<h1>` with `<div>`, not `<header>`
|
||||
* Fix: Use consistent `<h3>` for comments title and comment form
|
||||
* Fix: Remove heading tags from dynamic header/footer
|
||||
* Fix: Mobile Menu hamburger is not visible for logged-out users in some cases ([#369](https://github.com/elementor/hello-theme/issues/369))
|
||||
* Fix: Remove duplicate ID attributes in the header mobile menu
|
||||
* Fix: Remove redundant table styles ([#311](https://github.com/elementor/hello-theme/issues/311))
|
||||
* Fix: Remove redundant space bellow Site Logo in the header/footer
|
||||
* Fix: Remove redundant CSS from dynamic header/footer layout
|
||||
* Fix: Separate post tags in single post ([#304](https://github.com/elementor/hello-theme/issues/304))
|
||||
* Fix: Display `the_tags()` after `wp_link_pages()`
|
||||
* Fix: Remove page break navigation from archives when using `<!--nextpage-->`
|
||||
* Fix: Style posts pagination component layout
|
||||
* Fix: Add RTL support to pagination arrows in archive pages
|
||||
* Fix: Update pagination prev/next labels and positions ([#404](https://github.com/elementor/hello-theme/issues/404))
|
||||
* Fix: Check if Elementor is loaded when using dynamic header & footer
|
||||
|
||||
= 3.0.2 - 2024-05-28 =
|
||||
* Internal: Version bump release to refresh WordPress repository
|
||||
|
||||
= 3.0.1 - 2024-01-24 =
|
||||
* Fix: Harden security for admin notice dismiss button
|
||||
* Fix: Add `alt` attribute to all the images in the dashboard
|
||||
|
||||
= 3.0.0 - 2023-12-26 =
|
||||
* New: Option to disable cross-site header & footer
|
||||
* Tweak: Update `Requires PHP 7.3`
|
||||
* Tweak: Update `Tested up to 6.4`
|
||||
* Tweak: Move cross-site header & footer styles to a separate CSS file
|
||||
* Tweak: Don't load `header-footer.min.css` when disabling header & footer
|
||||
* Tweak: Don't load `hello-frontend.min.js` when disabling header & footer
|
||||
* Tweak: Replace jQuery code with vanilla JS in the frontend
|
||||
* Tweak: Replace jQuery code with vanilla JS in WordPress admin
|
||||
* Tweak: Remove unused JS code from the frontend
|
||||
* Tweak: Remove unused CSS code from the editor
|
||||
* Tweak: Remove unnecessary `role` attributes from HTML landmark elements
|
||||
* Tweak: Link from Elementor Site Settings to Hello Theme Settings
|
||||
* Fix: Dynamic script version for better caching
|
||||
|
||||
= 2.9.0 - 2023-10-25 =
|
||||
* New: Introducing the new settings page for the theme
|
||||
* New: Option to disable description meta tag
|
||||
* New: Option to disable skip link
|
||||
* New: Option to disable page title
|
||||
* New: Option to unregister Hello style.css
|
||||
* New: Option to unregister Hello theme.css
|
||||
* Tweak: Update `Requires at least 6.0`
|
||||
* Tweak: Update `Tested up to 6.3`
|
||||
|
||||
= 2.8.1 - 2023-07-05 =
|
||||
* Tweak: Added additional CSS selectors to apply RTL on comments
|
||||
* Fix: Comment area style regression
|
||||
|
||||
= 2.8.0 - 2023-07-04 =
|
||||
* Tweak: Update `Requires PHP 7.0`
|
||||
* Tweak: Added description meta tag with excerpt text
|
||||
* Tweak: Use CSS logical properties rather than physical properties
|
||||
* Tweak: Replace legacy `page-break-*` CSS properties with `break-*` properties
|
||||
* Tweak: Remove duplicate CSS classes for screen readers
|
||||
* Tweak: Merge similar translation strings (i18n)
|
||||
|
||||
= 2.7.1 - 2023-03-27 =
|
||||
* Tweak: Add excerpt support for pages
|
||||
* Tweak: When post comments are closed, display it to the user
|
||||
* Fix: Empty "Skip to content" href ([#276](https://github.com/elementor/hello-theme/issues/276))
|
||||
* Fix: Child themes using `hello_elementor_body_open()` no longer working ([#278](https://github.com/elementor/hello-theme/issues/278))
|
||||
|
||||
= 2.7.0 - 2023-03-26 =
|
||||
* Tweak: Update `Requires at least 5.9`
|
||||
* Tweak: Update `Tested up to 6.2`
|
||||
* Tweak: Remove backwards compatibility support for `wp_body_open()`
|
||||
* Tweak: Match `search.php` markup to `archive.php` markup
|
||||
* Tweak: Check if posts have featured images set
|
||||
* Tweak: Remove unnecessary `role` attributes from HTML landmark elements
|
||||
* Tweak: Escape translation strings for secure HTML output
|
||||
* Tweak: Use i18n function to make the "Menu" string translatable
|
||||
* Tweak: Minify SVG assets
|
||||
* Tweak: Make header nav-menu keyboard accessible
|
||||
* Tweak: Add `role="button"` to the nav-menu toggle for better accessibility
|
||||
* Tweak: Toggle mobile nav-menu with `Enter` & `Space` keyboard keys
|
||||
* Tweak: Add `hello_elementor_enable_skip_link` filter to enable/disable the skip link
|
||||
* Tweak: Add `hello_elementor_skip_link_url` filter to change skip link URL
|
||||
* Tweak: Use theme CSS not Elementor plugins CSS
|
||||
* Tweak: Added support for the new Elementor version
|
||||
* Tweak: Update autoprefixer to exclude dead browsers
|
||||
* Tweak: Delete deprecated `elementor_hello_theme_load_textdomain` filter hook
|
||||
* Tweak: Delete deprecated `elementor_hello_theme_register_menus` filter hook
|
||||
* Tweak: Delete deprecated `elementor_hello_theme_add_theme_support` filter hook
|
||||
* Tweak: Delete deprecated `elementor_hello_theme_add_woocommerce_support` filter hook
|
||||
* Tweak: Delete deprecated `elementor_hello_theme_enqueue_style` filter hook
|
||||
* Tweak: Delete deprecated `elementor_hello_theme_register_elementor_locations` filter hook
|
||||
* Tweak: Added additional and `custom` units to header & footer panels
|
||||
* Tweak: Link to Elementor "Site Identity" panel from the header & footer panels
|
||||
* Tweak: Delete the `hello_elementor_load_textdomain` filter hook
|
||||
|
||||
= 2.6.1 - 2022-07-11 =
|
||||
* Tweak: Tables looks weird on dark backgrounds ([#126](https://github.com/elementor/hello-theme/issues/126))
|
||||
* Fix: Remove unnecessary PHP tags ([#213](https://github.com/elementor/hello-theme/issues/213))
|
||||
|
||||
= 2.6.0 - 2022-07-10 =
|
||||
* Tweak: Added `theme_support` for `script` and `style` to avoid validation warnings ([#184](https://github.com/elementor/hello-theme/issues/184))
|
||||
* Tweak: Sanitized content for allowed HTML tags in post title ([#118](https://github.com/elementor/hello-theme/issues/118))
|
||||
* Tweak: Changed the containers to `max-width: 1140px` instead of `960px` to align with the header-footer width
|
||||
* Tweak: Centering the page title for better consistency in all cases
|
||||
* Tweak: Added link between the customizer to Elementor global settings
|
||||
* Tweak: Added Skip Links to custom or dynamic header for better accessibility
|
||||
* Fix: Added output escaping in several places ([#194](https://github.com/elementor/hello-theme/issues/194))
|
||||
* Fix: Post Password Form Submit button alignment (Props [@romanbondar](https://github.com/romanbondar))
|
||||
* Fix: Fatal error when kit doesn't exist or needs to be recreated ([#175](https://github.com/elementor/hello-theme/issues/175))
|
||||
|
||||
= 2.5.0 - 2022-01-26 =
|
||||
* Tweak: Added keyboard navigation to Hello Elementor theme menus
|
||||
* Tweak: Added Skip Links and `#content` for the main wrapper for better accessibility ([#133](https://github.com/elementor/hello-theme/issues/133))
|
||||
* Tweak: Added underline for text links in Post Content for better accessibility
|
||||
* Tweak: Removed `outline: none` from inputs for better accessibility
|
||||
* Fix: Footer menu location is not being presented on sites that are not running Elementor
|
||||
|
||||
= 2.4.2 - 2021-12-20 =
|
||||
* Tweak: Use HTTPS in XFN profile link to prevent mixed content error ([Topic](https://wordpress.org/support/topic/url-scheme-in-xfn-profile-link/))
|
||||
* Tweak: Remove comments in `style.min.css` output ([#179](https://github.com/elementor/hello-theme/issues/179))
|
||||
* Tweak: Promoted Hello Elementor theme Header & Footer experiment status to Stable
|
||||
* Tweak: Added compatibility for upcoming WordPress version 5.9
|
||||
|
||||
= 2.4.1 - 2021-07-07 =
|
||||
* Fix: Hello Elementor theme Header & Footer experiment should be inactive for existing sites
|
||||
|
||||
= 2.4.0 - 2021-06-29 =
|
||||
* New: Introducing Header and Footer site elements as an Elementor Experiment
|
||||
* Tweak: Updated Elementor admin notices UI
|
||||
|
||||
= 2.3.1 - 2020-12-28 =
|
||||
* Tweak: Improved UI for table elements
|
||||
* Tweak: Added support for Gutenberg Wide and Full image formats (Props [@ramiy](https://github.com/ramiy))
|
||||
* Tweak: Added font smoothing
|
||||
* Tweak: Update `Tested up to 5.6`
|
||||
* Tweak: Update `Requires PHP 5.6`
|
||||
* Fix: Adjusted font-family in `code`, `pre`, `kbd` and `samp` elements (Props [@75th](https://github.com/75th))
|
||||
|
||||
= 2.3.0 - 2020-04-19 =
|
||||
* Tweak: Removed caption centering by default to allow alignment using Elementor (Props [@cirkut](https://github.com/cirkut))
|
||||
* Tweak: Removed `text-align` property from table elements to avoid alignment issue in RTL websites (Props [@ramiy](https://github.com/ramiy))
|
||||
* Tweak: Added `input[type="url"]` to CSS reset rules ([#109](https://github.com/elementor/hello-theme/issues/109))
|
||||
* Tweak: Update `Tested up to 5.4`
|
||||
|
||||
= 2.2.2 - 2019-12-23 =
|
||||
* Fix: Conflicts with minifier `cssnano` and CSS animations (Props [@CeliaRozalenM](https://github.com/CeliaRozalenM))
|
||||
* Fix: Max-width property is missing in `_archive.scss` (Props [@redpik](https://github.com/redpik))
|
||||
|
||||
= 2.2.1 - 2019-09-10 =
|
||||
* Tweak: Added max width to `wp-caption` ([#91](https://github.com/elementor/hello-theme/issues/91))
|
||||
* Tweak: Added support of `wp_body_open`
|
||||
|
||||
= 2.2.0 - 2019-07-22 =
|
||||
* Tweak: Added viewport content filter ([#49](https://github.com/elementor/hello-theme/issues/49))
|
||||
* Tweak: Added support Hide Title in Elementor
|
||||
* Tweak: Adhere to TRT's Theme Sniffer
|
||||
|
||||
= 2.1.2 - 2019-06-19 =
|
||||
* Tweak: Added theme version to enqueued styles
|
||||
* Tweak: Remove header tags with `hello_elementor_page_title` filter
|
||||
|
||||
= 2.1.1 - 2019-06-13 =
|
||||
* Tweak: Rename `Install Elementor Now` button to `Install Elementor`
|
||||
|
||||
= 2.1.0 - 2019-06-12 =
|
||||
* New: Added basic theme styling
|
||||
* New: Added tagline under the site name in header
|
||||
* New: Added `hello_elementor_page_title` filter for show\hide page title
|
||||
* New: Added `hello_elementor_enqueue_theme_style` filter for enqueue theme-specific style
|
||||
* Tweak: Hide site name & tagline if logo file is exist
|
||||
* Tweak: Hide default page list when there is no primary menu
|
||||
* Tweak: Removed `#main` in `archive.php`, `single.php`, `search.php` & `404.php` files
|
||||
* Tweak: Removed `#site-header` in `header.php` file
|
||||
* Tweak: Replaced `#top-menu` with `.site-navigation`
|
||||
* Tweak: Removed custom SCSS directory, it is recommended to use child theme instead of editing parent theme
|
||||
|
||||
= 2.0.7 - 2019-06-04 =
|
||||
* Tweak: Added nextpage support to `single.php`
|
||||
* Tweak: Keep both original and minified css files
|
||||
* Tweak: Removed `flexible-header`, `custom-colors`, `editor-style` tags
|
||||
|
||||
= 2.0.6 - 2019-05-08 =
|
||||
* Tweak: Removed irrelevant font family from `$font-family-base`
|
||||
* Fix: Minified `style.css` for better optimization
|
||||
|
||||
= 2.0.5 - 2019-05-21 =
|
||||
* New: Introducing [Hello Theme Child](https://github.com/elementor/hello-theme-child)
|
||||
* Tweak: Enqueue only parent theme stylesheet
|
||||
* Tweak: Added admin notice box for recommending Elementor plugin
|
||||
|
||||
= 2.0.4 - 2019-05-20 =
|
||||
* Tweak: Removed `accessibility-ready` tag from `style.css`
|
||||
|
||||
= 2.0.3 - 2019-05-19 =
|
||||
* Tweak: Removed `accessibility-ready` tag
|
||||
|
||||
= 2.0.2 - 2019-05-13 =
|
||||
* Tweak: Added `hello_elementor_content_width` filter, as per WordPress best practice
|
||||
|
||||
= 2.0.1 - 2019-05-12 =
|
||||
* Tweak: Updated theme screenshot (following comment by WP Theme Review team)
|
||||
|
||||
= 2.0.0 - 2019-05-12 =
|
||||
* Tweak: Updated theme screenshot (following comment by WP Theme Review team)
|
||||
* Tweak: Add Copyright & Image and Icon License sections in readme (following comment by WP Theme Review team)
|
||||
* Tweak: Remove duplicated call to `add_theme_support( 'custom-logo')`
|
||||
* Tweak: Readme file grammar & spelling
|
||||
* Tweak: Update `Tested up to 5.2`
|
||||
* Tweak: Change functions.php methods names prefix from `hello_elementor_theme_` to `hello_elementor_`
|
||||
* Tweak: Change hook names to fit theme's name. Old hooks are deprecated, users are urged to update their code where needed
|
||||
* Tweak: Update style for `img`, `textarea`, 'label'
|
||||
|
||||
= 1.2.0 - 2019-02-12 =
|
||||
* New: Added classic-editor.css for Classic editor
|
||||
* Tweak: A lot of changes to match theme review guidelines
|
||||
* Tweak: Updated theme screenshot
|
||||
|
||||
= 1.1.1 - 2019-01-28 =
|
||||
* Tweak: Removed padding reset for lists
|
||||
|
||||
= 1.1.0 - 2018-12-26 =
|
||||
* New: Added SCSS & do thorough style reset
|
||||
* New: Added readme file
|
||||
* New: Added `elementor_hello_theme_load_textdomain` filter for load theme's textdomain
|
||||
* New: Added `elementor_hello_theme_register_menus` filter for register the theme's default menu location
|
||||
* New: Added `elementor_hello_theme_add_theme_support` filter for register the various supported features
|
||||
* New: Added `elementor_hello_theme_add_woocommerce_support` filter for register woocommerce features, including product-gallery zoom, swipe & lightbox features
|
||||
* New: Added `elementor_hello_theme_enqueue_style` filter for enqueue style
|
||||
* New: Added `elementor_hello_theme_register_elementor_locations` filter for register elementor settings
|
||||
* New: Added child-theme preparations
|
||||
* New: Added template part search
|
||||
* New: Added translation support
|
||||
* Tweak: Re-write of already existing template parts
|
||||
|
||||
= 1.0.0 - 2018-03-19 =
|
||||
* Initial Public Release
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying sidebar.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* This file is here to avoid the Deprecated Message for sidebar by wp-includes/theme-compat/sidebar.php.
|
||||
*/
|
||||
@@ -0,0 +1,582 @@
|
||||
/*
|
||||
Theme Name: Hello Elementor
|
||||
Theme URI: https://elementor.com/hello-theme/?utm_source=wp-themes&utm_campaign=theme-uri&utm_medium=wp-dash
|
||||
Description: Hello Elementor is a lightweight and minimalist WordPress theme that was built specifically to work seamlessly with the Elementor site builder plugin. The theme is free, open-source, and designed for users who want a flexible, easy-to-use, and customizable website. The theme, which is optimized for performance, provides a solid foundation for users to build their own unique designs using the Elementor drag-and-drop site builder. Its simplicity and flexibility make it a great choice for both beginners and experienced Web Creators.
|
||||
Author: Elementor Team
|
||||
Author URI: https://elementor.com/?utm_source=wp-themes&utm_campaign=author-uri&utm_medium=wp-dash
|
||||
Version: 3.3.0
|
||||
Stable tag: 3.3.0
|
||||
Requires at least: 6.0
|
||||
Tested up to: 6.7
|
||||
Requires PHP: 7.4
|
||||
License: GNU General Public License v3 or later.
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
Text Domain: hello-elementor
|
||||
Tags: accessibility-ready, flexible-header, custom-colors, custom-menu, custom-logo, featured-images, rtl-language-support, threaded-comments, translation-ready,
|
||||
*/
|
||||
/**
|
||||
* Loading first in the style.scss & classic-editor.scss
|
||||
*/
|
||||
/**
|
||||
* Document basic styling
|
||||
* Inspired by Normalize.css, HTML5 Boilerplate & Bootstrap Reboot Projects under MIT License
|
||||
*/
|
||||
/**
|
||||
* 1. Correct the line height in all browsers.
|
||||
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
* 3. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
|
||||
*/
|
||||
html {
|
||||
line-height: 1.15; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box; /* 3 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
*/
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #333333;
|
||||
background-color: #fff;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-block-start: 0.5rem;
|
||||
margin-block-end: 1rem;
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-block-start: 0;
|
||||
margin-block-end: 0.9rem;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
*/
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
*/
|
||||
a {
|
||||
background-color: transparent;
|
||||
text-decoration: none;
|
||||
color: #CC3366;
|
||||
}
|
||||
a:hover, a:active {
|
||||
color: #333366;
|
||||
}
|
||||
a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:not([href]):not([tabindex]):focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Chrome 57-
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
abbr[title] {
|
||||
border-block-end: none; /* 1 */
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
*/
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10.
|
||||
*/
|
||||
img {
|
||||
border-style: none;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Interactive
|
||||
*/
|
||||
/*
|
||||
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||
*/
|
||||
details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
line-height: 1.4;
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Misc
|
||||
*/
|
||||
/**
|
||||
* Add the correct display in IE 10+.
|
||||
*/
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10.
|
||||
*/
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Print
|
||||
*/
|
||||
@media print {
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
background: transparent !important;
|
||||
color: #000 !important; /* Black prints faster */
|
||||
box-shadow: none !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
a,
|
||||
a:visited {
|
||||
text-decoration: underline;
|
||||
}
|
||||
a[href]:after {
|
||||
content: " (" attr(href) ")";
|
||||
}
|
||||
abbr[title]:after {
|
||||
content: " (" attr(title) ")";
|
||||
}
|
||||
a[href^="#"]:after,
|
||||
a[href^="javascript:"]:after {
|
||||
content: "";
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap !important;
|
||||
}
|
||||
pre,
|
||||
blockquote {
|
||||
-moz-column-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
border: 1px solid #cccccc;
|
||||
}
|
||||
thead {
|
||||
display: table-header-group;
|
||||
}
|
||||
tr,
|
||||
img {
|
||||
-moz-column-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
p,
|
||||
h2,
|
||||
h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2,
|
||||
h3 {
|
||||
-moz-column-break-after: avoid;
|
||||
break-after: avoid;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Form styling
|
||||
*/
|
||||
label {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers.
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 1rem; /* 1 */
|
||||
line-height: 1.5; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
input[type=date],
|
||||
input[type=email],
|
||||
input[type=number],
|
||||
input[type=password],
|
||||
input[type=search],
|
||||
input[type=tel],
|
||||
input[type=url],
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
border: solid 1px #666666;
|
||||
border-radius: 3px;
|
||||
padding: 0.5rem 1rem;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
input[type=text]:focus,
|
||||
input[type=date]:focus,
|
||||
input[type=email]:focus,
|
||||
input[type=number]:focus,
|
||||
input[type=password]:focus,
|
||||
input[type=search]:focus,
|
||||
input[type=tel]:focus,
|
||||
input[type=url]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
border-color: #333333;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
width: auto;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
button,
|
||||
[type=submit],
|
||||
[type=button] {
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
color: #CC3366;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
background-color: transparent;
|
||||
border: 1px solid #CC3366;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 3px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
button:focus:not(:focus-visible),
|
||||
[type=submit]:focus:not(:focus-visible),
|
||||
[type=button]:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
button:hover, button:focus,
|
||||
[type=submit]:hover,
|
||||
[type=submit]:focus,
|
||||
[type=button]:hover,
|
||||
[type=button]:focus {
|
||||
color: #ffffff;
|
||||
background-color: #CC3366;
|
||||
text-decoration: none;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=submit]:not(:disabled),
|
||||
[type=button]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the padding in Firefox.
|
||||
*/
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
legend {
|
||||
box-sizing: border-box; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
display: table; /* 1 */
|
||||
max-width: 100%; /* 1 */
|
||||
padding: 0; /* 3 */
|
||||
white-space: normal; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE 10+.
|
||||
*/
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10.
|
||||
* 2. Remove the padding in IE 10.
|
||||
*/
|
||||
[type=checkbox],
|
||||
[type=radio] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
[type=number]::-webkit-inner-spin-button,
|
||||
[type=number]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
[type=search] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
[type=search]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
select {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Table styling
|
||||
*/
|
||||
table {
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
margin-block-end: 15px;
|
||||
font-size: 0.9em;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table th,
|
||||
table td {
|
||||
padding: 15px;
|
||||
line-height: 1.5;
|
||||
vertical-align: top;
|
||||
border: 1px solid rgba(128, 128, 128, 0.5019607843);
|
||||
}
|
||||
table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
table thead th,
|
||||
table tfoot th {
|
||||
font-size: 1em;
|
||||
}
|
||||
table caption + thead tr:first-child th,
|
||||
table caption + thead tr:first-child td,
|
||||
table colgroup + thead tr:first-child th,
|
||||
table colgroup + thead tr:first-child td,
|
||||
table thead:first-child tr:first-child th,
|
||||
table thead:first-child tr:first-child td {
|
||||
border-block-start: 1px solid rgba(128, 128, 128, 0.5019607843);
|
||||
}
|
||||
table tbody > tr:nth-child(odd) > td,
|
||||
table tbody > tr:nth-child(odd) > th {
|
||||
background-color: rgba(128, 128, 128, 0.0705882353);
|
||||
}
|
||||
table tbody tr:hover > td,
|
||||
table tbody tr:hover > th {
|
||||
background-color: rgba(128, 128, 128, 0.1019607843);
|
||||
}
|
||||
table tbody + tbody {
|
||||
border-block-start: 2px solid rgba(128, 128, 128, 0.5019607843);
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
table table {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
table table th,
|
||||
table table td {
|
||||
padding: 7px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
table table th {
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List styling
|
||||
*/
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li {
|
||||
margin-block-start: 0;
|
||||
margin-block-end: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
background: transparent;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying 404 pages (not found).
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
?>
|
||||
<main id="content" class="site-main">
|
||||
|
||||
<?php if ( apply_filters( 'hello_elementor_page_title', true ) ) : ?>
|
||||
<div class="page-header">
|
||||
<h1 class="entry-title"><?php echo esc_html__( 'The page can’t be found.', 'hello-elementor' ); ?></h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="page-content">
|
||||
<p><?php echo esc_html__( 'It looks like nothing was found at this location.', 'hello-elementor' ); ?></p>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying archive pages.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
?>
|
||||
<main id="content" class="site-main">
|
||||
|
||||
<?php if ( apply_filters( 'hello_elementor_page_title', true ) ) : ?>
|
||||
<div class="page-header">
|
||||
<?php
|
||||
the_archive_title( '<h1 class="entry-title">', '</h1>' );
|
||||
the_archive_description( '<p class="archive-description">', '</p>' );
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="page-content">
|
||||
<?php
|
||||
while ( have_posts() ) {
|
||||
the_post();
|
||||
$post_link = get_permalink();
|
||||
?>
|
||||
<article class="post">
|
||||
<?php
|
||||
printf( '<h2 class="%s"><a href="%s">%s</a></h2>', 'entry-title', esc_url( $post_link ), wp_kses_post( get_the_title() ) );
|
||||
if ( has_post_thumbnail() ) {
|
||||
printf( '<a href="%s">%s</a>', esc_url( $post_link ), get_the_post_thumbnail( $post, 'large' ) );
|
||||
}
|
||||
the_excerpt();
|
||||
?>
|
||||
</article>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
global $wp_query;
|
||||
if ( $wp_query->max_num_pages > 1 ) :
|
||||
$prev_arrow = is_rtl() ? '→' : '←';
|
||||
$next_arrow = is_rtl() ? '←' : '→';
|
||||
?>
|
||||
<nav class="pagination">
|
||||
<div class="nav-previous"><?php
|
||||
/* translators: %s: HTML entity for arrow character. */
|
||||
previous_posts_link( sprintf( esc_html__( '%s Previous', 'hello-elementor' ), sprintf( '<span class="meta-nav">%s</span>', $prev_arrow ) ) );
|
||||
?></div>
|
||||
<div class="nav-next"><?php
|
||||
/* translators: %s: HTML entity for arrow character. */
|
||||
next_posts_link( sprintf( esc_html__( 'Next %s', 'hello-elementor' ), sprintf( '<span class="meta-nav">%s</span>', $next_arrow ) ) );
|
||||
?></div>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
|
||||
</main>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying footer.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
$is_editor = isset( $_GET['elementor-preview'] );
|
||||
$site_name = get_bloginfo( 'name' );
|
||||
$tagline = get_bloginfo( 'description', 'display' );
|
||||
$footer_class = did_action( 'elementor/loaded' ) ? hello_get_footer_layout_class() : '';
|
||||
$footer_nav_menu = wp_nav_menu( [
|
||||
'theme_location' => 'menu-2',
|
||||
'fallback_cb' => false,
|
||||
'container' => false,
|
||||
'echo' => false,
|
||||
] );
|
||||
?>
|
||||
<footer id="site-footer" class="site-footer dynamic-footer <?php echo esc_attr( $footer_class ); ?>">
|
||||
<div class="footer-inner">
|
||||
<div class="site-branding show-<?php echo esc_attr( hello_elementor_get_setting( 'hello_footer_logo_type' ) ); ?>">
|
||||
<?php if ( has_custom_logo() && ( 'title' !== hello_elementor_get_setting( 'hello_footer_logo_type' ) || $is_editor ) ) : ?>
|
||||
<div class="site-logo <?php echo esc_attr( hello_show_or_hide( 'hello_footer_logo_display' ) ); ?>">
|
||||
<?php the_custom_logo(); ?>
|
||||
</div>
|
||||
<?php endif;
|
||||
|
||||
if ( $site_name && ( 'logo' !== hello_elementor_get_setting( 'hello_footer_logo_type' ) ) || $is_editor ) : ?>
|
||||
<div class="site-title <?php echo esc_attr( hello_show_or_hide( 'hello_footer_logo_display' ) ); ?>">
|
||||
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr__( 'Home', 'hello-elementor' ); ?>" rel="home">
|
||||
<?php echo esc_html( $site_name ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif;
|
||||
|
||||
if ( $tagline || $is_editor ) : ?>
|
||||
<p class="site-description <?php echo esc_attr( hello_show_or_hide( 'hello_footer_tagline_display' ) ); ?>">
|
||||
<?php echo esc_html( $tagline ); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $footer_nav_menu ) : ?>
|
||||
<nav class="site-navigation <?php echo esc_attr( hello_show_or_hide( 'hello_footer_menu_display' ) ); ?>" aria-label="<?php echo esc_attr__( 'Footer menu', 'hello-elementor' ); ?>">
|
||||
<?php
|
||||
// PHPCS - escaped by WordPress with "wp_nav_menu"
|
||||
echo $footer_nav_menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( '' !== hello_elementor_get_setting( 'hello_footer_copyright_text' ) || $is_editor ) : ?>
|
||||
<div class="copyright <?php echo esc_attr( hello_show_or_hide( 'hello_footer_copyright_display' ) ); ?>">
|
||||
<p><?php echo wp_kses_post( hello_elementor_get_setting( 'hello_footer_copyright_text' ) ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying header.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
if ( ! hello_get_header_display() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$is_editor = isset( $_GET['elementor-preview'] );
|
||||
$site_name = get_bloginfo( 'name' );
|
||||
$tagline = get_bloginfo( 'description', 'display' );
|
||||
$header_class = did_action( 'elementor/loaded' ) ? hello_get_header_layout_class() : '';
|
||||
$menu_args = [
|
||||
'theme_location' => 'menu-1',
|
||||
'fallback_cb' => false,
|
||||
'container' => false,
|
||||
'echo' => false,
|
||||
];
|
||||
$header_nav_menu = wp_nav_menu( $menu_args );
|
||||
$header_mobile_nav_menu = wp_nav_menu( $menu_args ); // The same menu but separate call to avoid duplicate ID attributes.
|
||||
?>
|
||||
<header id="site-header" class="site-header dynamic-header <?php echo esc_attr( $header_class ); ?>">
|
||||
<div class="header-inner">
|
||||
<div class="site-branding show-<?php echo esc_attr( hello_elementor_get_setting( 'hello_header_logo_type' ) ); ?>">
|
||||
<?php if ( has_custom_logo() && ( 'title' !== hello_elementor_get_setting( 'hello_header_logo_type' ) || $is_editor ) ) : ?>
|
||||
<div class="site-logo <?php echo esc_attr( hello_show_or_hide( 'hello_header_logo_display' ) ); ?>">
|
||||
<?php the_custom_logo(); ?>
|
||||
</div>
|
||||
<?php endif;
|
||||
|
||||
if ( $site_name && ( 'logo' !== hello_elementor_get_setting( 'hello_header_logo_type' ) || $is_editor ) ) : ?>
|
||||
<div class="site-title <?php echo esc_attr( hello_show_or_hide( 'hello_header_logo_display' ) ); ?>">
|
||||
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr__( 'Home', 'hello-elementor' ); ?>" rel="home">
|
||||
<?php echo esc_html( $site_name ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif;
|
||||
|
||||
if ( $tagline && ( hello_elementor_get_setting( 'hello_header_tagline_display' ) || $is_editor ) ) : ?>
|
||||
<p class="site-description <?php echo esc_attr( hello_show_or_hide( 'hello_header_tagline_display' ) ); ?>">
|
||||
<?php echo esc_html( $tagline ); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $header_nav_menu ) : ?>
|
||||
<nav class="site-navigation <?php echo esc_attr( hello_show_or_hide( 'hello_header_menu_display' ) ); ?>" aria-label="<?php echo esc_attr__( 'Main menu', 'hello-elementor' ); ?>">
|
||||
<?php
|
||||
// PHPCS - escaped by WordPress with "wp_nav_menu"
|
||||
echo $header_nav_menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php if ( $header_mobile_nav_menu ) : ?>
|
||||
<div class="site-navigation-toggle-holder <?php echo esc_attr( hello_show_or_hide( 'hello_header_menu_display' ) ); ?>">
|
||||
<button type="button" class="site-navigation-toggle" aria-label="<?php echo esc_attr( 'Menu', 'hello-elementor' ); ?>">
|
||||
<span class="site-navigation-toggle-icon" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<nav class="site-navigation-dropdown <?php echo esc_attr( hello_show_or_hide( 'hello_header_menu_display' ) ); ?>" aria-label="<?php echo esc_attr__( 'Mobile menu', 'hello-elementor' ); ?>" aria-hidden="true" inert>
|
||||
<?php
|
||||
// PHPCS - escaped by WordPress with "wp_nav_menu"
|
||||
echo $header_mobile_nav_menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying footer.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
$footer_nav_menu = wp_nav_menu( [
|
||||
'theme_location' => 'menu-2',
|
||||
'fallback_cb' => false,
|
||||
'container' => false,
|
||||
'echo' => false,
|
||||
] );
|
||||
?>
|
||||
<footer id="site-footer" class="site-footer">
|
||||
<?php if ( $footer_nav_menu ) : ?>
|
||||
<nav class="site-navigation" aria-label="<?php echo esc_attr__( 'Footer menu', 'hello-elementor' ); ?>">
|
||||
<?php
|
||||
// PHPCS - escaped by WordPress with "wp_nav_menu"
|
||||
echo $footer_nav_menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
</footer>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying header.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
$site_name = get_bloginfo( 'name' );
|
||||
$tagline = get_bloginfo( 'description', 'display' );
|
||||
$header_nav_menu = wp_nav_menu( [
|
||||
'theme_location' => 'menu-1',
|
||||
'fallback_cb' => false,
|
||||
'container' => false,
|
||||
'echo' => false,
|
||||
] );
|
||||
?>
|
||||
|
||||
<header id="site-header" class="site-header">
|
||||
|
||||
<div class="site-branding">
|
||||
<?php
|
||||
if ( has_custom_logo() ) {
|
||||
the_custom_logo();
|
||||
} elseif ( $site_name ) {
|
||||
?>
|
||||
<div class="site-title">
|
||||
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr__( 'Home', 'hello-elementor' ); ?>" rel="home">
|
||||
<?php echo esc_html( $site_name ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php if ( $tagline ) : ?>
|
||||
<p class="site-description">
|
||||
<?php echo esc_html( $tagline ); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $header_nav_menu ) : ?>
|
||||
<nav class="site-navigation" aria-label="<?php echo esc_attr__( 'Main menu', 'hello-elementor' ); ?>">
|
||||
<?php
|
||||
// PHPCS - escaped by WordPress with "wp_nav_menu"
|
||||
echo $header_nav_menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying search results.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
?>
|
||||
<main id="content" class="site-main">
|
||||
|
||||
<?php if ( apply_filters( 'hello_elementor_page_title', true ) ) : ?>
|
||||
<div class="page-header">
|
||||
<h1 class="entry-title">
|
||||
<?php echo esc_html__( 'Search results for: ', 'hello-elementor' ); ?>
|
||||
<span><?php echo get_search_query(); ?></span>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="page-content">
|
||||
<?php if ( have_posts() ) : ?>
|
||||
<?php
|
||||
while ( have_posts() ) :
|
||||
the_post();
|
||||
$post_link = get_permalink();
|
||||
?>
|
||||
<article class="post">
|
||||
<?php
|
||||
printf( '<h2 class="%s"><a href="%s">%s</a></h2>', 'entry-title', esc_url( $post_link ), wp_kses_post( get_the_title() ) );
|
||||
if ( has_post_thumbnail() ) {
|
||||
printf( '<a href="%s">%s</a>', esc_url( $post_link ), get_the_post_thumbnail( $post, 'large' ) );
|
||||
}
|
||||
the_excerpt();
|
||||
?>
|
||||
</article>
|
||||
<?php
|
||||
endwhile;
|
||||
?>
|
||||
<?php else : ?>
|
||||
<p><?php echo esc_html__( 'It seems we can\'t find what you\'re looking for.', 'hello-elementor' ); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
global $wp_query;
|
||||
if ( $wp_query->max_num_pages > 1 ) :
|
||||
$prev_arrow = is_rtl() ? '→' : '←';
|
||||
$next_arrow = is_rtl() ? '←' : '→';
|
||||
?>
|
||||
<nav class="pagination">
|
||||
<div class="nav-previous"><?php
|
||||
/* translators: %s: HTML entity for arrow character. */
|
||||
previous_posts_link( sprintf( esc_html__( '%s Previous', 'hello-elementor' ), sprintf( '<span class="meta-nav">%s</span>', $prev_arrow ) ) );
|
||||
?></div>
|
||||
<div class="nav-next"><?php
|
||||
/* translators: %s: HTML entity for arrow character. */
|
||||
next_posts_link( sprintf( esc_html__( 'Next %s', 'hello-elementor' ), sprintf( '<span class="meta-nav">%s</span>', $next_arrow ) ) );
|
||||
?></div>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
|
||||
</main>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* The template for displaying singular post-types: posts, pages and user-defined custom post types.
|
||||
*
|
||||
* @package HelloElementor
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
while ( have_posts() ) :
|
||||
the_post();
|
||||
?>
|
||||
|
||||
<main id="content" <?php post_class( 'site-main' ); ?>>
|
||||
|
||||
<?php if ( apply_filters( 'hello_elementor_page_title', true ) ) : ?>
|
||||
<div class="page-header">
|
||||
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="page-content">
|
||||
<?php the_content(); ?>
|
||||
|
||||
<?php wp_link_pages(); ?>
|
||||
|
||||
<?php if ( has_tag() ) : ?>
|
||||
<div class="post-tags">
|
||||
<?php the_tags( '<span class="tag-links">' . esc_html__( 'Tagged ', 'hello-elementor' ), ', ', '</span>' ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php comments_template(); ?>
|
||||
|
||||
</main>
|
||||
|
||||
<?php
|
||||
endwhile;
|
||||
@@ -0,0 +1,305 @@
|
||||
@charset "UTF-8";
|
||||
/**
|
||||
* Loading first in the style.scss & classic-editor.scss
|
||||
*/
|
||||
/**
|
||||
* General - https://wordpress.org/documentation/article/css/
|
||||
*/
|
||||
.page-content a,
|
||||
.comments-area a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.alignright {
|
||||
float: right;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.alignleft {
|
||||
float: left;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.aligncenter {
|
||||
clear: both;
|
||||
display: block;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.alignwide {
|
||||
margin-inline: -80px;
|
||||
}
|
||||
|
||||
.alignfull {
|
||||
margin-inline: calc(50% - 50vw);
|
||||
max-width: 100vw;
|
||||
width: 100vw;
|
||||
}
|
||||
.alignfull img {
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.wp-caption {
|
||||
margin-block-end: 1.25rem;
|
||||
max-width: 100%;
|
||||
}
|
||||
.wp-caption.alignleft {
|
||||
margin: 5px 20px 20px 0;
|
||||
}
|
||||
.wp-caption.alignright {
|
||||
margin: 5px 0 20px 20px;
|
||||
}
|
||||
.wp-caption img {
|
||||
display: block;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.wp-caption-text {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.gallery-caption {
|
||||
display: block;
|
||||
font-size: 0.8125rem;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.sticky {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.bypostauthor {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.post-password-form p {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.post-password-form [type=submit] {
|
||||
margin-inline-start: 3px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility styles
|
||||
*/
|
||||
.screen-reader-text {
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute !important;
|
||||
width: 1px;
|
||||
word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */
|
||||
}
|
||||
.screen-reader-text:focus {
|
||||
background-color: #eeeeee;
|
||||
clip: auto !important;
|
||||
clip-path: none;
|
||||
color: #333333;
|
||||
display: block;
|
||||
font-size: 1rem;
|
||||
height: auto;
|
||||
left: 5px;
|
||||
line-height: normal;
|
||||
padding: 12px 24px;
|
||||
text-decoration: none;
|
||||
top: 5px;
|
||||
width: auto;
|
||||
z-index: 100000; /* Above WP toolbar. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Post item in archive pages
|
||||
*/
|
||||
.post .entry-title a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.post .wp-post-image {
|
||||
width: 100%;
|
||||
max-height: 500px;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.post .wp-post-image {
|
||||
max-height: 400px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 575px) {
|
||||
.post .wp-post-image {
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comments
|
||||
*/
|
||||
#comments .comment-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
#comments .comment,
|
||||
#comments .pingback {
|
||||
position: relative;
|
||||
}
|
||||
#comments .comment .comment-body,
|
||||
#comments .pingback .comment-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-block-start: 30px;
|
||||
padding-block-end: 30px;
|
||||
padding-inline-start: 60px;
|
||||
padding-inline-end: 0;
|
||||
border-block-end: 1px solid #cccccc;
|
||||
}
|
||||
#comments .comment .avatar,
|
||||
#comments .pingback .avatar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
border-radius: 50%;
|
||||
margin-inline-end: 10px;
|
||||
}
|
||||
html[dir=rtl] #comments .comment .avatar, body.rtl #comments .comment .avatar,
|
||||
html[dir=rtl] #comments .pingback .avatar,
|
||||
body.rtl #comments .pingback .avatar {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#comments .comment-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-block-end: 0.9rem;
|
||||
}
|
||||
#comments .reply,
|
||||
#comments .comment-metadata {
|
||||
font-size: 11px;
|
||||
line-height: 1;
|
||||
}
|
||||
#comments .children {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding-inline-start: 30px;
|
||||
}
|
||||
#comments .children li:last-child {
|
||||
padding-block-end: 0;
|
||||
}
|
||||
#comments ol.comment-list .children:before {
|
||||
display: inline-block;
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
line-height: 100%;
|
||||
content: "↪";
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
left: 0;
|
||||
width: auto;
|
||||
}
|
||||
html[dir=rtl] #comments ol.comment-list .children:before, body.rtl #comments ol.comment-list .children:before {
|
||||
content: "↩";
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#comments .comment-author,
|
||||
#comments .comment-metadata {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
#comments .comment .comment-body {
|
||||
padding: 30px 0;
|
||||
}
|
||||
#comments .children {
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
#comments .comment .avatar {
|
||||
position: inherit;
|
||||
float: left;
|
||||
}
|
||||
html[dir=rtl] #comments .comment .avatar, body.rtl #comments .comment .avatar {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsive layouts
|
||||
*/
|
||||
.site-header .header-inner, .site-header:not(.dynamic-header), .site-footer .footer-inner, .site-footer:not(.dynamic-footer), body:not([class*=elementor-page-]) .site-main, .page-header .entry-title {
|
||||
margin-inline-start: auto;
|
||||
margin-inline-end: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 575px) {
|
||||
.site-header .header-inner, .site-header:not(.dynamic-header), .site-footer .footer-inner, .site-footer:not(.dynamic-footer), body:not([class*=elementor-page-]) .site-main, .page-header .entry-title {
|
||||
padding-inline-start: 10px;
|
||||
padding-inline-end: 10px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.site-header .header-inner, .site-header:not(.dynamic-header), .site-footer .footer-inner, .site-footer:not(.dynamic-footer), body:not([class*=elementor-page-]) .site-main, .page-header .entry-title {
|
||||
max-width: 500px;
|
||||
}
|
||||
.site-header.header-full-width .header-inner {
|
||||
max-width: 100%;
|
||||
}
|
||||
.site-footer.footer-full-width .footer-inner {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.site-header .header-inner, .site-header:not(.dynamic-header), .site-footer .footer-inner, .site-footer:not(.dynamic-footer), body:not([class*=elementor-page-]) .site-main, .page-header .entry-title {
|
||||
max-width: 600px;
|
||||
}
|
||||
.site-header.header-full-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
.site-footer.footer-full-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.site-header .header-inner, .site-header:not(.dynamic-header), .site-footer .footer-inner, .site-footer:not(.dynamic-footer), body:not([class*=elementor-page-]) .site-main, .page-header .entry-title {
|
||||
max-width: 800px;
|
||||
}
|
||||
.site-header.header-full-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
.site-footer.footer-full-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.site-header .header-inner, .site-header:not(.dynamic-header), .site-footer .footer-inner, .site-footer:not(.dynamic-footer), body:not([class*=elementor-page-]) .site-main, .page-header .entry-title {
|
||||
max-width: 1140px;
|
||||
}
|
||||
.site-header.header-full-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
.site-footer.footer-full-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
.site-header + .elementor {
|
||||
min-height: calc(100vh - 320px);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/theme.json",
|
||||
"version": 3,
|
||||
"settings": {
|
||||
"appearanceTools": true,
|
||||
"layout": {
|
||||
"contentSize": "800px",
|
||||
"wideSize": "1200px"
|
||||
},
|
||||
"color": {
|
||||
"custom": true,
|
||||
"link": true
|
||||
},
|
||||
"typography": {
|
||||
"customFontSize": true,
|
||||
"lineHeight": true
|
||||
},
|
||||
"spacing": {
|
||||
"defaultSpacingSizes": false,
|
||||
"margin": true,
|
||||
"padding": true,
|
||||
"units": [ "%", "px", "em", "rem", "vh", "vw" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit05c72fd3cff988f6319ad655da525fd6::getLoader();
|
||||
@@ -0,0 +1,579 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var string|null */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array<string, list<string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* List of PSR-0 prefixes
|
||||
*
|
||||
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||
*
|
||||
* @var array<string, array<string, list<string>>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var string|null */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var array<string, self>
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param string|null $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string> Array of classname => path
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $classMap Class to filename map
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
$paths = (array) $paths;
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
$paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
$paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param list<string>|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param list<string>|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||
*
|
||||
* @return array<string, self>
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
$copiedLocalDir = false;
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
self::$installedByVendor[$vendorDir] = $required;
|
||||
$installed[] = $required;
|
||||
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $required;
|
||||
$copiedLocalDir = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array() && !$copiedLocalDir) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Elementor\\WPNotificationsPackage\\' => array($vendorDir . '/elementor/wp-notifications-package/src'),
|
||||
);
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit05c72fd3cff988f6319ad655da525fd6
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit05c72fd3cff988f6319ad655da525fd6', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit05c72fd3cff988f6319ad655da525fd6', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit05c72fd3cff988f6319ad655da525fd6::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit05c72fd3cff988f6319ad655da525fd6
|
||||
{
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'E' =>
|
||||
array (
|
||||
'Elementor\\WPNotificationsPackage\\' => 33,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Elementor\\WPNotificationsPackage\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/elementor/wp-notifications-package/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit05c72fd3cff988f6319ad655da525fd6::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit05c72fd3cff988f6319ad655da525fd6::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit05c72fd3cff988f6319ad655da525fd6::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "elementor/wp-notifications-package",
|
||||
"version": "1.1.0",
|
||||
"version_normalized": "1.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/elementor/wp-notifications-package.git",
|
||||
"reference": "cd8093bad42df73c738aa530b5be98ab16621822"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/elementor/wp-notifications-package/zipball/cd8093bad42df73c738aa530b5be98ab16621822",
|
||||
"reference": "cd8093bad42df73c738aa530b5be98ab16621822",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^v1.0.0",
|
||||
"squizlabs/php_codesniffer": "^3.10.2",
|
||||
"wp-coding-standards/wpcs": "^3.1.0"
|
||||
},
|
||||
"time": "2025-01-21T13:50:20+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Elementor\\WPNotificationsPackage\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"support": {
|
||||
"source": "https://github.com/elementor/wp-notifications-package/tree/1.1.0"
|
||||
},
|
||||
"install-path": "../elementor/wp-notifications-package"
|
||||
}
|
||||
],
|
||||
"dev": false,
|
||||
"dev-package-names": []
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => 'elementor/hello-theme',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '91562490fc13a2740b322c390ff38991364c454c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => false,
|
||||
),
|
||||
'versions' => array(
|
||||
'elementor/hello-theme' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '91562490fc13a2740b322c390ff38991364c454c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'elementor/wp-notifications-package' => array(
|
||||
'pretty_version' => '1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => 'cd8093bad42df73c738aa530b5be98ab16621822',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../elementor/wp-notifications-package',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
Vendored
+115
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: WP Notifications Package
|
||||
* Description: ...
|
||||
* Plugin URI: https://elementor.com/
|
||||
* Author: Elementor.com
|
||||
* Version: 1.0.0
|
||||
* License: GPL-3
|
||||
* License URI: https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
*
|
||||
* Text Domain: wp-notifications-package
|
||||
*/
|
||||
|
||||
use Elementor\WPNotificationsPackage\V100\Notifications;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Plugin_Example {
|
||||
|
||||
public Notifications $notifications;
|
||||
|
||||
public function __construct() {
|
||||
$this->init();
|
||||
}
|
||||
|
||||
private function init() {
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$this->notifications = new Notifications(
|
||||
'wp-notifications-package',
|
||||
'1.0.0',
|
||||
'wppe'
|
||||
);
|
||||
|
||||
add_action( 'admin_notices', [ $this, 'display_notifications' ] );
|
||||
add_action( 'admin_footer', [ $this, 'display_dialog' ] );
|
||||
}
|
||||
|
||||
public function display_notifications() {
|
||||
$notifications = $this->notifications->get_notifications_by_conditions( true );
|
||||
|
||||
if ( empty( $notifications ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="notice notice-info is-dismissible">
|
||||
<h3><?php esc_html_e( 'What\'s new:', 'wp-notifications-package' ); ?></h3>
|
||||
<ul>
|
||||
<?php foreach ( $notifications as $item ) : ?>
|
||||
<li><a href="<?php echo esc_url( $item['link'] ?? '#' ); ?>" target="_blank"><?php echo esc_html( $item['title'] ); ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
// Example with HTML Dialog modal
|
||||
?>
|
||||
<div class="notice notice-info is-dismissible">
|
||||
<button class="plugin-example-notifications-dialog-open">Open Notification</button>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function display_dialog() {
|
||||
$notifications = $this->notifications->get_notifications_by_conditions( true );
|
||||
|
||||
if ( empty( $notifications ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<style>
|
||||
#plugin-example-notifications-dialog {
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
#plugin-example-notifications-dialog::backdrop {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
</style>
|
||||
<dialog id="plugin-example-notifications-dialog">
|
||||
<h3><?php esc_html_e( 'What\'s new:', 'wp-notifications-package' ); ?></h3>
|
||||
<ul>
|
||||
<?php foreach ( $notifications as $item ) : ?>
|
||||
<li><a href="<?php echo esc_url( $item['link'] ?? '#' ); ?>" target="_blank"><?php echo esc_html( $item['title'] ); ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<button class="close">Close</button>
|
||||
</dialog>
|
||||
|
||||
<script>
|
||||
document.addEventListener( 'DOMContentLoaded', function() {
|
||||
const openDialogBtn = document.querySelector( '.plugin-example-notifications-dialog-open' );
|
||||
const closeDialogBtn = document.querySelector( '#plugin-example-notifications-dialog button.close' );
|
||||
const dialog = document.getElementById( 'plugin-example-notifications-dialog' );
|
||||
|
||||
openDialogBtn.addEventListener( 'click', function() {
|
||||
dialog.showModal();
|
||||
} );
|
||||
|
||||
closeDialogBtn.addEventListener( 'click', function() {
|
||||
dialog.close();
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
new Plugin_Example();
|
||||
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
namespace Elementor\WPNotificationsPackage\V110;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Notifications {
|
||||
|
||||
const PACKAGE_VERSION = '1.1.0';
|
||||
|
||||
private string $app_name;
|
||||
|
||||
private string $app_version;
|
||||
|
||||
private string $short_app_name;
|
||||
|
||||
private string $transient_key;
|
||||
|
||||
private string $api_endpoint = 'https://my.elementor.com/api/v1/notifications';
|
||||
|
||||
public function __construct( string $app_name, string $app_version, string $short_app_name = 'plugin' ) {
|
||||
$this->app_name = sanitize_title( $app_name );
|
||||
$this->app_version = $app_version;
|
||||
$this->short_app_name = $short_app_name;
|
||||
|
||||
$this->transient_key = "_{$this->app_name}_notifications";
|
||||
|
||||
add_action( 'admin_init', [ $this, 'refresh_notifications' ] );
|
||||
add_filter( 'body_class', [ $this, 'add_body_class' ] );
|
||||
}
|
||||
|
||||
public function refresh_notifications(): void {
|
||||
$this->get_notifications();
|
||||
}
|
||||
|
||||
public function add_body_class( array $classes ): array {
|
||||
$classes[] = $this->short_app_name . '-default';
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
public function get_notifications_by_conditions( $force_request = false ) {
|
||||
$notifications = $this->get_notifications( $force_request );
|
||||
|
||||
$filtered_notifications = [];
|
||||
|
||||
foreach ( $notifications as $notification ) {
|
||||
if ( empty( $notification['conditions'] ) ) {
|
||||
$filtered_notifications = $this->add_to_array( $filtered_notifications, $notification );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $this->check_conditions( $notification['conditions'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filtered_notifications = $this->add_to_array( $filtered_notifications, $notification );
|
||||
}
|
||||
|
||||
return $filtered_notifications;
|
||||
}
|
||||
|
||||
private function get_notifications( $force_update = false ): array {
|
||||
$notifications = static::get_transient( $this->transient_key );
|
||||
|
||||
if ( false === $notifications || $force_update ) {
|
||||
$notifications = $this->fetch_data();
|
||||
static::set_transient( $this->transient_key, $notifications );
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
|
||||
private function add_to_array( $filtered_notifications, $notification ) {
|
||||
foreach ( $filtered_notifications as $filtered_notification ) {
|
||||
if ( $filtered_notification['id'] === $notification['id'] ) {
|
||||
return $filtered_notifications;
|
||||
}
|
||||
}
|
||||
|
||||
$filtered_notifications[] = $notification;
|
||||
|
||||
return $filtered_notifications;
|
||||
}
|
||||
|
||||
private function check_conditions( $groups ): bool {
|
||||
foreach ( $groups as $group ) {
|
||||
if ( $this->check_group( $group ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function check_group( $group ) {
|
||||
$is_or_relation = ! empty( $group['relation'] ) && 'OR' === $group['relation'];
|
||||
unset( $group['relation'] );
|
||||
$result = false;
|
||||
|
||||
foreach ( $group as $condition ) {
|
||||
// Reset results for each condition.
|
||||
$result = false;
|
||||
switch ( $condition['type'] ) {
|
||||
case 'wordpress': // phpcs:ignore WordPress.WP.CapitalPDangit
|
||||
// include an unmodified $wp_version
|
||||
include ABSPATH . WPINC . '/version.php';
|
||||
$result = version_compare( $wp_version, $condition['version'], $condition['operator'] );
|
||||
break;
|
||||
case 'multisite':
|
||||
$result = is_multisite() === $condition['multisite'];
|
||||
break;
|
||||
case 'language':
|
||||
$in_array = in_array( get_locale(), $condition['languages'], true );
|
||||
$result = 'in' === $condition['operator'] ? $in_array : ! $in_array;
|
||||
break;
|
||||
case 'plugin':
|
||||
if ( ! function_exists( 'is_plugin_active' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$is_plugin_active = is_plugin_active( $condition['plugin'] );
|
||||
|
||||
if ( empty( $condition['operator'] ) ) {
|
||||
$condition['operator'] = '==';
|
||||
}
|
||||
|
||||
$result = '==' === $condition['operator'] ? $is_plugin_active : ! $is_plugin_active;
|
||||
break;
|
||||
case 'theme':
|
||||
$theme = wp_get_theme();
|
||||
if ( wp_get_theme()->parent() ) {
|
||||
$theme = wp_get_theme()->parent();
|
||||
}
|
||||
|
||||
if ( $theme->get_template() === $condition['theme'] ) {
|
||||
$version = $theme->version;
|
||||
} else {
|
||||
$version = '';
|
||||
}
|
||||
|
||||
$result = version_compare( $version, $condition['version'], $condition['operator'] );
|
||||
break;
|
||||
|
||||
default:
|
||||
$result = apply_filters( "$this->app_name/notifications/condition/{$condition['type']}", $result, $condition );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ( $is_or_relation && $result ) || ( ! $is_or_relation && ! $result ) ) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function fetch_data(): array {
|
||||
$response = wp_remote_get(
|
||||
$this->api_endpoint,
|
||||
[
|
||||
'timeout' => 10,
|
||||
'body' => [
|
||||
'api_version' => self::PACKAGE_VERSION,
|
||||
'app_name' => $this->app_name,
|
||||
'app_version' => $this->app_version,
|
||||
'site_lang' => get_bloginfo( 'language' ),
|
||||
'site_key' => $this->get_site_key(),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = \json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( empty( $data['notifications'] ) || ! is_array( $data['notifications'] ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $data['notifications'];
|
||||
}
|
||||
|
||||
private function get_site_key() {
|
||||
$site_key = get_option( 'elementor_connect_site_key' );
|
||||
|
||||
if ( ! $site_key ) {
|
||||
$site_key = md5( uniqid( wp_generate_password() ) );
|
||||
update_option( 'elementor_connect_site_key', $site_key );
|
||||
}
|
||||
|
||||
return $site_key;
|
||||
}
|
||||
|
||||
private static function get_transient( $cache_key ) {
|
||||
$cache = get_option( $cache_key );
|
||||
|
||||
if ( empty( $cache['timeout'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( time() > $cache['timeout'] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return json_decode( $cache['value'], true );
|
||||
}
|
||||
|
||||
private static function set_transient( $cache_key, $value, $expiration = '+12 hours' ) {
|
||||
$data = [
|
||||
'timeout' => strtotime( $expiration, time() ),
|
||||
'value' => wp_json_encode( $value ),
|
||||
];
|
||||
|
||||
return update_option( $cache_key, $data, false );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user