For LÖVE 0.10.2

Here's a function which loads images and sounds from a folder into a table, with keys based on file names and subfolders in subtables.

For example, if you have a game folder with these files...

main.lua
rainbow.png
sounds/sparkle.ogg
sounds/music/smoothjazz.xm

... and then call this function...

loadresources()

... the resources will be loaded and can be used like this:

love.graphics.draw(rainbow)
sounds.sparkle:play()
sounds.music.smoothjazz:play()

A table can be given to load the resources into...

resources = {}

loadresources(resources)

love.graphics.draw(resources.rainbow)
resources.sounds.sparkle:play()
resources.sounds.music.smoothjazz:play()

... or a base folder can be given...

loadresources('sounds')

sparkle:play()
music.smoothjazz:play()

... or both, with the arguments in either order:

resources = {}

loadresources('sounds', resources)

resources.sparkle:play()
resources.music.smoothjazz:play()

The function:

function loadresources(a, b)

	local base_folder, resource_table

	if type(a) == 'string' then
		base_folder = a
	elseif type(b) == 'string' then
		base_folder = b
	else
		base_folder = ''
	end

	if type(a) == 'table' then
		resource_table = a
	elseif type(b) == 'table' then
		resource_table = b
	else
		resource_table = _G
	end

	local function load_directory(folder, place)

		for _, item in pairs(love.filesystem.getDirectoryItems(folder)) do

			local path = folder..'/'..item

			if love.filesystem.isFile(path) then
				local name, ext = item:match('(.+)%.(.+)$')

				if ext == 'png' or ext == 'bmp' or ext == 'jpg' or ext == 'jpeg' or ext == 'gif' or ext == 'tga' then
					place[name] = love.graphics.newImage(path)

				elseif ext == 'ogg' or ext == 'mp3' or ext == 'wav' or ext == 'xm' or ext == 'it' or ext == 's3m' then
					place[name] = love.audio.newSource(path)
				end

			else
				place[item] = {}
				load_directory(path, place[item])
			end
		end
	end

	load_directory(base_folder, resource_table)

end

What's going on:

There's a base folder to search through and a table for the resources to be loaded into. If these aren't given to the function as arguments, the base folder is the game folder and the resource table is the global table, _G.

There's a local function which is given a folder and a table, and is defined like this:

Loop through each item (file and folder) in the given folder using the table returned by love.filesystem.getDirectoryItems and pairs...

If it's a file...

If it's a folder...

After the function is defined, it's called with the base folder and resource table.

An example:

For example, if you have a game folder with these files...

main.lua
rainbow.png
sounds/sparkle.ogg
sounds/music/smoothjazz.xm

... and then call the function like this...

resources = {}

loadresources(resources)

... here's what happens:

Loop through all of the items in the folder

folder ''
place resources
main.lua
rainbow.png
sounds

Create the full path by joining the folder with the item name

path = '' .. '/' .. 'main.lua'

Is it a file or a folder?

love.filesystem.isFile('/main.lua') returns true, it's a file!

Separate the name and extension

name, ext = ('main.lua'):match('(.+)%.(.+)$')

main, lua

Is it an image or a sound extension?

Neither, nothing to do here!

Next item in the folder!

folder ''
place resources
main.lua
rainbow.png
sounds

Create the full path by joining the folder with the item name

path = '' .. '/' .. 'rainbow.png'

Is it a file or a folder?

love.filesystem.isFile('/rainbow.png') returns true, it's a file!

Separate the name and extension

name, ext = ('rainbow.png'):match('(.+)%.(.+)$')

rainbow, png

Is it an image or a sound extension?

Image!

Load it into the current place with the key of the name

resources['rainbow'] =
love.graphics.newImage('/rainbow.png')

Next item in the folder!

folder ''
place resources
main.lua
rainbow.png
sounds

Create the full path by joining the folder with the item name

path = '' .. '/' .. 'sounds'

Is it a file or a folder?

love.filesystem.isFile('/sounds') returns false, it's a folder!

Create a new table in the current place with key of the folder name

resources['sounds'] = {}

Repeat the function with this table and this folder path

load_folder('/sounds', resources.sounds)

Loop through all of the items in the folder

folder '/sounds'
place resources.sounds
music
sparkle.ogg

Create the full path by joining the folder with the item name

path = '/sounds' .. '/' .. 'music'

Is it a file or a folder?

love.filesystem.isFile('/sounds/music') returns false, it's a folder!

Create a new table in the current place with key of the folder name

resources.sounds['music'] = {}

Repeat the function with this table and this folder path

load_folder('sounds', resources.sounds)

Next item in the folder!

folder '/sounds'
place resources.sounds
music
sparkle.ogg

Create the full path by joining the folder with the item name

path = '/sounds' .. '/' .. 'sparkle.ogg'

Is it a file or a folder?

love.filesystem.isFile('/sounds/sparkle.ogg') returns true, it's a file!

Separate the name and extension

name, ext = ('sparkle.ogg'):match('(.+)%.(.+)$')

sparkle, ogg

Is it an image or a sound extension?

Sound!

Load it into the current place with the key of the name

resources.sounds['sparkle'] =
love.graphics.newSource('/sounds/sparkle.ogg')

Loop through all of the items in the folder

folder '/sounds/music'
place resources.sounds.music
smoothjazz.xm

Create the full path by joining the folder with the item name

path = '/sounds/music' .. '/' .. 'smoothjazz.xm'

Is it a file or a folder?

love.filesystem.isFile('/sounds/music/smoothjazz.xm') returns true, it's a file!

Separate the name and extension

name, ext = ('smoothjazz.xm'):match('(.+)%.(.+)$')

smoothjazz, xm

Is it an image or a sound extension?

Sound!

Load it into the current place with the key of the name

resources.sounds.music['smoothjazz'] =
love.graphics.newSource('/sounds/music/smoothjazz.xm')