Introduction
I wanted to add a simple gallery of images to my personal web site and couldn't find anything suitable that was based around picking them from a folder rather than a database. Perhaps I should have looked harder! Nonetheless, here is my take on implementing a photographic gallery that picks the images from one or more folders and does it in the simplest possible fashion.
Background
I have implemented this in Visual Studio 2017 as an MVC Asp.Net 4.6.2 application. Feel free to adapt to your chosen framework version and to extract to a web-forms application if so desired. I have not tested for that scenario but, with some minor mods, it should work.
Note also that the application uses jquery and bootstrap but nothing much else.
Using the code
Ok, let's get started!
First thing to do is to open the attached project and examine the code. For the most part, it is fairly straightforward and you should be able to extract the bits that do the work into your own application - this is designed to be as simple as simple can be.
What is going on...
If you haven't already got an application into which you wish to apply the gallery, you should open your Visual Studio of choice and create an MVC web application.You can accept the defaults since that will not impact what comes next.
The first thing is to create a folder to store our images. I have named mine "Photos". Beneath that I have created a sub-folder called "Other". You can create any number of sub-folders under the primary folder though that may get messy to keep track of. Remember, this is a simple solution, not an enterprise level image gallery solution!
The "Photos" folder holds all of my default images; those that I want to display immediately, whereas the other folders contain sub-sets of images or images that you need to drill through to get to.
Now we need a class to hold all of the images - I will call it "Photos" (evidently, I lack imagination).
public string Path { get; set; }
public string Description { get; set; }
public Photos(string path, string description)
{
Path = path;
Description = description;
}
Nothing magical here; we need to get the path to its location and some descriptive text
Next, we need a way to get the images into the model (class) so that we can pass the appropriate set of images to the view.
A reasonable way to do this is to create a class that inherits form a list of our model like:
public class PhotoModel : List<Photos>
Inside the constructor we can navigate to a given folder and enumerate all of the files in that folder.
public PhotoModel(string folder)
which, having parsed the folder into a DirectoryInfo
object, allows us to enumerate the folder making sure we only hit the given folder and no folders that exist beneath it...
foreach (var file in di.EnumerateFiles("*.jpg", SearchOption.TopDirectoryOnly))
Finally, add each found file to the <Photos> object with
var p = new Photos(string.Concat(folder, file.Name), Path.GetFileNameWithoutExtension(file.Name));
Add(p);
To get all of this to the view we need to add code to the Controller object which instantiates that view:
Open the controller and add the following code:
public ActionResult Gallery(int id)
{
string folder = "~/photos/";
switch (id)
{
case 1:
folder = "~/photos/other/";
break;
case 0:
folder = "~/photos/";
break;
}
return View(new PhotoModel(folder));
}
I did stress that this was simple, hence hard coding the paths to the photo folders here. Feel free to extract this bit and make it configurable or however you think you'd prefer to do it. In any case, we have to tell <PhotoModel> which path we want it to get the images from. Note also that we pass the method an integer as id to tell it which folder to use. Again, simple although could also pass this as a string of the path - take your pick. Finally, invoke the view, passing the correct model.
Visually speaking...
Ok, so we've covered all of the code so let's look at the view
To start with, we need to add a menu option to drive the page - we do that by adding a line to Views/Shared/_Layout.cshtml
.
<li>@Html.ActionLink("Gallery", "Gallery", "Home", new { id = 0 }, null)</li>
Notice that we are pre-loading by telling the Controller that we want to display the default gallery. If you don't do this, it'll go terribly wrong.
Now add a page under Views/Home
called Gallery.cshtml
. This requires four things:
- Add css and javascript
- A means to switch folder
- A means to display all of the images that were found
- A means to display individual folders in a popup
We also need to include some css and javascript which will style the page and give us the ability to display the popup - the files are called gallery.css and gallery.js.
Feel free to examine and change the css as appropriate - nothing magical in there. The javascript simply displays an otherwise hidden div
, pops the chosen image into a new image control and uses the alt text of that image as descriptive text on the popup.
Note: if you don't like that I have blacked out the page when displaying the modal, you can later the following line (line 26) in gallery.css:
background-color: rgb(0, 0, 0);
For instance, the following gives a rather nice yellow-orange shade (on my screen):
background-color: rgb(255, 216, 0);
The main part of the View is the foreach
loop that renders the images into the page, assigning the values from the <PhotoModel> class.
Below that the snippet of html that describes the modal popup:
<div id="divimage" class="modal">
<img class="modal-content" id="modalimg">
<div id="caption"></div>
</div>
And that's it. The attached demo should work and be compilable as is.
Points of Interest
It works well for me - if this is not complex enough or you need to load images from a database, this solution is not for you.
Finally
I'm certain that this could be improved upon but it satisfies my requirement as it stands especially as it didn't take too long to pull it together. Enjoy!
History
v1 - initial and final release