Jan 05 2017 08:45 AM
Hi
Using PnP JS Core, How would I go about getting a list of files from the "Pages" folder of an "Enterprise Wiki" and then getting the properties associated with each file?
Eventually I want to get all the properties associated with each file. In particular I'm interested in Title, ServerRelativePath and ServerRelativeUrl for now.
In case it helps, we use an "Enterprise Wiki" with folders. For each folder I want to generate a table of contents. So for a given folder I would want to filter by the url (ServerRelatieUrl?) for only files in that folder.
Thanks.
Jan 07 2017 02:27 AM
Jan 07 2017 04:43 AM
@Deleted, thanks for the reply.
If possible, I really want to do this in JavaScript. As you say, I could create an add-in and have that do the work. I'm new to SharePoint development it looks like the JavaScript way is simpler, in that I don't have to host it externally.
Also, if this was successful, a follow on project would be to create an enhanced left hand menu. It seems that the easiest way to do this, without creating/editing templates or page layouts, is with JavaScript embedding.
I'm using the judgement, feel free to correct me, that add-ins are for users to add to pages they create. Whereas, JavaScript embedding can be used to make changes to all pages.
BTW I never used Azure, have beginners skills in JavaScript, average skills in C#. I've spent most of the last 5 years or so doing PowerShell and Transact-SQL. I have good skills on both of these.
Jan 07 2017 04:57 AM - edited Jan 07 2017 04:59 AM
SolutionHi Alan,
First, 'Pages' is not a folder, it's a document library.
You can query a doc lib by multiple available methods in SharePoint REST API and PnP JS Core REST wrapper, like:
// Get by title
$pnp.sp.web.lists.getByTitle('Pages').items.get().then(function(item) { console.log(item); });
or
// Get by list url is more preferable way as list renaming won't crash the logic
$pnp.sp.web.getList(_spPageContextInfo.webServerRelativeUrl + '/Pages').items.get().then(function(item) { console.log(item); });
or by querying the real folder objects with `GetFolderByServerRelativeUrl` method like:
$pnp.sp.web
.getFolderByServerRelativeUrl(_spPageContextInfo.webServerRelativeUrl + '/Pages') // Here comes a folder/subfolder path .files .expand('Files/ListItemAllFields') // For Metadata extraction .select('Title,Name') // Fields to retrieve .get().then(function(item) { console.log(item); });
Cheers
Jan 07 2017 07:13 AM
@Andrew Koltyakov, thanks for the reply.
After some investigation I figured out that 'Pages' was a list and not a folder.
In our "Enterprise Wiki" we have used folders to create a hierarchy. Your last code snippet worked great for getting a list of files, but did not return folders. I modified it slightly (replaced .files with .folders) and was able to get folder information. So it now looks like this:
var files; $pnp.sp.web .getFolderByServerRelativeUrl(_spPageContextInfo.webServerRelativeUrl + '/Pages') // Here comes a folder/subfolder path .files .expand('Files/ListItemAllFields') // For Metadata extraction .select('Title,Name') // Fields to retrieve .get()
.then(function(item) { files = item; }); var folders; $pnp.sp.web .getFolderByServerRelativeUrl(_spPageContextInfo.webServerRelativeUrl + '/Pages') // Here comes a folder/subfolder path .files .expand('Folders/ListItemAllFields') // For Metadata extraction .select('Title,Name') // Fields to retrieve .get()
.then(function(item) { folders = item; });
Is this OK or is there a better way?
Thanks.
Jan 07 2017 07:54 AM
Hi @Alan Trafford,
There could be at least 2 strategies with your case:
In case of the first scenario, I would recommend using `$pnp.sp.web.getList(_spPageContextInfo.webServerRelativeUrl + '/Pages').items` ... with the conditions and so on.
With the second one, imo, it's better to deal with `$pnp.sp.web.getFolderByServerRelativeUrl('[...path to folder...]').files` and `$pnp.sp.web.getFolderByServerRelativeUrl('[...path to folder...]').folders` in a batch request. Or using plain REST call `/_api/Web/GetFolderByServerRelativeUrl(@FolderServerRelativeUrl)?$expand=Folders,Files,Folders/ListItemAllFields,Files/ListItemAllFields$select=...`.
Using search API also can be a good idea. A lot depends on usage scenarios and data amount.
For instance, I would decide to show only categories structure in the wiki menu. In the case of folders, it can be easily one single cached request to a list's folders. In some more advanced cases you would need to apply multiple categories to the wiki article, then managed metadata is better (with MMD you can even use OOTB tree MMD navigation).
Jan 07 2017 08:22 AM
@Andrew Koltyakov, thanks for your help, it's much appreciated.
Looks like I've some learning to do!
I'm visiting the PnP JS Core API pages regularly, but they lack examples. I'm sure this will make more sense in a few months.
Can you recommend any resources (articles, examples, references) for learning about searching, even if it's just terms I should search for?
Thanks.
Jan 07 2017 08:51 AM
PnP JS Core is mostly the wrapper around SharePoint REST APIs with syntax sugar and helpers it doesn't cover all the API.
I would recommend learning SharePoint REST API reference and PnP JS Core simultaneously. PnP JS Core has nice chaining logic and based on promises. During chaining helpers methods it constructs REST endpoint URL and builds requests data parameters (in POST calls), then initiates a promise.
I found myself learning such open source libraries which evolve faster than the documentation with the use of "debug-first learning" by logging in the console intermediate objects and results and checking the available options, like this:
var requestObject = $pnp.sp.web.getFolderByServerRelativeUrl(_spPageContextInfo.webServerRelativeUrl + '/Pages') .files.expand('Files/ListItemAllFields').select('Title,Name'); console.log('Valuable methods and props', requestObject); console.log('Url endpoint', requestObject.toUrl()); var promise = requestObject.get(); promise.then(function(data) { console.log(data); });
and diving in the sources and issues history.
It's not so scary like it seems. E.g., in the API reference documentation you might have found something like `GetFolderByServerRelativeUrl` method, it probably can be already implemented in the library (we know it is), the easiest way to check it is to search on GitHub repo. In most cases it's rather straightforward to figure out that: 1) implemented or not, 2) how to use a specific option. Also, issues area is opened for issues and questions if the previously described learning pattern can't help.
Jan 08 2017 09:39 AM
Jan 07 2017 04:57 AM - edited Jan 07 2017 04:59 AM
SolutionHi Alan,
First, 'Pages' is not a folder, it's a document library.
You can query a doc lib by multiple available methods in SharePoint REST API and PnP JS Core REST wrapper, like:
// Get by title
$pnp.sp.web.lists.getByTitle('Pages').items.get().then(function(item) { console.log(item); });
or
// Get by list url is more preferable way as list renaming won't crash the logic
$pnp.sp.web.getList(_spPageContextInfo.webServerRelativeUrl + '/Pages').items.get().then(function(item) { console.log(item); });
or by querying the real folder objects with `GetFolderByServerRelativeUrl` method like:
$pnp.sp.web
.getFolderByServerRelativeUrl(_spPageContextInfo.webServerRelativeUrl + '/Pages') // Here comes a folder/subfolder path .files .expand('Files/ListItemAllFields') // For Metadata extraction .select('Title,Name') // Fields to retrieve .get().then(function(item) { console.log(item); });
Cheers