/* <% scripts(patterns); %> Where patterns may contain *, ** and !pattern for exclusion */ PUBLIC void scripts(cchar *patterns) { HttpStream *stream; HttpRx *rx; HttpRoute *route; EspRoute *eroute; MprList *files; MprJson *cscripts, *script; cchar *uri, *path, *version; int next, ci; stream = getStream(); rx = stream->rx; route = rx->route; eroute = route->eroute; patterns = httpExpandRouteVars(route, patterns); if (!patterns || !*patterns) { version = espGetConfig(route, "version", "1.0.0"); if (eroute->combineScript) { scripts(eroute->combineScript); } else if (espGetConfig(route, "http.content.combine[@=js]", 0)) { if (espGetConfig(route, "http.content.minify[@=js]", 0)) { eroute->combineScript = sfmt("all-%s.min.js", version); } else { eroute->combineScript = sfmt("all-%s.js", version); } scripts(eroute->combineScript); } else { if ((cscripts = mprGetJsonObj(route->config, "client.scripts")) != 0) { for (ITERATE_JSON(cscripts, script, ci)) { scripts(script->value); } } } return; }
/* Load the config.json */ PUBLIC int espLoadConfig(HttpRoute *route) { EspRoute *eroute; MprJson *msettings; MprPath cinfo; cchar *cpath, *value; eroute = route->eroute; cpath = mprJoinPath(route->documents, "config.json"); if (mprGetPathInfo(cpath, &cinfo) == 0) { if (eroute->config && cinfo.mtime > eroute->configLoaded) { eroute->config = 0; } eroute->configLoaded = cinfo.mtime; } if (!eroute->config) { if ((eroute->config = mprLoadJson(cpath)) != 0) { /* Blend the mode properties into settings */ eroute->mode = mprGetJsonValue(eroute->config, "mode", 0); if ((msettings = mprGetJson(eroute->config, sfmt("modes.%s", eroute->mode), 0)) != 0) { mprBlendJson(mprLookupJson(eroute->config, "settings"), msettings, 0); } if ((value = espGetConfig(route, "settings.showErrors", 0)) != 0) { httpSetRouteShowErrors(route, smatch(value, "true")); } if ((value = espGetConfig(route, "settings.update", 0)) != 0) { eroute->update = smatch(value, "true"); } if ((value = espGetConfig(route, "settings.keepSource", 0)) != 0) { eroute->keepSource = smatch(value, "true"); } if ((eroute->serverPrefix = espGetConfig(route, "settings.serverPrefix", 0)) == 0) { eroute->serverPrefix = sclone(BIT_ESP_SERVER_PREFIX); } if ((value = espGetConfig(route, "settings.login.name", 0)) != 0) { /* Automatic login as this user. Password not required */ httpSetAuthUsername(route->auth, value); } if ((value = espGetConfig(route, "settings.xsrfToken", 0)) != 0) { httpSetRouteXsrf(route, smatch(value, "true")); } if ((value = espGetConfig(route, "settings.sendJson", 0)) != 0) { eroute->json = smatch(value, "true"); } if (espTestConfig(route, "settings.map", "compressed")) { httpAddRouteMapping(route, "js,css,less", "min.${1}.gz, min.${1}, ${1}.gz"); httpAddRouteMapping(route, "html,xml", "${1}.gz"); } if (!eroute->database) { if ((eroute->database = espGetConfig(route, "server.database", 0)) != 0) { if (espOpenDatabase(route, eroute->database) < 0) { mprError("Cannot open database %s", eroute->database); return MPR_ERR_CANT_OPEN; } } } eroute->json = espTestConfig(route, "settings.json", "1"); } else { eroute->config = mprCreateJson(MPR_JSON_OBJ); espAddComponent(route, "legacy-mvc"); } if (espHasComponent(route, "legacy-mvc")) { eroute->legacy = 1; } } return 0; }
/* <% stylesheets(patterns); %> Where patterns may contain *, ** and !pattern for exclusion */ PUBLIC void stylesheets(cchar *patterns) { HttpStream *stream; HttpRx *rx; HttpRoute *route; EspRoute *eroute; MprList *files; cchar *filename, *ext, *uri, *path, *kind, *version, *clientDir; int next; stream = getStream(); rx = stream->rx; route = rx->route; eroute = route->eroute; patterns = httpExpandRouteVars(route, patterns); clientDir = httpGetDir(route, "documents"); if (!patterns || !*patterns) { version = espGetConfig(route, "version", "1.0.0"); if (eroute->combineSheet) { /* Previously computed combined stylesheet filename */ stylesheets(eroute->combineSheet); } else if (espGetConfig(route, "http.content.combine[@=css]", 0)) { if (espGetConfig(route, "http.content.minify[@=css]", 0)) { eroute->combineSheet = sfmt("css/all-%s.min.css", version); } else { eroute->combineSheet = sfmt("css/all-%s.css", version); } stylesheets(eroute->combineSheet); } else { /* Not combining into a single stylesheet, so give priority to all.less over all.css if present Load a pure CSS incase some styles need to be applied before the lesssheet is parsed */ ext = espGetConfig(route, "http.content.stylesheets", "css"); filename = mprJoinPathExt("css/all", ext); path = mprJoinPath(clientDir, filename); if (mprPathExists(path, R_OK)) { stylesheets(filename); } else if (!smatch(ext, "less")) { path = mprJoinPath(clientDir, "css/all.less"); if (mprPathExists(path, R_OK)) { stylesheets("css/all.less"); } } } } else { if (sends(patterns, "all.less")) { path = mprJoinPath(clientDir, "css/fix.css"); if (mprPathExists(path, R_OK)) { stylesheets("css/fix.css"); } } if ((files = mprGlobPathFiles(clientDir, patterns, MPR_PATH_RELATIVE)) == 0 || mprGetListLength(files) == 0) { files = mprCreateList(0, 0); mprAddItem(files, patterns); } for (ITERATE_ITEMS(files, path, next)) { path = sjoin("~/", strim(path, ".gz", MPR_TRIM_END), NULL); uri = httpLink(stream, path); kind = mprGetPathExt(path); if (smatch(kind, "css")) { espRender(stream, "<link rel='stylesheet' type='text/css' href='%s' />\n", uri); } else { espRender(stream, "<link rel='stylesheet/%s' type='text/css' href='%s' />\n", kind, uri); } } } }
/* WARNING: may yield */ PUBLIC int espLoadConfig(HttpRoute *route) { EspRoute *eroute; cchar *name, *package; bool modified; eroute = route->eroute; if (!route->update) { return 0; } package = mprJoinPath(mprGetPathDir(eroute->configFile), "package.json"); modified = 0; ifConfigModified(route, eroute->configFile, &modified); ifConfigModified(route, package, &modified); if (modified) { lock(esp); httpInitConfig(route); #if DEPRECATED || 1 /* Don't reload if configFile == package.json */ if (!mprSamePath(package, eroute->configFile)) { #endif if (mprPathExists(package, R_OK)) { if (httpLoadConfig(route, package) < 0) { unlock(esp); return MPR_ERR_CANT_LOAD; } } } if (httpLoadConfig(route, eroute->configFile) < 0) { unlock(esp); return MPR_ERR_CANT_LOAD; } if ((name = espGetConfig(route, "name", 0)) != 0) { eroute->appName = name; } if (espLoadCompilerRules(route) < 0) { return MPR_ERR_CANT_OPEN; } unlock(esp); } if (!route->cookie) { httpSetRouteCookie(route, sfmt("esp-%s", eroute->appName)); } if (route->database && !eroute->edi) { if (espOpenDatabase(route, route->database) < 0) { mprLog("error esp", 0, "Cannot open database %s", route->database); return MPR_ERR_CANT_LOAD; } } #if !ME_STATIC if (!(route->flags & HTTP_ROUTE_NO_LISTEN)) { MprJson *preload, *item; cchar *errMsg, *source; char *kind; int i; /* WARNING: may yield when compiling modules */ if (eroute->combine) { source = mprJoinPaths(route->home, httpGetDir(route, "CACHE"), sfmt("%s.c", eroute->appName), NULL); } else { source = mprJoinPaths(route->home, httpGetDir(route, "SRC"), "app.c", NULL); } lock(esp); if (espLoadModule(route, NULL, "app", source, &errMsg) < 0) { if (eroute->combine) { mprLog("error esp", 0, "%s", errMsg); unlock(esp); return MPR_ERR_CANT_LOAD; } } if (!eroute->combine && (preload = mprGetJsonObj(route->config, "esp.preload")) != 0) { for (ITERATE_JSON(preload, item, i)) { source = ssplit(sclone(item->value), ":", &kind); if (*kind == '\0') { kind = "controller"; } source = mprJoinPaths(route->home, httpGetDir(route, "CONTROLLERS"), source, NULL); if (espLoadModule(route, NULL, kind, source, &errMsg) < 0) { mprLog("error esp", 0, "Cannot preload esp module %s. %s", source, errMsg); unlock(esp); return MPR_ERR_CANT_LOAD; } } } unlock(esp); }