// _core : CluarCustomData class Cluar { static base() { if (_env.is("dev")) { return "website/public" } else { return "website/build" } } static build(settings) { settings = settings || {} const data = _val.map() /* * * LANGUAGES * */ const dbLanguages = _db.find( 'language', _val.map() .set( 'where', _val.map() .set("active", true) ) ) const languages = _val.list() for (const dbLanguage of dbLanguages) { languages.add( _val.map() .set("code", dbLanguage.getString("code")) .set("locale", dbLanguage.getString("locale")) .set("description", dbLanguage.getString("description")) .set("default", dbLanguage.getBoolean("default")) ) } data.set("languages", languages) /* * * CONFIGURATION * */ const configuration = _val.map() const dbConfigurationWithLanguages = _db.query(` SELECT language.code "language", configuration_parameter.code "code", configuration.value FROM language INNER JOIN configuration ON language.id = configuration.language_id INNER JOIN configuration_parameter ON configuration.parameter_id = configuration_parameter.id WHERE language.active = TRUE AND configuration.active = TRUE AND configuration_parameter.active = TRUE ORDER BY language.code, configuration_parameter.code `) for (const dbParameter of dbConfigurationWithLanguages) { if (!configuration.has(dbParameter.getString("language"))) { configuration.set(dbParameter.getString("language"), _val.map()) } configuration.getValues(dbParameter.getString("language")) .set(dbParameter.getString("code"), dbParameter.getString("value")) } const dbConfigurationWithoutLanguages = _db.query(` SELECT configuration_parameter.code "code", configuration.value FROM configuration INNER JOIN configuration_parameter ON configuration.parameter_id = configuration_parameter.id WHERE (configuration.language_id = 0 OR configuration.language_id IS NULL) AND configuration.active = TRUE AND configuration_parameter.active = TRUE ORDER BY configuration_parameter.code `) for (const dbParameter of dbConfigurationWithoutLanguages) { if (!configuration.has("GENERIC")) { configuration.set("GENERIC", _val.map()) } configuration.getValues("GENERIC") .set(dbParameter.getString("code"), dbParameter.getString("value")) } data.set("configuration", configuration) /* * * DICTIONARY * */ const dbDictionary = _db.query(` SELECT language.code "language", dictionary_entry.code "code", dictionary.value FROM language INNER JOIN dictionary ON dictionary.language_id = language.id INNER JOIN dictionary_entry ON dictionary.entry_id = dictionary_entry.id WHERE language.active = TRUE AND dictionary.active = TRUE AND dictionary_entry.active = TRUE ORDER BY language.code, dictionary_entry.code `) const dictionary = _val.map() for (const dbEntry of dbDictionary) { if (!dictionary.has(dbEntry.getString("language"))) { dictionary.set(dbEntry.getString("language"), _val.map()) } dictionary.getValues(dbEntry.getString("language")) .set(dbEntry.getString("code"), dbEntry.getString("value")) } data.set("dictionary", dictionary) /* * * PAGES * */ const dbPages = _db.query(` SELECT page.id, language.code "language", page.parent_id, page.link, page.title, page.description, page.keywords, page.menu, page.menu_title, page.sorter FROM language INNER JOIN page ON language.id = page.language_id INNER JOIN page_status ON page.status_id = page_status.id WHERE language.active = TRUE AND page.active = TRUE AND page_status.active = TRUE AND page_status.code = 'published' ORDER BY language.code, page.sorter, page.link `) const pages = _val.map() for (const dbPage of dbPages) { if (!pages.has(dbPage.getString("language"))) { pages.set(dbPage.getString("language"), _val.list()) } const structure = _val.list() /* * * CONTENTS * */ const dbContents = _db.query(` SELECT content.id, content_type.code "type", content.title, content.content, content.image, content.image_alt, content.image_title, content.image_max_width, content.sorter FROM content INNER JOIN content_type ON content.type_id = content_type.id WHERE content.active = TRUE AND content_type.active = TRUE AND content.page_id = ${dbPage.getInt("id")} `) for (const dbContent of dbContents) { structure.add( _val.map() .set("section", "content") .set("type", dbContent.getString("type")) .set("title", dbContent.getString("title")) .set("content", dbContent.getString("content")) .set("image", dbContent.getString("image")) .set("image_alt", dbContent.getString("image_alt")) .set("image_title", dbContent.getString("image_title")) .set("image_max_width", dbContent.getString("image_max_width")) .set("sorter", dbContent.getInt("sorter")) .set("actions", Cluar.actions("content", dbContent.getInt("id"))) ) if (settings.images === true) { Cluar.publishImage("content", dbContent.getString("image")) } } /* * * BANNERS * */ const dbBanners = _db.query(` SELECT banner.id, banner_type.code "type", banner.title, banner.content, banner.image, banner.image_alt, banner.image_title, banner.sorter, banner.position_x, banner.position_y FROM banner INNER JOIN banner_type ON banner.type_id = banner_type.id WHERE banner.active = TRUE AND banner_type.active = TRUE AND banner.page_id = ${dbPage.getInt("id")} `) for (const dbBanner of dbBanners) { structure.add( _val.map() .set("section", "banner") .set("type", dbBanner.getString("type")) .set("title", dbBanner.getString("title")) .set("content", dbBanner.getString("content")) .set("image", dbBanner.getString("image")) .set("image_alt", dbBanner.getString("image_alt")) .set("image_title", dbBanner.getString("image_title")) .set("sorter", dbBanner.getInt("sorter")) .set( "position", _val.map() .set("x", dbBanner.getString("position_x")) .set("y", dbBanner.getString("position_y")) ) .set("actions", Cluar.actions("banner", dbBanner.getInt("id"))) ) if (settings.images === true) { Cluar.publishImage("banner", dbBanner.getString("image")) } } /* * * LISTING * */ const dbListings = _db.query(` SELECT listing.id, listing_type.code "type", listing.title, listing.image_alt, listing.image_title, listing.content, listing.image, listing.sorter FROM listing INNER JOIN listing_type ON listing.type_id = listing_type.id WHERE listing.active = TRUE AND listing_type.active = TRUE AND listing.page_id = ${dbPage.getInt("id")} `) for (const dbListing of dbListings) { const items = _val.list() const dbItems = _db.query(` SELECT title, content, image, image_alt, image_title, sorter, link FROM listing_item WHERE listing_id = ${dbListing.getInt("id")} `) for (const dbItem of dbItems) { items.add( _val.map() .set("section", "listing_item") .set("title", dbItem.getString("title")) .set("content", dbItem.getString("content")) .set("image", dbItem.getString("image")) .set("image_alt", dbItem.getString("image_alt")) .set("image_title", dbItem.getString("image_title")) .set("sorter", dbItem.getInt("sorter")) .set("link", dbItem.getString("link")) ) if (settings.images === true) { Cluar.publishImage("listing_item", dbItem.getString("image")) } } structure.add( _val.map() .set("section", "listing") .set("type", dbListing.getString("type")) .set("title", dbListing.getString("title")) .set("content", dbListing.getString("content")) .set("image", dbListing.getString("image")) .set("image_alt", dbListing.getString("image_alt")) .set("image_title", dbListing.getString("image_title")) .set("items", items) .set("sorter", dbListing.getInt("sorter")) ) if (settings.images === true) { Cluar.publishImage("listing", dbListing.getString("image")) } } /* * * FUNCTIONALITY * */ const dbFunctionalities = _db.query(` SELECT functionality.id, functionality_type.code "type", functionality.title, functionality.content, functionality.image, functionality.sorter FROM functionality INNER JOIN functionality_type ON functionality.type_id = functionality_type.id WHERE functionality.active = TRUE AND functionality_type.active = TRUE AND functionality.page_id = ${dbPage.getInt("id")} `) for (const dbFunctionality of dbFunctionalities) { structure.add( _val.map() .set("section", "functionality") .set("type", dbFunctionality.getString("type")) .set("title", dbFunctionality.getString("title")) .set("content", dbFunctionality.getString("content")) .set("image", dbFunctionality.getString("image")) .set("sorter", dbFunctionality.getInt("sorter")) ) if (settings.images === true) { Cluar.publishImage("functionality", dbFunctionality.getString("image")) } } structure.sort((a, b) => a.getInt("sorter") - b.getInt("sorter")) /* * * ADD PAGE * */ let parentLink = "" if (dbPage.getInt("parent_id") > 0) { const dbParentPage = _db.findFirst( "page", _val.map() .set("where", _val.map().set("id", dbPage.getInt("parent_id"))) ) parentLink = dbParentPage.getString("link") } pages.getValues(dbPage.getString("language")) .add( _val.map() .set("parent", parentLink) .set("link", dbPage.getString("link")) .set("title", dbPage.getString("title")) .set("description", dbPage.getString("description")) .set("keywords", dbPage.getString("keywords")) .set("menu", dbPage.getBoolean("menu")) .set("menu_title", dbPage.getString("menu_title")) .set("sorter", dbPage.getInt("sorter")) .set("structure", structure) ) } data.set("pages", pages) CluarCustomData(data) /* * * DATA FILE * */ const file = _app.file(`${Cluar.base()}/cluarData.js`) file.output().print(`window.cluarData = ${data.toJSON(4)};`) if (_app.settings.getBoolean("uglifyjs") == true) { const osUglifyJS = _os.init() osUglifyJS.directory(_app.folder(Cluar.base())) const osUglifyJSResult = osUglifyJS.command(`uglifyjs -o cluarData.js -- cluarData.js`) if (osUglifyJSResult.output() != '' && osUglifyJSResult.error() != '') { _log.error(`UglifyJS failed:\n\tOutput: ${osUglifyJSResult.output()}\n\tError: ${osUglifyJSResult.error()}`) } } /* * * SITEMAP & ROBOTS * */ const origin = _app.settings.getValues("website").getString("origin") const xml = _xml.create() const document = xml.builder().newDocument() const tagURLSet = document.createElement("urlset") const attrNS = document.createAttribute("xmlns") attrNS.setValue("http://www.sitemaps.org/schemas/sitemap/0.9") tagURLSet.setAttributeNode(attrNS) const attrNews = document.createAttribute("xmlns:news") attrNews.setValue("http://www.google.com/schemas/sitemap-news/0.9") tagURLSet.setAttributeNode(attrNews) const attrXHTML = document.createAttribute("xmlns:xhtml") attrXHTML.setValue("http://www.w3.org/1999/xhtml") tagURLSet.setAttributeNode(attrXHTML) const attrMobile = document.createAttribute("xmlns:mobile") attrMobile.setValue("http://www.sitemaps.org/schemas/sitemap/0.9") tagURLSet.setAttributeNode(attrMobile) const attrImage = document.createAttribute("xmlns:image") attrImage.setValue("http://www.google.com/schemas/sitemap-image/1.1") tagURLSet.setAttributeNode(attrImage) const attrVideo = document.createAttribute("xmlns:video") attrVideo.setValue("http://www.google.com/schemas/sitemap-video/1.1") tagURLSet.setAttributeNode(attrVideo) for (const language of languages) { if (pages.getValues(language.getString("code")) == null) { continue } for (const page of pages.getValues(language.getString("code"))) { const tagURL = document.createElement("url") const tagLoc = document.createElement("loc") tagLoc.appendChild(document.createTextNode(origin +"/"+ language.getString("locale") + page.getString("link"))) tagURL.appendChild(tagLoc) const tagChangeFreq = document.createElement("changefreq") tagChangeFreq.appendChild(document.createTextNode("daily")) tagURL.appendChild(tagChangeFreq) let priority = "0.5" if (page.getString("link") == '/') { priority = "1.0" } else if (page.getString("parent") == '') { priority = "0.7" } const tagPriority = document.createElement("priority") tagPriority.appendChild(document.createTextNode(priority)) tagURL.appendChild(tagPriority) tagURLSet.appendChild(tagURL) } } document.appendChild(tagURLSet) xml.save(document, _app.file(`${Cluar.base()}/sitemap.xml`)) if (!_app.file(`${Cluar.base()}/robots.txt`).exists()) { const output = _app.file(`${Cluar.base()}/robots.txt`).output() .println('User-agent: *') .println('Allow: /') .println(`Sitemap: ${origin}/sitemap.xml`) .close() } } static publishImage(section, fileName) { if (fileName == "") { return; } const folder = _app.folder(`${Cluar.base()}/images/${section}`) if (!folder.exists()) { folder.mkdir() } _storage.database(section, "image", fileName) .file() .copy(`${folder.path()}/${fileName}`, true) } static actionDataItemProcessWithAnImage() { const section = _dataItem.getTable() const folder = _app.folder(`${Cluar.base()}/images/${section}`) if (!folder.exists()) { folder.mkdir() } if (_dataItem.getValues().has("image:old")) { _app.file(`${folder.path()}/${_dataItem.getValues().getString("image:old")}`).delete() } if (_dataItem.getValues().has("image:new")) { _storage.database(section, "image", _dataItem.getValues().getString("image:new")) .file() .copy(`${folder.path()}/${_dataItem.getValues().getString("image:new")}`) } } static actions(section, id) { const dbActions = _db.query(` SELECT action.title, action.content, action.indication, action.link FROM action INNER JOIN ${section}_action ON ${section}_action.action_id = action.id WHERE action.active = true AND ${section}_action.active = TRUE AND ${section}_action.${section}_id = ${id} ORDER BY ${section}_action.sorter `) const actions = _val.list() for (const dbAction of dbActions) { actions.add( _val.map() .set("title", dbAction.getString("title")) .set("content", dbAction.getString("content")) .set("indication", dbAction.getString("indication")) .set("link", dbAction.getString("link")) .set("sorter", dbAction.getInt("sorter")) ) } return actions } }