How To: Update the Atlas
Let's get an idea of what it's like to make a change to the Atlas! Recently for another project I've updated the copies of various sprite rips from the Pokémon games and standardized them a bit. Which means there are now images for shiny Pokémon using the models from gen6! I thought it would be a nice touch to implement these on the team overviews on the Atlas.
First thing's first, get the development server up and running. Editing code on production is... frowned upon. For the Atlas, the site is built using Django which has it's own development webserver which is quick and easy to get running. The development server lives on a Raspberry Pi so I have to connect into it first from my desktop and start the server up from there.
Once it's running, that console window will print out errors, file requests, and any print statements in the Atlas code. At this point I can put "192.168.0.31:8000" into any browser on my local network and see the site. That address is a bit of a mouthful so I've set up an alias so that "django.pi" takes me right to it instead.
I log in just the same as I would on the live site, and look for a suitable team to work with. At some point I copied the live site's database over to the development server so I had more to work with. I may have stolen this team, but I don't see a Sine Armor on the live Atlas so they may have since left! Their team was not a Pachirisu and a Mandibuzz however.
Anyway! Neither of the Pokémon on this team are shiny, so I need to change that. If I needed to, I could edit them in the database manually and set shiny to 1 for them, but there's an easier way.
Admins can edit the lock time for teams and Pokémon on them, bypassing the usual restriction of not being able to edit things after 24 hours. I make them editable, and set them to shiny.
Okay! Now I have a team I can test with!
Next up is copying the images into the proper folder. I just drag and drop them in Windows and overwrite the old ones. There's some other images here like megas, and female forms for dimorphic Pokémon like Pikachu. While it would be nice to use the female sprites, that's a bit tough since unlike the games, PMDU will let you put whatever you like for gender.
In fact, there are 99 different entries on the Atlas for gender. Such as: "(No Gender)", "ALL OF THEM", "Both", "Fantastic", "Female", "Identifies Male", "None/Him", "Plant" (that one's mine), and so on. (Every single one of these is a valid answer FYI!) While it would be possible to add another field and let people set if they want to display the female model, it's a bit of effort for something most Pokémon don't have available, and that these models don't begin to capture the personalities of everybody's characters as is.
But I'm getting distracted! I need to find the files that reference these gen6 sprites, and add some code to change what shows up if they're shiny.
Using grep, I can search through files. In this case, the HMTL templates directory is going to be the relevant place. I search for any files which contain "x-y" which was the folder name with the images. These are the files that will need to be updated.
Starting with pokemon_show.html, which is a part of the page you see when you view a team, you can see where the sprite gets used. (You can also see inline CSS...) <img id="poke_sprite-{{forloop.counter}}" class="sprite" src="/assets/images/sprites/x-y/{{poke.species}}.png">
So this is an HTML img tag. This means there's going to be an image here. The id is a unique identifier set so that the element can be referenced again elswhere. The class is a more generic identifier, usually used for CSS to tell browsers how to display this image, like saying to make it 200 pixels wide or giving it a red border, or whatever else. Lastly is the source, which is the location of the image that should be displayed.
You can see {{forloop.counter}} and {{poke.species}}. This is where Django comes in. On simple sites, an HTML file is just rendered directly. With django, it's ran through a templating engine which will do some processing on it. So if you take a look at the source code of a team's page on the Atlas (hit Control+U, or right click something and select Inspect Element to jump to that portion of the HTML), you'll actually see id="poke_sprite-1" and id="poke_sprite-2" if you view a team that has two members. {{poke.species}} is an object called "poke" with a property called "species" which holds the species value of a pokémon and place it there. So a Pikachu would get src="/assets/iamges/sprites/x-y/25.png"
So how do we change it?
Well, "poke" basically holds all the information stored on a Pokémon. {{poke.name}}, {{poke.ability}}, {{poke.gender}}, {{poke.shiny}} are already defined as part of "poke" objects. So to make a Pokémon shiny... <img id="poke_sprite-{{forloop.counter}}" class="sprite" src="/assets/images/sprites/x-y/shiny/{{poke.species}}.png">
Just update the path to the shiny image! But... that's going to make every Pokémon on the Atlas show up as shiny. I only want Pokémon people have said are shiny to show up as such! To do this I need to only add in the /shiny path if the Pokémon is shiny. With Django's templating engine, I can make the check right here, without touching any of the site's main code. <img id="poke_sprite-{{forloop.counter}}" class="sprite" src="/assets/images/sprites/x-y/{% if poke.shiny %}shiny/{% endif %}{{poke.species}}.png">
By adding an if statement, Django will see if poke.shiny is true, and if it is will add in the text within the if statement. So shiny Pokémon will be shiny, and non-shinies will display the same image source they always did.
The exact same change can be made in pokemon_edit.html as well, and also set_stats.html. So that's 3 out of 5 pages already!
Next I'll try the Evolve Teammate page. This one is slightly more complex! But still won't need to touch any Python code. I've added a new Pokémon to a different team to have a good test subject as well as changing Alexander back into a Meowth. Pika up there is supposed to be shiny. The evolve.html template has an image tag similar to the one worked on previously, and adding the if statement is enough to make the Pikachu sprite shiny. But it would be nice to make it so the Raichu sprite was also shiny as that status doesn't change on evolution.
Here we have some JavaScript (and more inline CSS... it's a wonder I've ever been hired). This JavaScript is what draws the options under the New Species heading once you select a teammate to evolve. The code doesn't use a "poke" object because it's going to change every time you click a teammate. Instead, data is passed into the JavaScript function to load stats and evolution options.
And so here's the "poke" object yet again! When you click on a Pokémon all those data-whatevers are read by the JavaScript. So by adding the shiny value here, we'll be able to have it in the JS function. I can then edit that function with an if statement as well, but it will look a little different as we're in JavaScript code rather than Django templating.
Ok, I lied and didn't use an if statement. Instead I used a "Ternary" which is basically a shortcut for an if statement that's usually worthwhile if what you need to do based on that if statement is simple enough, such as just adding some text in this case. ($(this).data("shiny") ? 'shiny/' : '')
The part before the question mark is the condition, the shiny attribute is checked and then if it's true, it will return the section after the question mark, and if it's false, it will return the section after the colon. Here the false value is just an empty string so nothing changes, like if you added 0 to another number.
Reloading the page with the changes, and now the Raichu is shiny to match! And if Meowth is slected, the Persian will not be shiny. Only one page left, and it's actually just another template for the team page!
This is the team page yet again. Before I was editing files which would be included based on whether or not the Pokémon was editable. You can see here it takes a "poke" object out of the list of Pokémon given to the page, and then uses an if statement to decide whether to include pokemon_edit.html or pokemon_show.html
But there's still some cases where you might get shinyness mixed up here! If you change the species of a Pokémon or change the shiny value of a Pokémon the image needs to update! Let's go with the species change first, as there's already code in place to update the image. It just needs to also make a shiny status check.
So here's the JavaScript code for changing the species! It reads an ID attribute to know which Pokémon on the team is having its species changes. Then it gets its currently selected value to get the species number. The next two lines update the icon in the team roster section, and then the image of the Pokémon being edited. Lastly it calls another function moves_link(), this is what makes it so you can click links to go to Veekun's Pokédex and check moves for the currently selected species. Those tiny icons don't have shiny variants, so only one image needs to be changed.
I didn't show it, but I added a data-id attribute to the shiny select box. Once that was in place, I had the function pull it. Pulling it is a little more complex, it first looks for the HTML element with an id of "pokemon_info" + whatever the id is, and then looks inside of that for the shiny select box. This is chaining two selectors, and is something I didn't really do when I made the Atlas. It would be an easier system than tacking on those ID attributes to so many things.
I then use a ternary again, but note that the condition is wrapped in a parseInt()! That's because the select box uses strings of text and not numbers. A string would be something like "Hello" or "52 is a good number" or even just "1". "1" and 1 are different things in programming! Isn't it great? But it makes sense when you realize "Hello " + "World" = "Hello World" and so "1" + "1" = "11" and not 2! Any string that isn't empty is considered true, so a non-shiny Pokémon having a "0" value is still true. Telling JavaScript to parse "1" as 1 and "0" as 0 will give the true/false behavior I'm looking for.
Oh, wait I did take a screenshot of it! See, here's the data-id attribute!
Lastly, I copy the species change function and tweak it for pulling the shiny value and then species. It can skip the move update as a shiny Pikachu has the same moves as a regular one.
I save my changes and give it a test! Only to find one last issue!
There's no such thing as a shiny egg / shiny substitute doll! If you try to use the egg/other species choices, and make it shiny, you'll get a broken image. So..... I will just copy the regular images for these two into the shiny folder and be done with it.
Satisfied that I didn't break everything beyond repair, I can upload my changes to the live site and check the results! And those results appear to be that it's working!
So I hope you enjoyed getting some idea how the site works. The changes here were all on the frontend, nothing needed in the Python code of the site. It can definitely be hectic, HTML, CSS, JavaScript, and Django's templating all used to make shiny Pokémon appear shiny, and I didn't even touch Python, which is what the backend is done in. If web design is something that interests you, give it a shot! You certainly don't need to learn a dozen things at once, and even only knowing HTML is enough to get a simple site up and running.












