I'm attempting to use Google Docs' ability to run scripts to create the necessary folder structure for new clients (to upload content/images into). Here's what I have thusfar:
/**
* This script creates the necessary folder structure for a new client
*/
function newClientSetup() {
var initial = DocsList.getFolder("Clients");
var client = DocsList.addtoFolder.createFolder("Client Name");
var file = DocsList.addtoFolder(client);
};
Now this is not working (TypeError: Cannot call method "createFolder" of undefined. (line 7)), but I'm having trouble figuring out how to use the Folder class within DocList. I saw that DocsList has a createFolder method, that I could use like:
var folder = DocsList.createFolder("Folder Name");
but I'm trying to start off with a parent folder, called Clients (already in Google Docs) and then create the following structure:
Clients
Client Name
Content
Images
Ideally I could run this script, but pass in a variable for Client Name to actually create the client name, but I haven't found much help from the docs. Any suggestions? Thanks!
Here is an example of how it works, see comments :
function createSubFolder(subfolder) { // the argument is the name of the folder you want to create
var parentfolder = DocsList.getFolder('Clients'); //begin in the client folder (you could also open by Id, I prefer the ID as I find it more failsafe (ID are unique, names aren't necessarily
var newFolder = DocsList.createFolder(subfolder); // create the new subfolder from the argument of the function
newFolder.addToFolder(parentfolder);// add the newly created folder to 'Clients'
}
to test this function simply use something like this :
function test(){
createSubFolder('test');// this will create a new folder called test in your Clients folder
}
note : to get the ID of your folder, take the value right behind folders/ in the url of the folder. Example in bold : https://drive.google.com/?hl=fr&tab=wo#folders/0B3qSFxxxxxxxxxdsMTFZMDQ
The sequence might be much longer if you have more folder levels... but the structure is always the same and is unique for every folder.
Here's a function and some code I wrote which might help you. It uses a sub function to see if the folder already exists and if it doesn't makes it. If the folder does already exist it returns that object which helps with chaining (referenced here on how it is used):
function newClientSetup() {
var ROOT_FOLDER = "Clients";
var CLIENTNAME_FOLDER = "Client Names";
// get a the system route folder (if it deosn't existing make it
var rootFolder = folderMakeReturn(ROOT_FOLDER);
// create/get draft and release folders
var clientNamesFolder = folderMakeReturn(CLIENTNAME_FOLDER,rootFolder, ROOT_FOLDER+"/"+CLIENTNAME_FOLDER);
}
// function to see if folder exists in DocList and returns it
// (optional - if it doesn't exist then makes it)
function folderMakeReturn(folderName,optFolder,optFolderPath){
try {
if (optFolderPath != undefined){
var folder = DocsList.getFolder(optFolderPath);
} else {
var folder = DocsList.getFolder(folderName);
}
return folder;
} catch(e) {
if (optFolder == undefined) {
var folder = DocsList.createFolder(folderName);
} else {
var folder = optFolder.createFolder(folderName);
}
return folder;
}
}
I know the question/answer is 3 years old and it was correct earlier, but this solution is no more working correctly with Google Apps script as on 2015, current easiest way to create a subfolder on a specific folder is,
function createSubFolder(parentId, folderName)
{
var id="";
try
{
var parent=DriveApp.getFolderById(parentId); // get parent folder
var folder =parent.createFolder(folderName); // create sub folder
id=folder.getId(); // get the subfolder id to return
}
catch(e)
{
}
return id;
}
pass the parent folder id with the sub folder name you want to create, the Folder class has the method createFolder to create a folder under it which returns the created subfolder's object.
Related
I have two folders next to each other as it follows ..
// Folder 1
users
-services
-index
-otherThings
= services
exports.A = (a,b,c)=> { // do something }
exports.B = (a,b,c)=> { // do something }
= index.js
const services= require('./services');
const otherThings= require('./otherThings');
module.exports = { otherThings, services};
// Folder 2
middlewares
-is-auth
-index.js
= is-auth
const { services } = require('../users');
// services here is undefined
// when i require the full index object it is an empty object
const indexObject = require('../users')
console.log(indexObject) // {}
the weird thing is when using services required above i am getting suggestions of the folder 1 services (A,B functions) but they are undefined !
console log services in folder 1 if it is coming there.
check the hierarchy of your folder structures when importing and
check the paths also,
other wise the code seems right.
edit 1:
not sure what exactly services type are, but it seems only function A and B are there, if you just need those functions you can export them individually and try,
if that works then you can back track to, why services was not working in the first place,
if not, then just try any random variable try importing if it doesn't work then it's may be related to hierarchy.
edit 2:
i think i got it,
if my assumption is right users is folder and services is file, then you need the path as require(../users/services);
edit 3:
then check out this link require folder as a module
This might seem a little convoluted, so I apologize in advance if it does.
I'm attempting to create a build tool in Node.js for Chrome Extensions, so the final JS file has to be ES5 compliant.
I have separate JS files for each setting within the extension that export an object, the function within this object needs to be imported into the contentScript.js file and placed within it's own settings object.
I've put together a basic screenshot that shows how this should flow, but I'm not sure of how to approach this issue. I've considered some type of string interpolation within the contentScript which Node would then replace, but that seems more of a workaround than a solution.
Say we have a folder called settings, within those settings are two JavaScript files, each with a different name, type, and function, they'd look like this.
// settingName1.js
module.exports = {
name: 'Setting Name 1',
type: 'switch',
function: () => {
console.log('Setting 1 initialized');
}
}
Ideally, both of these files would have their respective functions imported into the contentScript, under a settings object, for example.
// contentScript.js
// Settings Functions Go Here
const settings = {
settingName1: function() {
console.log('Setting 1 initialized')
},
settingName2: function() {
console.log('Setting 2 initialized')
}
}
});
Basically cutting/copying the function from the source setting file itself, and pasting it under a function (named using the file's name) within the contentScript's settings object.
Here's an idea for the generated file:
// header on the file
const capturedExports = [];
// insert this prologue before each inserted file
(function() {
// =============================
// insert settingName1.js here
module.exports = {
name: 'Setting Name 1',
type: 'switch',
function: () => {
console.log('Setting 1 initialized');
}
}
// =============================
// insert this epilogue after each inserted file
})();
capturedExports.push(module.exports);
// insert this prologue before each inserted file
(function() {
// =============================
// insert settingName2.js here
module.exports = {
name: 'Setting Name 2',
type: 'switch',
function: () => {
console.log('Setting 2 initialized');
}
}
// =============================
// insert this epilogue after each inserted file
})();
capturedExports.push(module.exports);
// insert code that builds the settings object
const settings = {};
for (let exportItem of capturedExports) {
let name = exportItem.name.replace(/\s/, "");
name = name.slice(0, 1).toLowerCase() + name.slice(1);
settings[name] = exportItem.function;
}
You do the following steps to output a new file that is collection of all the settingNamex.js files.
Create the new file.
Write a header to it with the const capturedExports = []; line and the start of the IIFE.
For each settingNameX.js file, write that file to it.
Then write the close of the IIFE and the capturedExports.push(module.exports); after it. This will grab whatever the previous code assigned to module.exports and add it to the caputuredExports array.
Repeat this process for each settingNameX.js file.
Then, insert the code that builds the settings object from the capturedExports array.
Enclosing each inserted module in its own IIFE, gives it its own scope so it doesn't create symbol conflicts with the other inserted modules.
This makes the following assumptions.
It assumes that the code from each of the settingNameX.js files assigns the appropriate object to module.exports like your examples show. In the real world, you probably want to add a bunch of tests to see if the right thing is assigned to module.exports (proper defensive coding).
It assumes that the inserted modules are not assigning conflicting things to the global object.
It assumes your own module doesn't need the module.exports or can overwrite it at the end after the inserted modules have used it. If this assumption isn't OK, then you'd have to manually change module.exports = to something else that you define in your master module.
I have created a js file to create folders when creating an event in Alfresco. But the problem is, when I create an event on the Alfresco site, it will automatically create a folder in a shared folder. That's a problem because when updating an existing event it creates a new folder without removing the existing folder. Also, when I delete an event it will not delete the corresponding folder.
How can I solve this problem?
Here is my code to create a new folder when an item is created:
// create a new folder in the same space
var folderNode = space.createFolder(document.properties["ia:whatEvent"]);
// copy the doc into the newly created folder node
//var copy = document.copy(folderNode);
// move the folder node to companyhome
var objDestFolder = companyhome.childByNamePath("Shared/SECRETARY/COMMISSION_PAPER_RECEIVED");
folderNode.move(objDestFolder);
If you wanted to create folder in the site than you need to specify the parent folder object where the new folder/document will get created.
like docLibContainer.createFolder for this docLibContainer is parent folder object.
In your case space is parent folder object.
Please try in this example docLibContainer will create a folder of name document.properties["ia:whatEvent"] in Document Library Folder.
var site = document.getSiteShortName();
var docLibContainer = siteService.getSite(site).getContainer("documentLibrary");
if(docLibContainer){
// create a new folder in the same space
var folderNode = docLibContainer.createFolder(document.properties["ia:whatEvent"]);
// copy the doc into the newly created folder node
//var copy = document.copy(folderNode);
// move the folder node to companyhome
var objDestFolder = companyhome.childByNamePath("Shared/SECRETARY/COMMISSION_PAPER_RECEIVED");
folderNode.move(objDestFolder);
}else{
// create a new folder in the same space
var folderNode = space.createFolder(document.properties["ia:whatEvent"]);
// copy the doc into the newly created folder node
//var copy = document.copy(folderNode);
// move the folder node to companyhome
var objDestFolder = companyhome.childByNamePath("Shared/SECRETARY/COMMISSION_PAPER_RECEIVED");
folderNode.move(objDestFolder);
}
If I want to span my JavaScript project across multiple source files, but have each file have access to the same private variable, how would one do that?
For example, if I have the following code:
APP = (function () {
var _secret = {},
app = {};
// Application part 01:
app.part01 = (function () { /* function that uses _secret */ }());
// Application part 02:
app.part02 = (function () { /* function that uses _secret */ }());
//
return app;
}());
How do I put app.part01 and app.part02 in seperate files, but still have access to _secret?
I don't want to pass it as an argument. That's just giving the secret away, as app.part01() could be replaced by any other function.
Maybe I am asking the impossible, but your suggestions might lead me in the right way.
I want to work with multiple files, but I don't know how. Copying and pasting everything inside a single function each time before testing is not something I want to do.
How do I put app.part01 and app.part02 in seperate files, but still have access to _secret?
That's impossible indeed. Script files are executed in the global scope, and don't have any special privileges. All variables that they will be able to access are just as accessible to all other scripts.
Copying and pasting everything inside a single function each time before testing is not something I want to do
What you are looking for is an automated build script. You will be able to configure it so that it bundles your files together, and wraps them in an IEFE in whose scope they will be able to share their private state. The most simple example:
#!/bin/sh
echo "APP = (function () {
var _secret = {},
app = {};" > app.js
cat app.part01.js >> app.js
cat app.part02.js >> app.js
echo " return app;
}());" >> app.js
The only way that you can share _secret is attaching it to the application object and then application object to the window object. Here is an example.
// FIRST JS FILE...
var application; // will be attached to window
(function(app) {
app.secret = "blah!"; // will be attached to application
})(application || (application = {}));
// ANOTHER JS FILE
var application;
(function(app) {
app.method1 = function(){ console.log(app.secret); }; // will be attached to application;
})(application || (application = {}));
console.log(application.method1()); // will display 'blah!' on the console
Working example on jsbin
One way I was able to accomplish this was to create a JS file that contained the global object.
// Define a global object to contain all environment and security variables
var envGlobalObj = {
appDatabase: process.env.YCAPPDATABASEURL,
sessionDatabase: process.env.YCSESSIONDATABASEURL,
secretPhrase: process.env.YCSECRETPHRASE,
appEmailAddress: process.env.YCAPPEMAILADDRESS,
appEmailPassword: process.env.YCAPPEMAILPASSWORD
}
module.exports = envGlobalObj
Then in the files I wish to reference this object, I added a require statement.
var envGlobalObj = require("./envGlobalObj.js");
This allowed me to centralize the environment and secrect variables.
I have two files, let's call them main.js and sub.js, with a function in sub.js that is exported and called from the second file main.js but is also called from within sub.js (from another function that is exported).
The code is something like this:
Main.js:
var streak = require('./sub.js');
profile = streak.streak_broken(profile); // is called from another file
Sub.js:
// External functions
module.exports.streak_broken = function(profile) {
profile.counter = 0;
return profile;
};
module.exports.second_func = function(profile) {
// Do something
profile = streak_broken(profile); // streak_broken is not defined - how can I correct this?
return profile;
};
I could obviously make a copy of the streak_broken function and either have it as a local function further up in sub.js or put it directly into the module.exports.second_func code where it's called within sub.js but that isn't the best programming I guess.
How can I overcome that warning "streak_broken is not defined"? Your help is appreciated, thank you in advance!
Replace
profile = streak_broken(profile);
with
profile = module.exports.streak_broken(profile);