How to match metadata with a nested file? - harp

My _layout.jade file
(...)
if toc
div(id='toc', class="")
(...)
makes use of a variable set in _data.json:
{
"handbook": {
"toc": true
},
"incidents/incidents": {
"toc": true
}
}
This works fine for handbook.md located in the root directory, but incidents.md located in the directory incidents is not matched. I tried to have a bare "incidents" in _data.json, but it is not matched either.
How should I reference /incidents/incidents.md in _data.json?

Try adding a _data.json file in the incidents/ directory too. That’s where you’ll specify all the metadata for the pages in that folder:
{
"incidents": {
"toc": true
}
}
Then /incidents/incidents will have the toc variable, too.

Related

How to download file from Sanity via HTTP?

I would like to know if there is possibility to download file from Sanity with HTTP request?
I only have reference ID:
{
file: {
asset: {
_ref: "file-fxxxxxxxxxxxxxxxxxxxx-xlsx"
_type: "reference"
}
}
}
I would like to do this is this scenario:
<a href="https://cdn.sanity.io/assets/clientID/dataset/file-xxxxxxxxxxx-xlsx">
Download File
</a>
You can, indeed 🎉 With a bit of custom code you can do it just from the _ref, which is the file document's _id
Creating the URL from the _ref/_id of the file
The _ref/_id structure is something like this: file-{ID}-{EXTENSION} (example: file-207fd9951e759130053d37cf0a558ffe84ddd1c9-mp3).
With this, you can generate the downloadable URL, which has the following structure: https://cdn.sanity.io/files/{PROJECT_ID}/{DATASET}/{ID_OF_FILE}.{EXTENSION}. Here's some pseudo Javascript code for the operation:
const getUrlFromId = ref => {
// Example ref: file-207fd9951e759130053d37cf0a558ffe84ddd1c9-mp3
// We don't need the first part, unless we're using the same function for files and images
const [_file, id, extension] = ref.split('-');
return `https://cdn.sanity.io/files/${PROJECT_ID}/${DATASET}/${id}.${extension}`
}
Querying the URL directly
However, if you can query for the file's document with GROQ that'd be easier:
*[(YOUR FILTER HERE)] {
file->{ url } // gets the URL from the referenced file
}
You can do the same with images, too.

createjs loadManifest, it should be loading files in manifest, correct?

If I understand the docs correctly… 
window.queue = new createjs.LoadQueue(true, null, true);
queue.loadManifest({src: manifest, type: "manifest"}, true);
should be loading the files that are located in the json file, correct? Not seeing any requests in inspector, only getting the results array in console. Do I have to loop over results array and do the loadFile manually?
JSON is formatted correctly in a {src:"",id:"",type:"createjs.Types.IMAGE"} structure.
Any help is appreciated.
Adding more code:
function to pass in manifest url
function loadImages(manifest) {
window.queue = new createjs.LoadQueue(true, null, true);
queue.loadManifest({src: manifest, type: "manifest"}, true);
queue.on("fileload", this.handleFileLoaded);
queue.on("progress", function(event) {
console.log("progress " + event.progress);
});
queue.on("fileprogress", function(event) {
console.log("file progress " + event.progress);
});
queue.on("error", function(event) {
console.log("file error");
});
queue.on("complete", function(event) {
console.log("queue complete");
console.log(event);
});
queue.load();
return queue;
}
handleFileLoaded event is just dumping event to console at this point.
Manifest with two examples
{
"path":"https://images.unsplash.com/",
"type":"manifest",
"manifest": [
{
"src":"photo-1542838454-d4dce2a7cfde?fit=crop&w=500&q=60",
"id":"stair_boy",
"type":"createjs.Types.IMAGE"
},
{
"src":"photo-1549948558-1c6406684186?fit=crop&w=500&q=60",
"id":"night_bridge",
"type":"createjs.Types.IMAGE"
}
]}
I get access to the manifest array in the fileload event, I can manually load the images from there, but that seems counterintuitive to the whole point of using the PreloadJS. Seems like on page load, Preload should load the manifest, recognize 'type'… loop through files and in network inspector I should see the web requests for the images.
The types in your manifest are incorrect. You are passing in a string value of "createjs.Types.IMAGE". This is not equal to "image", nor is it the equivalent of the JavaScript createjs.Types.IMAGE, since it is interpretted as a string.
Instead use the string value "image"
{
"path":"https://images.unsplash.com/",
"type":"manifest",
"manifest": [
{
"src":"photo-1542838454-d4dce2a7cfde?fit=crop&w=500&q=60",
"id":"stair_boy",
"type":"image"
},
{
"src":"photo-1549948558-1c6406684186?fit=crop&w=500&q=60",
"id":"night_bridge",
"type":"image"
}
]}
Edit: The type property is only required when there is not a recognizable image extension, such as this case.
From the docs:
The loadManifest call supports four types of manifests:
A string path, which points to a manifest file, which is a JSON file that contains a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An object which defines a "src", which is a JSON or JSONP file. A "callback" can be defined for JSONP file. The JSON/JSONP file should contain a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An object which contains a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An Array of files to load.
Your example uses the first approach. If something is not working, then feel free to post more code.
You could always throw some more events on your queue to see what is happening, such as "fileststart", "fileload", and "error". You should get at least one event when the first manifest starts loading.
Cheers.

How to properly set contents in a gitbook-plugin's block?

Get the path of a file in gitbook head
This question touch the possibility to get a path of a specific file.
For example, to get some content, before page loads in a gitbook, is possible to add in "head:end" some customizations. This work fine when we need jquery loaded in `.
module.exports = {
book: {
...
/* Load files */
html: {
'head:end': function(current){
console.log()
var p = current.basePath+"/"+current.staticBase+"/plugins/myplugin/jquery-latest.min.js";
...
}
...
Get the path of a file in gitbook block
But in a custom block, how i do this?
blocks: {
myblock: {
process: function(current) {
//current isnt same... :(
// h
console.log(current);
var p = current.basePath+"/"+current.staticBase+"/plugins/myplugin/"+current.args[0];

Appcelerator Titanum Delete File in tmpdirectory

I am using Appcelerator Titanium 3.0.2 to allows user to watch/download videos&audios. Here is part of code to get the file object and play the audio.
var filename = self.url.substring(self.url.lastIndexOf('/')+1);
var file = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory,filename);
if(!file.exists())
self._download(self.url, filename, Ti.Filesystem.tempDirectory, function(){
setAudUrl(file.nativePath);
timeBar.max = audPlayer.duration*1000;
prgHandle = setInterval(updateProgressBar,10000);
audPlayer.play();
audCtrlBar.show();
loading.hide();
},
function(_progress,_position){
httpClient=_position;
loading.show();
},
function(){
noLabel.show();
loading.hide();
});
else {
setAudUrl(file.nativePath);
timeBar.max = audPlayer.duration*1000;
prgHandle = setInterval(updateProgressBar,10000);
audPlayer.play();
audCtrlBar.show();
}
This code is working, but my question is how to remove the file when the user exist the app. Since Apple required that file in /tmp directory will be removed after user exist the app. Anyone can help? Thanks.
You could use Titanium's application events pause and paused. They are called when the app becomes inactive but this only works on iOS.
Titanium.App.addEventListener('pause' /* or paused, see docs */, function() {
var dir = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory, 'tmpDownloads'); // ensure that you use the same folder for storing the downloaded files. A separate folder is easier to remove.
if(dir.exists() && dir.isDirectory()) {
dir.deleteDirectory(true); // true removes recursively the directory and its contents
}
});
You need to create the directory again when resume-ing the app.

usemin revved filenames and requirejs dependencies

I'm running into the following problem with requirejs and usemin:
I want to setup a multipage application, where I dynamically load modules that only contain page specific functionality (e.g. about -> about.js, home -> home.js). I could go ahead and pack everything in a single file, but that just leads to a bigger file size and overhead on functionality that isn't necessary on each site! (e.g. why would I need to load a carousel plugin on a page that doesn't have a carousel!)
I checked out the example https://github.com/requirejs/example-multipage-shim
That is in fact a great way to deal with it, until I bring usemin into the game. After revving the filenames the src path of each script tag is updated, but what about the dependencies?
<script src="scripts/vendor/1cdhj2.require.js"></script>
<script type="text/javascript">
require(['scripts/common'], function (common) {
require(['app'], function(App) {
App.initialize();
});
});
</script>
In that case, require.js got replaced by the revved file 1cdhj2.require.js. Great!
But the required modules "common" and "app" no longer work since common became 4jsh3b.common.js and app became 23jda3.app.js!
What can I do about this? Thanks for your help!
(Also using Yeoman, btw)
It's a tricky problem and I'm sure somebody else fixed in in a more elegant way, but the following works for me.
I might publish this as a grunt plugin once it's a little more robust.
Taken from my Gruntfile:
"regex-replace": {
rjsmodules: { // we'll build on this configuration later, inside the 'userevd-rjsmodules' task
src: ['build/**/*.js'],
actions: []
}
},
grunt.registerTask('userevd-rjsmodules', 'Make sure RequireJS modules are loaded by their revved module name', function() {
// scheduled search n replace actions
var actions = grunt.config("regex-replace").rjsmodules.actions;
// action object
var o = {
search: '',
replace: '', //<%= grunt.filerev.summary["build/js/app/detailsController.js"] %>
flags: 'g'
};
// read the requirejs config and look for optimized modules
var modules = grunt.config("requirejs.compile.options.modules");
var baseDir = grunt.config("requirejs.compile.options.dir");
var i, mod;
for (i in modules) {
mod = modules[i].name;
revvedMod = grunt.filerev.summary[baseDir + "/" + mod + ".js"];
revvedMod = revvedMod.replace('.js', '').replace(baseDir+'/','');
o.name = mod;
o.search = "'"+mod+"'";
// use the moduleid, and the grunt.filerev.summary object to find the revved file on disk
o.replace = "'"+revvedMod+"'";
// update the require(["xxx/yyy"]) declarations by scheduling a search/replace action
actions.push(o);
}
grunt.config.set('regex-replace.rjsmodules.actions', actions);
grunt.log.writeln('%j', grunt.config("regex-replace.rjsmodules"));
grunt.task.run("regex-replace:rjsmodules");
}),
You can also use requirejs' map config to specify a mapping between your original module and your revved one.
Filerev outputs a summary object containing a mapping of all the modules that were versioned and their original names. Use grunt file write feature to write a file in AMD way with the contents being the summary object:
// Default task(s).
grunt.registerTask('default', ['uglify', 'filerev', 'writeSummary']);
grunt.registerTask('writeSummary', 'Writes the summary output of filerev task to a file', function() {
grunt.file.write('filerevSummary.js', 'define([], function(){ return ' + JSON.stringify(grunt.filerev.summary) + '; })');
})
and use this file in your require config so that the new revved modules are used instead of old ones:
require(['../filerevSummary'], function(fileRev) {
var filerevMap = {};
for (var key in fileRev) {
var moduleID = key.split('/').pop().replace('.js', '');
var revvedModule = '../' + fileRev[key].replace('.js', '');
filerevMap[moduleID] = revvedModule;
}
require.config({
map: {
'*': filerevMap
}
});
The filerevMap object that I created above is specific to my folder structure. You can tweak it as per yours. It just loops through the filerev summary and makes sure the keys are modified as per your module names and values as per your folder structure.